知

模块三 · Agent 内核

第 7 / 14 节19 分钟阅读型

工具调用:别把模型当成可信执行者

工具调用的本质是"模型提请求、系统做决定"。这一节把 schema 设计、服务端校验、结构化错误与权限边界讲成一条能落地的链路。

读完这一节,你能做到

  1. 说清一次工具调用的完整链路,以及哪里必须由系统把关。
  2. 按四条原则设计出让模型"不容易选错"的工具。
  3. 让工具失败时返回模型能自纠的信息,而不是一句"失败"。
  4. 说清为什么权限永远不能由对话决定。

一、工具调用发生了什么

用户提问
→ 模型输出一段结构化的"调用请求"(工具名 + 参数)
→ 系统校验参数、鉴权、执行
→ 执行结果回填给模型
→ 模型基于结果继续推理或回复

两个关键认知:

  • 模型不执行任何东西。 它只是生成"我想调这个工具、参数是这样"。真正执行的是你的代码。
  • 模型输出的是不可信输入。 参数可能是编的、越界的、恶意的(被注入诱导时)。所有校验必须在代码里做。

二、schema 设计的四条原则

1. 名字要能自我判别

query_order_by_id 比 search 好,search_orders 与 search_products 要一眼能分开。名字承担了第一层选择成本。

2. 描述要写边界

不只写"这个工具做什么",还要写"什么时候不要用"。比如:

query_order_by_id:按订单号精确查询。订单号未知时,先用 search_orders 查找。
不要用它查用户订单列表——那是 list_user_orders 的职责。

这一句能消掉大量误调用。

3. 参数少而具体

  • 必填项明确,能枚举就枚举。
  • 给示例值,减少格式猜测。
  • 开放式字符串参数越少越好。

4. 不要万能工具

execute_sql、run_code、http_request 这类工具,等于把权限和风险交给了模型。如果业务确实需要,至少要加白名单与只读限制。

三、工具多的时候怎么办

工具到十几个以后,模型的选择准确率会明显下降。

做法:按场景分组,只把当前场景相关的子集给模型。比如"售后场景"只给订单查询、退款、物流三个工具,不给营销与库存。

判断标准:一个工具如果在这个场景里永远不该被调用,就别放进去。

四、服务端必须做的两件事

1. 校验

  • 结构校验:类型、必填、枚举范围。
  • 业务校验:这个用户有没有权限、这个状态能不能变、金额是否超限。

schema 定义得再严,也只是给模型的约束;服务端的校验才是保障。

2. 幂等

写操作必须带幂等键(由业务生成,不是模型编的)。同一 key 重复请求返回第一次的结果,而不是重复执行。

超时场景尤其要注意:结果未知时先查状态,不要直接重试。

五、失败时返回什么给模型

这是最容易被忽略、也最影响体验的一环。

差的返回

{"error": "failed"}

模型无法判断是参数错、权限错还是临时故障,只能反复重试。

好的返回

{"error": "stock_insufficient", "requested": 5, "available": 2,
 "suggestion": "把数量改为 2 或更少,或告知用户补货时间"}

结构化错误让模型能换参数、换策略,或者直接向用户解释。

结果也要裁剪

工具返回 500 行数据,塞进上下文既贵又稀释。返回前先截断:只给必要字段 + 前 N 条 + 总数。

六、权限边界:三条底线

  1. 身份来自会话,不是模型自述。模型说"我是管理员"没有任何含义。
  2. 最小权限:工具粒度要能落到"查本人订单",而不是"查所有订单"。
  3. 高影响动作人审:退款、删除、对外发送、改权限,先生成待确认操作单,人点了再执行。

再加一条:审计日志。谁、什么身份、什么参数、什么结果、耗时多少,出事时要能还原。

上线前的检查清单

一个新工具从设计到上线,过完这六条再放给模型:

  1. 名字能让模型区分它和相邻工具吗?
  2. 描述里写了“什么时候不要用”吗?
  3. 参数里还有开放式字符串吗?能枚举的都枚举了吗?
  4. 服务端有没有做业务校验(不只是类型校验)?
  5. 写操作有幂等键吗?超时后是查状态还是直接重做?
  6. 失败时返回的信息,能不能让模型自己修正?

这六条里,第 1、2 条解决“选不对”,后四条解决“选了也干不好”。漏掉任何一条,上线后都会以“模型不听话”的形式表现出来。

七、常见坑

  1. 相信模型传的参数。 不校验就直接查库。
  2. 工具名太泛。 模型只能靠描述猜,误调用率高。
  3. 一次给几十个工具。 选择准确率断崖式下降。
  4. 失败只回一句"失败"。 模型学不会,只能重试。
  5. 工具返回原始大对象。 上下文被塞满,成本与延迟都涨。
  6. 高影响动作直接执行。 一次误判就是真实损失。

八、动手任务:自写 → AI 写 → 对比 → 取舍

四步不跳:① 自己写(限时,关掉补全)→ ② 让 AI 写同一题 → ③ 逐条比对 → ④ 说出保留谁的写法。

① 自己写

  1. 为一个售后场景设计 3 个工具:名字、参数、描述(含"什么时候不要用")、错误返回结构。
  2. 写出这三个工具的服务端校验清单与幂等方案。

② 让 AI 写同一题

把第 1 题交给 AI,补一句 只给 JSON schema 与错误码表,不要写实现代码;每个工具必须写明不适合的场景。

③ 对比要盯的点

  • 它的工具名是否足够可判别?
  • 参数里有没有开放式字符串(容易编)?
  • 错误返回能不能让模型自纠?

④ 一句话取舍

如果三个工具里只能保留两个,你会砍哪个?为什么。

九、自测

  1. 工具调用的完整链路是什么?哪一步必须由系统做?
  2. schema 设计的四条原则是什么?
  3. 工具多了为什么准确率会下降?怎么解决?
  4. 服务端为什么必须再做一次校验?
  5. 为什么错误要结构化返回?举一个能自纠的例子。
  6. 权限的三条底线是什么?

参考答案要点:模型提请求、系统执行;名字可判别、描述写边界、参数收敛、不用万能工具;按场景给子集;schema 只是给模型的约束;告诉模型缺什么、可选什么;身份来自会话、最小权限、高影响人审。

配套题目

★ 越多越该先背;点题目可看完整答案与深入版。

提示:读完可以顺手做几道对应题目,检验是否真的理解