Skip to content

02 · 工具调用:模型怎么「按按钮」 ​

学完你能说出:

  • 工具调用(Function Calling)的完整 4 步:告诉模型有哪些工具 → 模型返回调用请求 → 程序执行 → 结果交回模型。
  • 工具说明(名字、描述、参数)为什么要写清楚。
  • 程序端必须做哪些检查。

先看地图 ​

上一篇说 Agent 的核心是「模型决定调哪个工具」。这一篇讲它具体是怎么「说」出来的:不是随便一句话,而是一段程序能直接解析的结构化数据。

本篇讲 4 个点:① 工具怎么描述 → ② 一次调用的完整来回 → ③ 为什么要结构化 → ④ 程序端要防什么。

一句话本质 ​

工具调用 = 先把「有哪些按钮、每个按钮要填什么」告诉模型;模型需要时,返回「按哪个按钮、填什么」的 JSON,由程序去按。

生活类比:餐厅点单 ​

  • 菜单(工具说明):每道菜的名字、介绍、可选项(辣度、份量)。
  • 顾客(模型):看着菜单,写出点单:「宫保鸡丁,微辣,一份」。
  • 后厨(程序):照单做菜,把菜端回来。
  • 顾客点了菜单上没有的东西,或者写了「辣度:999」,后厨要退回去,不能照做。

一步步看:「北京明天几度?」 ​

第 1 步:告诉模型有哪些工具 ​

用 JSON Schema(一种描述数据格式的标准写法)描述工具:

json
{
  "name": "get_weather",
  "description": "查询某个城市某一天的天气预报。用户问天气、温度、要不要带伞时使用。",
  "parameters": {
    "type": "object",
    "properties": {
      "city": { "type": "string", "description": "城市名,如 北京" },
      "date": { "type": "string", "description": "日期,格式 YYYY-MM-DD" }
    },
    "required": ["city", "date"]
  }
}

第 2 步:模型返回「调用请求」,而不是直接回答 ​

json
{ "tool": "get_weather", "arguments": { "city": "北京", "date": "2026-11-10" } }

第 3 步:程序检查并执行 ​

python
args = call["arguments"]                        # arguments = 参数
if call["tool"] not in ALLOWED_TOOLS:           # allowed 允许的;不在白名单里就拒绝
    raise ValueError("未知工具")
result = get_weather(args["city"], args["date"])  # 真正去调天气接口

第 4 步:把结果交回模型,让它生成最终回答 ​

[tool 结果] {"city": "北京", "temp_low": 3, "temp_high": 12, "weather": "晴"}
[assistant] 北京明天晴,气温 3–12℃。

一次工具调用,模型至少被调用两次:第一次决定调用什么,第二次根据结果写回答。

为什么这么设计 ​

为什么要返回结构化的 JSON,而不是一句话? ​

  • 问题:如果模型说「我想查一下北京明天的天气」,程序还得再去理解这句话,容易出错。
  • 方案:约定模型输出固定格式的 JSON:工具名 + 参数。
  • 好处:程序能直接解析、校验、执行,稳定可靠。

一句话答法

结构化输出让程序可以直接解析和校验调用请求,不用再理解自然语言,减少出错。

为什么工具的「描述」要写清楚? ​

  • 问题:模型选不选这个工具、参数怎么填,全靠读描述。描述含糊,它就会选错工具或填错参数。
  • 方案:描述写清楚「做什么、什么时候用」,每个参数写清含义和格式,例如「日期,格式 YYYY-MM-DD」。
  • 好处:选对工具、填对参数的概率大大提高。

一句话答法

模型完全依赖工具描述来决定是否调用、怎么填参数,描述就是给模型看的说明书,写清用途和格式才能调用准确。

为什么程序端一定要校验? ​

  • 问题:模型可能编造不存在的工具、漏填参数、填错格式,甚至被恶意输入诱导去调危险工具。
  • 方案:程序端做白名单检查(只允许注册过的工具)、参数校验(类型、范围)、权限检查;危险操作需要用户确认。
  • 好处:模型出错时不会造成实际损害,错误还能反馈给模型,让它重试。

