什么是 AI Agent 中的工具调用(Tool Calling)?它的基本流程是怎样的?
- 标签:AI、大模型、Agent
🏛 业务架构师
工具调用(Tool Calling)是让 LLM 使用外部能力的机制,基本流程五步:
- 工具声明:应用把工具的定义——名称、功能描述(写给模型看的使用说明)、参数 JSON Schema——随请求传给模型(或经 MCP 自动发现);
- 模型决策:模型分析用户请求,判断需要调用哪个工具、参数是什么,输出结构化调用意图(工具名+参数 JSON),而不是自己执行;
- 应用执行:框架代码接住意图,做安全检查(鉴权、参数校验、限流)后真实调用后端 API/数据库,拿到结果;
- 结果回填:工具返回(必要时限幅/摘要)作为"工具消息"追加进对话上下文;
- 模型继续:模型基于真实结果生成最终回答,或决定继续调用下一个工具——形成循环直至完成。
一个例子:用户问"订单 A1024 发货了吗"→模型意图 query_order(id="A1024") →应用调订单接口 →结果"已发货,顺丰 SF123" →模型答复用户。
业务视角的关键认知:这条链路里模型只负责"决策",执行权和风险都在工程侧——所以权限、审计、幂等必须建在应用层,不能指望模型自律。工具描述质量决定选对率(要像产品说明书一样打磨)、工具返回的体量决定上下文健康(要限幅)——这两个细节占工具调用 badcase 的八成,值得优先投入。
🏗 系统架构师
工具调用(Tool Calling)= 模型输出结构化的"调用意图"(工具名 + 参数),由应用层执行后回填结果的机制。基本流程五步:
- 工具定义注入:每个工具带三要素——name、description(写给模型看的"使用说明",质量决定选择准确率)、inputSchema(JSON Schema 参数约束);定义随请求下发,模型由此知道"有什么可用";
- 模型决策:LLM 结合任务判断需要工具 → 输出结构化意图
{"name": "query_order", "arguments": {"order_id": "A123"}}——模型只产意图不执行,这是安全边界; - 应用执行:框架校验(Schema 合法性 → 权限检查 → 高危审批)→ 真实调用(HTTP/MCP/本地函数)→ 异常捕获返回结构化错误;
- 结果回填:结果封装为 tool 消息写回上下文(超大结果先截断/摘要/落盘);
- 迭代终止:模型基于结果继续决策——再调用、换工具、或输出无工具调用的最终答案。
架构师视角的三个关键点:
- 协议本质:把自然语言意图翻译成确定性 API 调用的适配层——模型负责语义理解,工程层负责校验、鉴权、幂等、重试;
- 失败反馈设计:工具错误要返回"原因 + 建议动作"的结构化信息,模型才能改道,否则傻重试;
- 工具数量治理:几十个以内,超了按场景分组动态注入(太多稀释选择准确率)。
💻 全栈开发专家
工具调用(Tool Calling)基本流程五步,配 Java 实现讲:
1. 定义工具:名称+描述+参数 JSON Schema(描述写给模型看,决定选得对不对):
java
@Tool(description = "查询订单物流状态,用户问'到哪了/什么时候到'时使用")
public LogisticsVO track(@ToolParam(description = "订单号,形如 A123") String orderId) {
return logisticsClient.track(orderId);
}2. 模型决策:框架把工具定义转成请求的 tools 字段随消息发出;模型分析后输出结构化 tool_call(工具名+参数 JSON)——模型只产生意图,不执行。
3. 执行前校验(生产必备):JSON Schema 校验参数(防幻觉参数)、业务规则校验(状态机:未支付订单不能查物流?)、权限校验(这个用户能查这个订单吗)、写操作加幂等键。
4. 执行工具:真正调后端 API/查库,带超时和资源限制;结果裁剪成模型友好的紧凑形态(大 JSON 要瘦身)。
5. 结果回传循环:结果作为 tool 消息追加对话,再调模型——模型基于结果继续生成自然语言回答,或发起下一个调用,直到最终答案。
踩坑清单:一,工具描述空泛是选错工具的头号原因,写清「什么场景用、与相邻工具的区别」;二,工具报错要结构化回喂(错误码+建议动作),模型能自纠;三,同义工具别造两个(queryOrder 和 getOrder 模型必混淆);四,工具数量超过 20 个考虑工具检索(按需注入 schema)。