A1.1 Function Calling:一次「伸手」的全流程
模型没有手
先戳破一个想象:模型并不能「运行」任何东西。它没有网络权限、没有文件系统、碰不到你的日历——它从头到尾只会一件事:生成文本(上篇讲了九章的那件事)。
那它是怎么「调用」计算器、查到天气的?答案巧妙得近乎狡猾:
它生成一段描述「我想调用什么」的文本,真正动手的是旁边的普通程序。
就像一位被锁在房间里的军师:他不能亲自上阵,但他可以往门缝外递纸条——「派骑兵去左翼」。只要门外有个传令兵照着纸条执行、再把战报塞回来,军师就等于「指挥」了整场战役。工具调用(Function Calling)就是这套递纸条的规矩。
全流程五步
一次完整的「伸手」是这样的:
- 上清单:开发者把工具清单放进上下文。每个工具带一份工具描述——名字、用途、参数格式(JSON Schema),相当于说明书;
- 做决策:模型读用户的问题、读说明书,判断「回答这个问题,缺不缺外部信息或外部操作」——缺,才需要工具;
- 递纸条:需要就生成一段结构化调用请求(JSON):调哪个工具、参数填什么。注意这一步仍然是生成文本,只是格式特殊;
- 传令兵执行:外层程序解析这段 JSON,真正去执行(查 API、跑计算),把结果拼回上下文;
- 继续生成:模型读到结果,要么组织成人话回答,要么再递一张纸条——这就转起了 A0 章的行动循环。
亲手走一遍这五步:
calculatorget_weatherexchange_rateweb_searchcalendar_list建议的玩法:按顺序玩五个问题— —算术 → 天气 → 汇率 → 日程 → 寒暄。前四个各演示一类「模型自身做不到的事」(精确计算、实时信息、变动数据、私人数据);最后的寒暄题会告诉你,判断「不需要工具」同样是正确决策。然后勾上「⚠️ 把工具描述换成含糊版」,重玩汇率题和日程题:看着模型拿着「今天下午三点我有空吗」去搜索互联网,你就永远忘不了下面这一段。最后再勾上「🔧 注入工具执行失败」,重玩天气题或汇率题——工具会先返回一句报错(日期格式不对、币种要用 ISO 代码),看模型读懂报错、自己改对参数重试。这正是本节深入层要讲的「错误处理」在真实智能体里每天发生的样子。
描述即接口
模型决策时能看到的只有两样东西:用户的问题,和你写的工具描述。它没法打开工具「看源码」——描述写成什么样,工具在模型眼里就是什么样。
刚才的实验里,把 exchange_rate 的描述从「按实时汇率换算两种货币的金额」换成「处理数字」,模型就转头选了听起来更像「处理数字」的 calculator,用记忆里的旧汇率硬算,差了 200 多块。同一个模型、同一个问题、同样的工具代码——只是说明书烂了,任务就砸了。
所以工程圈有个略显扎心的共识:写工具时最值钱的不是代码,是那一句描述。 好的工具描述像好的 API 文档:说清楚它能干什么、不能干什么、参数的含义和格式,甚至给一两个使用示例。
组件里的「模型决策」是规则模拟——为了教学,它整齐得像查表。真实模型的工具选择是训练出来的「直觉」(下一节细讲),没有如此清晰的规则,也因此会以更意外的方式出错。真实系统还要兜底三件事:模型幻觉出清单里不存在的工具、参数 JSON 格式不合法、工具本身执行失败——这些错误处理占了工具调用工程的大半工作量(见深入层)。
小结
- 模型没有手:「调用工具」= 生成一段结构化的调用请求文本,真正执行的是外部程序。
- 五步流程:上清单 → 做决策 → 递纸条(生成 JSON)→ 外部执行 → 结果回填继续生成。
- 描述即接口:模型眼里的工具就是你写的那句描述,说明书的质量直接决定调用的对错。
延伸阅读
- Anthropic 工具使用文档与 OpenAI Function Calling 指南——两家的报文格式与最佳实践,写工具前值得通读。
- 下一节 A1.2 会用工具,是训练出来的:同一份说明书,为什么老模型看不懂、新模型一看就会。