工具调用架构:从能用到好用
作者:程序员马丁
Ragent AI —— 从 0 到 1 纯手工打造企业级 Agentic RAG,拒绝 Demo 玩具!AI 时代,助你拿个offer。
引言
在之前的文章中,咱们讲了 MCP 协议如何解决工具管理的标准化问题,让工具的注册、发现、调用变得更规范。再往前一篇咱们搞清楚了 Function Call 的基本原理和协议细节。
但这里有个关键问题:协议和框架只是解决了“怎么调用工具”的问题,工具本身的质量才决定了系统的上限。
打个比方,MCP 协议就像是给你提供了一套标准的餐具和上菜流程,但菜好不好吃,还得看厨师的手艺。工具定义写得烂,模型选错工具、参数传错、调用失败,用户体验就会很差。
举个真实的线上问题:
用户问:我还剩几天年假?
系统定义了一个工具
getUserInfo,description 写的是查询用户信息,参数有userId、infoType(可选值:annualLeave、sickLeave、salary、attendance)。结果模型调用时,
infoType传成了annual_leave(下划线格式),工具执行失败返回“参数格式错误”。模型拿到这个错误后,又重试了一次,这次传成了AnnualLeave(首字母大写),还是失败。最后模型只能回复用户:"抱歉,系统出错了,请稍后再试。"
这个问题的根源在哪?不是 Function Call 协议有问题,也不是模型太笨,而是工具定义本身设计得不好:
- 参数太多太灵活(
infoType枚举值没有明确约束) - 描述太模糊(查询用户信息太宽泛,模型不知道什么时候该用)
- 错误处理不友好(返回参数格式错误,模型不知道怎么修正)
- 没有参数校验和容错(应该支持多种格式或给出明确的格式要求)
工具调用不只是技术问题,更是设计问题。好的工具定义能让模型更容易选对工具、传对参数、处理好异常,最终给用户更好的体验。
这篇文章就来聊聊工具调用的最佳实践:怎么设计好的工具定义、怎么写清晰的工具描述、怎么处理错误和异常、怎么保证安全性和可观测性。这些原则和技巧适用于 Function Call 和 MCP 两种方式,也适用于任何需要让 AI 调用外部工具的场景。