大模型应用开发教程09 | Function Calling 原理与实践(工具调用)
理论部分前面我们做的事情本质上都是给模型一段输入让模型生成一段输出。但当我们希望模型“帮我们做事”时仅靠生成文本往往不够我们想要实时数据天气、股价、数据库查询结果模型本身拿不到我们想要模型触发动作发请求、查文件、执行计算文本并不能直接执行Function Calling工具调用就是把“模型输出”升级为“可执行的结构化意图”我们把可用工具函数及参数规则告诉模型模型根据用户问题决定要不要调用工具、调用哪个工具、传什么参数我们在代码里执行真实函数把函数结果回传给模型模型基于工具结果生成最终回答从工程视角看这里最关键的是模型只负责决定“调用什么 参数是什么”真正执行仍然由我们的程序掌控。这使得工具调用更可控、更可验证也更容易接入业务系统。一个完整的工具调用链路里会出现三类关键信息Tool Definition工具描述函数名、用途描述、参数 schema类型、枚举、必填字段Tool Call工具调用请求模型生成的结构化调用意图函数名 argumentsTool Result工具执行结果我们执行函数后的返回值通常是 JSON 字符串或可解析文本实践部分本案例做什么我们实现一个“智能天气助手”让模型在需要时自动调用get_current_weather工具用户提问比如“北京天气怎么样”模型决定调用工具并给出参数location、unit我们执行函数这里用模拟数据代替真实天气 API把工具返回结果喂回模型生成最终答复主要代码本篇使用项目脚本src/4.1_weather_agent.pyimportosimportjsonfromdotenvimportload_dotenvfromopenaiimportOpenAI# 加载环境变量load_dotenv()clientOpenAI(api_keyos.getenv(ZHIPUAI_API_KEY),base_urlos.getenv(ZHIPUAI_BASE_URL))# 1. 定义实际的工具函数 # 这里我们用模拟数据实际项目中可以调用真实的天气 APIdefget_current_weather(location,unitcelsius):获取指定城市的当前天气print(fDEBUG: 正在查询{location}的天气...)if北京inlocation:returnjson.dumps({location:北京,temperature:22,unit:unit,description:晴朗})elif上海inlocation:returnjson.dumps({location:上海,temperature:25,unit:unit,description:多云})elif广州inlocation:returnjson.dumps({location:广州,temperature:30,unit:unit,description:雷阵雨})else:returnjson.dumps({location:location,temperature:unknown})# 2. 定义工具描述 (Tool Definitions) # 告诉 LLM 有哪些工具可用以及参数格式tools[{type:function,function:{name:get_current_weather,description:获取指定城市的当前天气,parameters:{type:object,properties:{location:{type:string,description:城市名称如北京、上海,},unit:{type:string,enum:[celsius,fahrenheit],description:温度单位默认为摄氏度},},required:[location],},},}]# 3. 对话主循环 defrun_conversation():print( ️ 智能天气助手 (Function Calling Demo) )print(试着问我北京天气怎么样 或 上海和广州哪里更热 (输入 q 退出))messages[]# 维护上下文whileTrue:user_inputinput(\n 你: )ifuser_input.lower()in[q,quit]:break# 将用户消息加入历史messages.append({role:user,content:user_input})# 第一次调用模型查看是否需要调用工具responseclient.chat.completions.create(modelglm-4-flash,# 确保模型支持 Function Callingmessagesmessages,toolstools,tool_choiceauto,# 让模型自动决定是否调用工具)response_messageresponse.choices[0].message tool_callsresponse_message.tool_calls# 如果模型决定调用工具iftool_calls:# 必须先把模型的这条回复包含工具调用请求加入历史messages.append(response_message)print(f AI 决定调用工具:{len(tool_calls)}个请求)# 建立函数名到实际函数的映射available_functions{get_current_weather:get_current_weather,}# 遍历所有工具调用请求fortool_callintool_calls:function_nametool_call.function.name function_to_callavailable_functions[function_name]function_argsjson.loads(tool_call.function.arguments)# 执行真正的函数function_responsefunction_to_call(locationfunction_args.get(location),unitfunction_args.get(unit),)print(f -- 调用{function_name}({function_args}))print(f -- 返回{function_response})# 将工具执行结果作为 tool 类型的消息加入历史messages.append({tool_call_id:tool_call.id,role:tool,name:function_name,content:function_response,})# 第二次调用模型让模型根据工具结果生成最终回答print( AI 正在根据工具结果生成回答...)final_responseclient.chat.completions.create(modelglm-4-flash,messagesmessages,)ai_replyfinal_response.choices[0].message.contentprint(f AI:{ai_reply})# 把最终回答也加入历史messages.append({role:assistant,content:ai_reply})else:# 不需要调用工具直接回复ai_replyresponse_message.contentprint(f AI:{ai_reply})messages.append({role:assistant,content:ai_reply})if__name____main__:run_conversation()运行方式在项目根目录执行python3 src/4.1_weather_agent.py运行结果示例我们可以输入一个需要实时信息的问题例如“北京天气怎么样”“上海和广州哪里更热”运行时会看到类似输出模型的措辞可能不同但工具调用链路一致 ️ 智能天气助手 (Function Calling Demo) 试着问我北京天气怎么样 或 上海和广州哪里更热 (输入 q 退出) 你: 上海和广州哪里更热 AI 决定调用工具: 2 个请求 DEBUG: 正在查询 上海 的天气... -- 调用 get_current_weather({location: 上海, unit: celsius}) -- 返回 {location: 上海, temperature: 25, unit: celsius, description: 多云} DEBUG: 正在查询 广州 的天气... -- 调用 get_current_weather({location: 广州, unit: celsius}) -- 返回 {location: 广州, temperature: 30, unit: celsius, description: 雷阵雨} AI 正在根据工具结果生成回答... AI: ...总结这一篇我们跑通了 Function Calling 的完整闭环模型先决定是否调用工具以及工具参数我们负责执行真实函数并把结果回传最后再由模型整合工具结果生成最终回答。

