Function Calling 机制
模型没有调用任何函数:它只是按 schema 输出一段结构化的「我想调什么、参数是什么」,真正执行的是你的代码,再把结果作为消息塞回去。完整六步缺一不可,理解这一点才能理解并行调用、结果裁剪与 MCP 各自在改哪一步。
也叫:Function Calling · 函数调用 · 工具调用 · tool use · tool_calls
完整六步,缺一不可出自 T3-2
① 你发请求:messages + tools 定义(工具定义被拼进上下文,占 token)
│
▼
② 模型输出:stop_reason=tool_use
{ "id":"call_a1", "name":"search_order",
"arguments":{"user_id":"U123","status":"unshipped"} }
│ ← 到这一步为止,什么都没有真正发生
▼
③ 你的代码解析 + 校验参数(类型、越权、注入)
│
▼
④ 你的代码真正执行:查库 / 调 API / 跑脚本
│
▼
⑤ 结果作为 tool_result 消息回填,携带同一个 call_a1
│
▼
⑥ 带着完整历史再请求模型 → 它可能给最终答案,也可能再调工具(回到②)三个常被忽略但面试爱问的细节:
- 第 ③ 步是安全边界。模型输出的参数是不可信输入,等同于用户输入。
delete_file(path)的 path 必须校验,不能因为"是模型生成的"就信任。提示词注入(T1-5)的实际落点就在这里。 - 第 ⑤ 步的结果是纯文本(或结构化片段),模型对它的信任度完全取决于你怎么写。工具报错时返回
Error: 500毫无用处,返回订单号格式错误,应为 ORD- 开头的 16 位字符串,你传入的是 "123"能让模型下一轮自我修正。 - 每一轮都要重发全部历史。这是 Agent 成本随步数超线性增长的根因:第 N 轮的输入 ≈ 前 N-1 轮的所有内容。prompt 缓存(T1-4)之所以对 Agent 特别关键,原因就在这。
以上节选自T3-2 Function Calling 机制与工具设计——模型其实没有调用任何函数,读全文能看到前后语境。