一句话答法

模型的输出不可完全信任,程序必须校验工具名、参数和权限;校验失败就把错误信息返回给模型重试,危险操作要人工确认。

英文术语拆解 ​

术语拆开看一句话意思
Function Callingfunction 函数 + calling 调用让模型以结构化方式请求调用函数(工具)
Tool Usetool 工具 + use 使用同上,不同厂商的叫法
JSONJavaScript Object Notation(JS 对象表示法)一种通用的数据格式,{"键": 值}
Schema结构、模式描述数据长什么样、有哪些字段
Parameters / Arguments参数(定义时)/ 实参(调用时实际填的值)工具需要的输入
required必需的必须填的参数
Whitelistwhite 白 + list 名单白名单:只允许名单里的

面试怎么问 ​

Q:讲一下 Function Calling 的流程。

应用把可用工具的名称、描述和参数 Schema 随请求发给模型;模型判断需要调用时,返回工具名和 JSON 参数;应用校验后执行对应函数,把结果作为工具消息追加到对话中再次调用模型;模型根据结果生成最终回答,或继续发起下一次调用。

Q:模型调用工具时参数填错了怎么办?

应用端做 Schema 校验,失败时把具体的错误信息作为工具结果返回给模型,让它修正后重试,并限制重试次数;同时优化工具描述,比如写明格式和示例。

Q:工具很多(比如上百个)时会有什么问题?

所有工具描述都要占用上下文,成本上升,模型也更容易选错。可以按任务先筛出相关的少量工具再交给模型,或者把工具分组、分层。

容易混的地方 ​

  • 模型不会运行你的函数:它只返回 JSON,执行永远在你的程序里。
  • 「调用了一次工具」= 至少两次模型请求:一次决定调用,一次读结果写回答。
  • 一次可以请求多个工具:有的模型支持一次返回多个调用请求(比如同时查北京和上海的天气),程序可以并行执行。

和其他知识的连接 ​

  • ← 来自 Agent 是什么:这是 Agent 循环里「行动」那一步的具体实现。
  • ← 来自 Prompt 与采样参数:工具描述和「只输出 JSON」本质上都是提示的一部分。
  • → 影响 记忆与 MCP:MCP 把「怎么描述工具、怎么调用工具」做成了统一标准。
  • → 影响 安全与评估:校验、白名单、人工确认是 Agent 安全的第一道防线。

自测 3 问 ​

Q1:Function Calling 的 4 步是什么?

点开看答案

① 把工具的名称、描述、参数格式告诉模型;② 模型返回「调用哪个工具 + JSON 参数」;③ 程序校验后执行;④ 把执行结果交回模型,模型生成最终回答(或继续调用)。

Q2:为什么说「工具描述就是给模型看的说明书」?

点开看答案

模型完全靠读描述来判断什么时候用这个工具、参数怎么填。描述含糊就会选错工具、填错参数,所以要写清用途、使用时机和每个参数的格式。

Q3:程序端至少要做哪些检查?

点开看答案

① 工具名是否在白名单里;② 参数是否齐全、类型和格式是否正确;③ 是否有权限执行;④ 危险操作是否需要用户确认。校验失败就把错误返回给模型重试。

✅ 验收清单 ​

  • 能用「餐厅点单」类比讲清工具调用中模型和程序的分工
  • 能看懂一个工具的 JSON Schema,说出 name、description、parameters、required 各是什么
  • 能说出「一次工具调用至少两次模型请求」的原因
  • 能讲清「为什么要结构化」「为什么要写清描述」「为什么要校验」(问题 → 方案 → 好处)
  • 能说出参数填错时的处理办法

下一步该懂什么 ​

  • 一次调用会了,多步任务里「想」和「做」怎么交替进行?→ ReAct 与规划