相关新闻

mtr网络诊断工具:原理、实战与典型故障排查

mtr网络诊断工具:原理、实战与典型故障排查

1. 为什么网络工程师都爱用mtr? 第一次接触mtr是在处理一次跨国视频会议卡顿问题时。当时我按照传统套路,先ping测试丢包率,再用traceroute查路由节点,最后用speedtest测带宽,折腾半小时仍无法定位问题。直到运维总监过…

2026/10/17 11:09:51 阅读更多 →
Java开发中容易被忽视的五个代码细节

Java开发中容易被忽视的五个代码细节

你的代码能跑,不代表它能活过明天很多Java程序员都有过这样的瞬间:代码在本地运行完美,一上生产就出幺蛾子;单测覆盖率高达90%,线上还是半夜报警;明明按照教科书写的代码,却被运维骂得狗血淋头。…

2026/10/19 12:51:26 阅读更多 →
如何为新项目打好技术架构第一张牌:从需求分析到落地验证

如何为新项目打好技术架构第一张牌:从需求分析到落地验证

最近在技术社区看到不少关于“陈宇森打出第一张牌”的讨论,很多开发者对这个概念背后的技术实现和工程价值感到好奇。实际上,这并非一个具体的产品名称,而更像是一个比喻,用来描述在复杂系统架构演进或技术选型中,所做…

2026/10/17 11:10:37 阅读更多 →

最新新闻

C++析构函数深度解析:RAII、资源管理与内存泄漏排查

C++析构函数深度解析:RAII、资源管理与内存泄漏排查

1. 一个线上服务的内存泄漏排查,让我重新审视析构函数前阵子排查一个C服务的RSS持续上涨问题,现象很典型:请求量不算大,内存却以每小时几百MB的速度往上爬。用valgrind跑了一遍,泄漏点集中在一个看起来毫无存在感的类型…

2026/10/21 7:02:48 阅读更多 →
OpenClaw 代理 Token 消耗暴涨三倍?三招优化砍回 60% 成本

OpenClaw 代理 Token 消耗暴涨三倍?三招优化砍回 60% 成本

月初看到账单的时候,我差点以为后台被刷了。自用的 OpenClaw 代理跑了不到一个月,Token 消耗比预期翻了三倍,光是输入 Token 就把预算吃穿。刚开始我也像大多数玩家一样,把锅甩给“模型太贵”,后来把会话日志导出&…

2026/10/21 7:02:48 阅读更多 →
Linux UI开发技术路线全解析:从桌面到嵌入式选型与实战

Linux UI开发技术路线全解析:从桌面到嵌入式选型与实战

三、linux系统 应用开发:UI开发技术路线在 Linux 下做应用开发,UI 这块的坑和选择多得能让人挑花眼。我见过太多人一上来就扎进某个框架,吭哧吭哧写了三个月,结果发现跑在目标设备上卡得要命,或者界面风格跟整个系统格…

2026/10/21 7:02:48 阅读更多 →
agent-skills技能体系设计:从意图路由到执行编排的工程实践

agent-skills技能体系设计:从意图路由到执行编排的工程实践

1. 从"agent-skills"这个命名说起:它到底指什么第一次看到"agent-skills"这个词,很多人会下意识地把它理解成"给智能体装上一堆技能包"。这个理解方向没错,但太粗了。真正做过智能体项目的人都知道&#xff0c…

2026/10/21 7:02:48 阅读更多 →
YOLOv11嵌入式部署实战:模型压缩与推理加速全流程指南

YOLOv11嵌入式部署实战:模型压缩与推理加速全流程指南

简介:这份文档系统梳理了工业质检场景下基于YOLOv11实现零漏检目标的完整技术路线,涵盖模型压缩与嵌入式部署两大核心环节,适合从事缺陷检测、边缘AI开发的技术人员阅读。资源为单个PDF文件,约2.09MB,共30页&#xff0…

2026/10/21 7:02:48 阅读更多 →
AI辅助期刊论文写作全攻略:从选题到投稿避坑指南

AI辅助期刊论文写作全攻略:从选题到投稿避坑指南

学术圈里有个说法,论文写作是“九十九死一生”:想清楚一个能发表的研究问题很难,把研究过程讲清楚更难,最后过审稿人那关更是难上加难。我见过太多人,实验做得漂漂亮亮,数据也扎实,结果卡在“不…

2026/10/21 7:01:48 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事:AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里,按宣传口径,本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”,而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起:用户到底在追求什么“封号重开”这四个字,放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流,背后是大量的时间和精力成本。正常情况下,没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”,而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时,就意识到:单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/21 4:27:17 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →