很多人第一次做 Agent,模型能聊但一让它调用真实接口就乱:工具描述写得含糊、参数对不上、鉴权 Key 到处塞、调用链一深就不知道哪一环断了。这篇不聊概念,按「注册工具—设计鉴权—规划调用链」三段走,每段给你能照着做的动作和自查项,最后给一组出错时的排查顺序。
很多人第一次做 Agent,模型聊天很顺,一让它调用真实接口就乱套:要么选错工具,要么参数对不上,要么 Key 到处塞导致安全兜不住,要么调用链一深就不知道哪一环断了。这篇不聊概念,按「注册工具—设计鉴权—规划调用链」三段走,每段给你能照着做的动作和自查项,最后给一组出错时的排查顺序。
先明确适用范围:这套做法适合工具数量可控、调用链相对确定的场景,比如内部助手、客服工单流转、数据查询机器人。如果你的 Agent 要做开放式规划、工具数量上百且频繁变动,下面每节的「不适用」提示要认真看,那类场景需要更重的编排层,不在本文讨论范围。
工具注册:让模型知道你有哪些能力
工具注册的本质,是把「你能做什么」翻译成模型看得懂的说明书。说明书含糊,模型就靠猜。判断标准很简单:把每个工具的描述拿给一个不了解你系统的同事看,他能不能说清什么场景该用、参数填什么形状。说不清,就是描述不合格。
- 做什么
- 一句话说清工具的单一职责,避免「处理数据」「执行操作」这类谁都能套的话。
- 什么时候用
- 写清触发场景和明显不该用的边界,减少模型在相似工具之间反复横跳。
- 参数是什么
- 每个字段的类型、必填、取值范围、示例值都写死,不留模糊空间。
- 参数用严格 schema 表达:类型、必填、枚举值都固定,模型最容易犯的错是多包一层对象、把数字写成字符串,schema 越松越容易出这类问题
- 同类操作合并成一个工具加参数分支,别把每个小动作都注册一遍;工具太多时模型选错工具的概率明显上升,判断标准是你能不能一眼扫完工具列表
- 注册完先拿几个典型问法手动跑一遍,看模型选中的工具和你预期是否一致;不一致时改描述而不是改模型
- 描述里给一两个具体示例,示例要贴近真实输入,带偏的示例比没有示例更糟
- 工具的返回值结构也要写进说明,模型对返回字段的理解直接影响它下一步决策
鉴权设计:Key 放哪、权限给多少
Agent 的鉴权分两层,很多人混成一把就出事:第一层是 Agent 调用你的后端工具时用什么身份,第二层是你的后端调用上游模型或第三方 API 时用什么 Key。这两层的生命周期、权限范围、存放位置完全不同,必须分开设计。混在一起的后果是,一个环节泄露,整条链都被人拿走。
| 层次 | 放哪 | 权限给多少 | 轮换影响 |
|---|---|---|---|
| Agent 调你的工具 | 服务端签发,按会话或用户下发短期凭证 | 只开真要用的接口和范围,能读别给写 | 只影响该会话,吊销即时生效 |
| 你的后端调上游 | 服务端环境变量或密钥管理服务,绝不下发 | 按用途拆多把,分别对应不同上游 | 只影响对应那把,互不干扰 |
| 客户端直连场景 | 不直连,统一走网关转发 | 网关侧做鉴权和限流 | 改网关配置,前端无感 |
- 给 Agent 用的凭证走最小权限:能限单用户就别给全局,能设有效期就别长期有效,出问题时损失可控
- 上游 Key 一律放服务端,不写进模型能读到的上下文里;提示词、工具返回、日志里都不该出现明文 Key
- 按用途拆多把 Key,轮换和吊销时互不影响;离职、换人、额度见底这类情况只动对应的那一把
- 在服务端加一层出站校验,把不该出现的域名和路径拦掉,防止模型被诱导去调非预期接口
- 记录每次鉴权失败的原因分类,凭证过期、权限不足、被限流要能区分,不然排查时只能猜
调用链规划:一次任务经过哪几跳
调用链规划的目标,是让每一跳的失败都有明确归宿,而不是让 Agent 自由发挥到超支或死循环。先把链路画出来:用户请求 → 模型决策 → 工具调用 → 结果回填 → 下一轮决策。图上标出每一跳的超时、重试和失败回退分别怎么处理,标不出来的地方就是未来出事的地方。
- 画链路图把每一跳的输入输出写清楚,包括模型这一步看到什么上下文、工具返回什么结构;验证方式是找另一个同事照图复述一遍,能复述就说明没歧义。
- 设两道上限最大步数和最大花费都要设,超过就停下来返回中间结果;验证方式是故意构造一个会绕圈的任务,看它是否在到达上限时干净退出。
- 隔离不可逆动作下单、发消息、删数据这类单独拉出来做人工确认或二次校验,不要和查询类工具走同一条自动通道;验证方式是模拟一次误触发,看是否有拦截。
- 按链路记日志每一步的输入摘要、选中工具、耗时、失败原因都记下来,缺任何一项事后都很难定位是哪一跳坏的;验证方式是拿一次失败调用回放,看日志能否还原全过程。
| 失败位置 | 典型原因 | 先查什么 |
|---|---|---|
| 模型没选工具 | 描述含糊、路由规则缺失 | 工具描述和提示词里的路由规则 |
| 选了但参数不对 | 类型错、多包一层、必填缺失 | 对照 schema 和描述里的示例 |
| 参数对但请求失败 | 鉴权、网络、限流 | 凭证有效期、权限范围、地址和超时 |
| 都通过但结果不对 | 返回结构模型理解不了 | 工具返回值是否需裁剪或重排 |
调用链设计的底线不是让 Agent 更聪明,而是让它出错时能停下来、能查清。
出问题时按这个顺序排查
Agent 出错最忌讳到处改。按下面的顺序走,每一步只改对应层,改完立即复测同一个用例。跳步排查会把真正的原因掩盖掉,让你误以为修好了。这套顺序的判断依据是:越靠前的环节影响面越大,先排除掉能缩小后面排查范围。
- 第一步:看模型有没有选中工具没选就回去改工具描述和提示词里的路由规则,不要先怀疑接口;验证方式是用同一问法重跑,看选中率是否变化。
- 第二步:选了但参数不对对照 schema 看是类型、必填还是多包一层,多数是描述里的示例带偏了;验证方式是拿模型输出的参数直接跑一遍 schema 校验。
- 第三步:参数对但请求失败按鉴权(凭证过期、权限不足)、网络(地址、超时)、上游限流三类逐项排;验证方式是先用 curl 或调试工具绕过模型单独调一次。
- 第四步:都通过但结果不对看工具返回的数据结构是不是模型理解得了,必要时在返回前做一次裁剪或重排;验证方式是手工构造一个理想返回值,看模型下一步决策是否恢复正常。
- 每步只改一层,改完立即复测,避免多个变量同时动
- 先把失败用例固定下来,不要每次换新问法,否则无法对比
- 日志里的失败原因要分类,别只记一句「调用失败」
- 修完把这次的原因写进工具描述或链路文档,别等下次再踩
- 涉及真实数据的调试用脱敏样例,别拿生产数据直接试
常见问题
工具描述写到什么程度算够?
标准是:一个没看过你代码的人,只看描述就知道这个工具做什么、什么时候该用、要传什么。描述里出现「处理」「相关」「等」这类模糊词就要返工。写完拿几个边界问法试一遍,看模型会不会误选,误选就补一句「什么情况下不要用」。
Agent 的 Key 能不能和前端共用一把?
不建议。前端能拿到的 Key 等于公开,任何人抓包都能用。正确做法是前端只调你自己的后端,后端拿服务端存储的 Key 去调上游。如果非要在浏览器直连,至少走一层网关转发并做来源校验,同时给这把 Key 单独设额度上限。
调用链一深就慢,先优化哪一环?
先量再改。记录每一步耗时,看时间花在模型决策、工具执行还是网络往返。多数情况是串行步数太多,把互不依赖的查询类工具并行发起就能省一大截;模型决策占大头的话,是工具描述太长或工具太多导致选择变慢,收窄候选集比换模型有效。