很多人第一次听“大模型调用工具”会以为模型伸手去执行了什么。其实不是。模型只负责“说”要调用什么,真正执行的是你这一侧的运行时代码。
一、一次工具调用发生了什么
典型的一轮是这样的:
- 你在请求里声明可用的工具,每个工具带名字、用途描述和参数结构(JSON Schema)。
- 模型判断需要工具,返回一个结构化调用意图:调用哪个工具、传什么参数。
- 你的运行时按意图去真正执行(发请求、查库、读文件)。
- 把执行结果作为一条消息回填给模型。
- 模型基于结果继续推理,给出最终回答,或再次请求工具。
关键点:模型和真实副作用之间,始终隔着你的代码。这既是安全边界,也是可以做校验、做确认的地方。
二、工具 schema 怎么写才好用
工具的“描述”其实是给模型看的文档。经验上:
- 描述写清楚“什么时候用”,而不只是“这是什么”。
- 参数尽量少,必填项越少越好;枚举值要写全。
- 命名自解释,别用
doThing这种模糊名字。
工具太多、描述含糊,是模型“挑错工具”的主要原因。
三、错误也要结构化
工具执行失败时,别只回一句“失败”。把错误类型、原因、可重试与否结构化地回给模型,它才有机会自我修正或换策略。反过来,如果失败信息只有一句“error”,模型大概率会重试同样的事。
四、并行与多轮
现代模型常支持一次返回多个调用意图,可以并行执行、并行回填,显著减少往返。多轮调用则让 Agent 能“做几步再看结果”。
五、安全上的三个要点
- 白名单:只暴露必要的工具,别给全量清单。
- 参数校验:即使模型“说”要删数据,也要在服务端校验权限和参数范围。
- 幂等与确认:写操作设计成幂等,高风险动作加二次确认。
六、打包与复用
工具一多,接入和维护就成了负担。常见做法是把高频工具(搜索、解析、图像)打包成一套统一入口。例如长亭百智云的 Agent 工具包,用一个 Key 就能接入搜索、解析与图像工具,先把常见能力铺上,再按需接自有系统。
小结
Function Calling 的本质是把“决定做什么”和“实际做什么”分开:模型负责前者,你的代码负责后者。这个分界让 Agent 既能灵活决策,又不至于失控——前提是你在那一侧把白名单、校验和确认做扎实。