如何为 AI Agent 设计可靠的工具调用机制?
简化版
可靠的工具调用要过四道门:格式校验(Schema)、业务校验、权限校验、副作用保护(幂等/事务),再加错误分类、超时、重试、审计。核心红线——模型输出的工具名和参数只是「调用建议」,不能绕过用户权限或业务规则直接执行。Schema 管格式,执行层才管安全与正确性。
详细版
每个工具应职责单一,名称和描述说明适用条件、参数语义、副作用、返回值。执行链路:
模型提出调用 → 应用验证 Schema → 检查身份与权限 → 执行工具 → 规范化结果 → 把必要观察返回模型
结构化输出能减少格式错误,但不能保证参数业务正确、也不能证明用户有权执行。写操作还要用幂等键、乐观锁或事务,避免超时重试造成重复扣款、发信、建资源。
完整版教学
一、工具接口怎么设计:窄而明确
优先提供窄而明确的业务工具,别暴露万能接口:
✓ 好:get_order(order_id) request_refund(order_id, reason)
✗ 危险:run_sql(query) exec_shell(cmd) http_request(url) ← 权限过大、易被注入利用
枚举、范围、长度、必填都写进 Schema。关键认知:工具描述会影响模型选择,但描述文本本身不是安全策略——真正的限制必须在执行端实现。
二、四道门:Schema 之外还有三道
这是本题的核心框架。Schema 只是第一道,远远不够:
第1道 格式校验(Schema):类型、形状、枚举、必填对不对
第2道 业务校验:订单属于当前用户吗?金额≤额度吗?资源状态允许吗?动作和原始请求一致吗?
第3道 权限校验:当前用户对目标资源有权限吗?(身份凭证由运行时持有,不让模型生成/选择令牌)
第4道 副作用保护:写操作用幂等键/乐观锁/事务
记忆钩子:Schema 管格式、执行层管安全与正确性。 「参数形状对」离「这个操作可以安全执行」还差三道门。
三、错误怎么分类返回
错误要分类,让模型和运行时区别对待:
| 错误类型 | 处理 | 能否靠重试解决 |
|---|---|---|
| 瞬时(超时/限流/暂时不可用) | 有界指数退避重试 | 能 |
| 校验错误(参数不对) | 让模型修正参数再试 | 改参后能 |
| 无权限 | 停止,不该重复调用 | 不能 |
| 业务终态失败 | 记录原因,不盲目重试 | 不能 |
返回稳定错误码 + 安全摘要,绝不把堆栈、密钥、内部网络信息塞回模型上下文(会泄露 + 被注入利用)。
四、重试与幂等(最容易出事故的地方)
写操作的重试是重灾区。看一个经典事故:
Agent 调 request_refund(order_123, 50元) → 服务端执行成功,但【响应在网络中丢失】
Agent 以为失败 → 重试 → 又退了一次 50 元 → 重复退款!
正解:客户端生成幂等键 idempotency_key=uuid
服务端记录同一 key 的执行结果 → 第二次请求直接返回第一次的结果,不重复执行
只对瞬时故障做有界指数退避;无法安全重试的动作应查询最终状态或转人工。
五、结果与上下文:工具返回值不可信
工具返回的网页、邮件、数据库文本等仍是不可信数据——不能因为”来自工具”就升级为指令(间接 Prompt Injection 的入口)。大结果存外部,上下文只放引用、摘要、关键字段。
可观测性:记录请求 ID、工具版本、参数摘要、授权结果、耗时、错误码、状态变化,并对 PII 和密钥脱敏——才能回放失败轨迹、算工具成功率、定位责任边界。
六、常见误区与追问
- 误区:结构化输出(Schema)保证工具调用安全。 只保证格式,业务正确性/权限/副作用要另外三道门。
- 误区:模型说要调工具就执行。 模型输出只是建议,执行前必须过业务/权限校验。
- 误区:写操作直接重试就行。 会重复扣款/发信,必须用幂等键,服务端保证同 key 返回同结果。
- 误区:工具返回值可信、可当指令。 是不可信外部数据,可能藏间接注入,不能升级为指令。
- 误区:把错误堆栈返回给模型帮它调试。 会泄露密钥/内网信息并被注入利用,只返回稳定错误码+安全摘要。
- 追问:工具调用的四道门是什么? 格式校验(Schema)、业务校验、权限校验、副作用保护(幂等/事务)。
- 追问:为什么写操作要幂等键? “响应丢失但动作成功”会被误判失败并重试,导致重复执行,幂等键保证同 key 只生效一次。
- 追问:错误怎么分类? 瞬时(可退避重试)、校验错(改参重试)、无权限(停止)、业务终态失败(不重试)。
七、加强记忆
工具调用记「四道门 + 建议非命令」:格式校验(Schema)、业务校验(归属/额度/状态/一致性)、权限校验(真实身份,令牌由运行时持有)、副作用保护(幂等键/乐观锁/事务)。核心红线钉死:模型输出只是”调用建议”,Schema 管格式、执行层管安全与正确性;写操作必须幂等(防”响应丢失→重试→重复扣款”);工具返回值是不可信数据(可能藏注入、不能当指令);错误只返回稳定码+安全摘要(别回传堆栈密钥)。工具接口要窄而明确,别暴露 run_sql/exec_shell。