从定义到执行:Tool Calling 完整链路深度解析 📅 2026/7/1 2:00:51 从定义到执行Tool Calling 完整链路深度解析1. 引言Tool Calling 是什么为什么它是 Agent 的“手”2. 第一步工具是如何定义的2.1 标准定义格式2.2 关键字段详解2.3 tool_choice控制模型“什么时候用”3. 第二步LLM 怎么“调用”工具4. 第三步结果怎么回传——完整的闭环流程5. 进阶特性与注意事项5.1 并行工具调用5.2 Token 消耗一个容易被忽视的成本坑5.3 模型可能“幻觉”参数5.4 在 OpenClaw 中的实践6. 结语The Begin点点关注收藏不迷路⬇ ⬇ 底部 ⬇ ⬇1. 引言Tool Calling 是什么为什么它是 Agent 的“手”很多人把 Tool Calling 简单地理解为“AI 调用了一个函数”。但真实情况远没那么简单——它是一套让大模型从“只会说话”进化到“真正能做事”的完整通信协议。简单来说Tool Calling或称 Function Calling是一种让大语言模型能够根据用户请求输出结构化工具调用指令由应用程序执行这些指令并将结果返回给模型从而让模型生成更准确、更务实的最终回答的能力。它的本质是让模型输出可执行的 JSON而不是仅输出纯文本。内部执行链路用户视角① 帮我查一下北京的天气⑥ 北京今天晴26°C② LLM 推理输出 tool_calls JSON③ 应用层解析匹配函数名参数④ 执行真实函数API调用/数据库查询⑤ 结果回填作为tool message发回⑥ LLM 二次推理生成最终自然语言回答一句话定位Tool Calling 是 AI Agent 的“手”让它能把“理解”转化为“行动”。2. 第一步工具是如何定义的在 Tool Calling 中工具的定义不是“写一个函数”而是为模型写一份 JSON 格式的说明书。模型不执行任何代码它只看这份说明书来决定“要不要用、怎么用”。2.1 标准定义格式绝大多数主流模型OpenAI、Anthropic、Google、本地部署的 Ollama 等已基本统一采用类似 OpenAI 的格式{type:function,function:{name:get_weather,description:获取指定地点的当前天气信息。当用户询问天气时调用。,parameters:{type:object,properties:{location:{type:string,description:城市名称例如 San Francisco, CA},unit:{type:string,enum:[celsius,fahrenheit],description:温度单位}},required:[location]}}}2.2 关键字段详解字段作用对模型的意义name工具的唯一标识符模型调用时通过这个名称来指定要调用哪个工具description工具的功能描述这是模型判断“该不该用这个工具”的最核心依据。描述越清晰具体模型选得越准parametersJSON Schema 格式的参数定义告诉模型需要传什么参数、什么类型、哪些必填、有哪些可选值实用建议描述写得模糊模型就会选错工具或不知道该用哪个。这是实际开发中 80% 问题的根源。2.3 tool_choice控制模型“什么时候用”定义完工具后还可以通过tool_choice参数控制模型的调用行为模式说明适用场景auto默认模型自主决定是否调用工具大多数通用场景none禁止调用任何工具测试纯文本回复能力required强制模型至少调用一个工具你确定本次任务必须依赖工具完成指定函数强制调用特定工具如{type:function,function:{name:get_weather}}测试特定工具或任务明确指向单一工具3. 第二步LLM 怎么“调用”工具回到前端的天气查询例子用户说“What‘s the weather in San Francisco?”。模型拿到用户输入和工具定义后内部推断过程大致是意图理解用户问天气需要实时数据工具匹配get_weather的描述匹配当前需求参数提取从“San Francisco”提取location“San Francisco”输出结构化调用返回一个JSON 格式的指令模型不会真正去查天气它只是“建议”应用层去查。模型返回的内容长这样{choices:[{message:{tool_calls:[{id:call_abc123,type:function,function:{name:get_weather,arguments:{\location\: \San Francisco\}}}]}}]}关键点在于模型返回的是工具调用的元数据名称 参数而不是执行结果。应用层拿到这个 JSON才知道接下来该做什么。4. 第三步结果怎么回传——完整的闭环流程将以上步骤串联起来Tool Calling 的完整调用链路如下图所示外部工具/API大模型应用层用户外部工具/API大模型应用层用户“北京天气怎么样”用户消息 工具定义列表返回 tool_calls:{name:“get_weather”, args:{city:“北京”}}根据 name 匹配函数传入 args 执行返回执行结果 {“temp”:26,“condition”:“晴”}将 tool 结果作为新消息回传生成最终回复“北京今天晴26°C”显示最终回复这个闭环的核心设计是模型不执行工具只输出调用指令应用层执行工具结果以特殊格式回传给模型让模型看到执行结果并据此生成最终回答。# 伪代码展示完整流程# Step 1: 发送用户消息 工具定义responseclient.chat.completions.create(modelgpt-4,messages[{role:user,content:北京天气怎么样}],tools[weather_tool_definition])# Step 2: 检查模型是否需要调用工具ifresponse.choices[0].message.tool_calls:tool_callresponse.choices[0].message.tool_calls[0]tool_nametool_call.function.name argumentsjson.loads(tool_call.function.arguments)# Step 3: 执行真实的工具函数resultget_weather(**arguments)# 实际调用 API# Step 4: 将工具执行结果回传给模型messages.append(response.choices[0].message)# 加入 assistant 的 tool_callsmessages.append({role:tool,tool_call_id:tool_call.id,content:json.dumps(result)})# Step 5: 让模型基于工具结果生成最终回答finalclient.chat.completions.create(modelgpt-4,messagesmessages)print(final.choices[0].message.content)5. 进阶特性与注意事项5.1 并行工具调用部分模型支持在一次响应中调用多个工具减少往返轮次、降低延迟和成本。应用层需要能同时处理多个tool_calls并将所有结果一次回传。5.2 Token 消耗一个容易被忽视的成本坑工具定义是随每次请求一起发送给模型的其 JSON 长度会直接占用上下文窗口并计入 Token 费用。建议只注册当前任务真正相关的工具精简工具的名称和描述复杂场景下按需加载避免一次性塞入几十个工具5.3 模型可能“幻觉”参数模型可能会输出未定义的参数或格式错误的值。应用层必须对模型返回的参数做校验和容错处理而不是盲目透传给工具函数。5.4 在 OpenClaw 中的实践OpenClaw 对工具调用做了工程化封装在Agent Loop中自动处理“模型推理 → 工具执行 → 结果回传”的循环并提供before_tool_call/after_tool_call钩子供开发者拦截和干预工具调用过程。开发者通过编写Skill包含SKILL.md描述 执行脚本即可让 OpenClaw 识别并调用自定义接口。6. 结语Tool Calling 本质上是一套模型与应用层之间的结构化通信协议定义阶段用 JSON Schema 为模型提供工具的“说明书”调用阶段模型输出tool_calls名称 参数而非执行结果回传阶段应用层执行工具将结果以role: tool消息回传模型二次推理后生成最终回复理解这条完整链路是理解 AI Agent 如何“动手”做事的基础也是后续深入 OpenClaw、Skills 等上层框架的必经之路。The End点点关注收藏不迷路⬆ ⬆ 顶部 ⬆ ⬆