Agent 工具调用失败怎么办?从错误分类、超时接管到幂等重试的工程指南

补充:术语、错误字段与结果未知时的返回示例

1. 工具调用与工具执行

工具调用是模型提出“使用哪个工具、传入什么参数”;工具执行是应用真正访问接口、运行命令或修改数据。模型生成了调用,并不代表操作已经成功。OpenAI 的 Function calling 文档将这两个阶段明确分开。

2. 瞬时错误与确定性错误

瞬时错误可能随着时间过去而消失,比如短暂网络故障;确定性错误在相关条件不变时不会自行消失,比如缺少必填字段。分类是为了决定恢复方式,不能只凭一条“调用失败”的提示下判断。

3. 指数退避与随机抖动

指数退避是逐步拉长重试间隔。随机抖动是在间隔里加入随机性,避免大量客户端同时再次访问服务。

正文中的 random(0, min(cap, base × 2^n)) 是一种常见的全抖动写法:base 是初始等待尺度,cap 是等待上限,n 是重试序号。次数和累计耗时还需要单独限制。

4. Retry-After

服务端提示客户端应等待多久再发送后续请求的 HTTP 响应头。其值可能是等待秒数,也可能是 HTTP 日期。它提供等待提示,不保证到时服务一定恢复,更不能代替写操作的防重复保障。

5. 副作用与幂等

副作用是操作改变了外部状态,例如发出邮件、创建订单、扣减库存。

幂等是同一个操作重复执行时,预期效果与执行一次一致。它不要求每次响应文字完全相同。例如第一次删除资源可能返回成功,第二次返回不存在,但资源最终都处于已删除状态。

6. Idempotency-Key

用于标识同一个业务操作的请求键。第一次请求前生成并保存;该操作发生重试时复用,而不是每次网络请求都重新生成。

Stripe 的约定是一个具体实现:同键请求可以返回首次保存的结果,包括 500;同键参数改变会报错,记录清理后再使用原键可能形成新请求。其他服务必须查看自己的接口约定。

7. “结果未知”与“失败”

“失败”通常表示已经得到明确失败结果;“结果未知”表示客户端无法确认最终状态。

付款请求超时后,钱可能已经扣了。把它直接写成失败,再创建一笔新付款,可能导致重复操作。结果未知是需要保留的业务状态,不是一个应该被掩盖的异常。

8. 超时、取消与回滚

超时是等待超过限制;取消是请求停止继续执行;回滚是撤销已经发生的修改。三者不同。

停止等待不会自动撤销远端订单,杀死进程也不会自动恢复已写入的文件。某些操作只能通过补偿动作处理,例如取消订单;补偿本身同样可能失败,需要确认结果。

Python 的 Popen.communicate(timeout=...) 超时不会自动杀死子进程,而 subprocess.run(timeout=...) 有不同的处理行为。使用执行器前,应确认具体接口的取消和清理约定。

9. 严格模式与业务校验

严格模式约束模型输出的参数结构,例如字段是否齐全、类型是否正确。它不替应用验证库存、金额上限、对象归属或用户权限。结构合法的请求,仍然可能违反业务规则。

10. is_error 与 isError

这是不同协议的字段,不能混用。

Claude 客户端工具结果的示例:

{
  "type": "tool_result",
  "tool_use_id": "toolu_example",
  "is_error": true,
  "content": "结束时间早于开始时间;本次未创建日程。请检查时间字段。"
}

MCP 工具执行错误的结果示例:

{
  "content": [
    {
      "type": "text",
      "text": "结束时间早于开始时间;本次未创建日程。"
    }
  ],
  "isError": true
}

以上只展示结果对象,不是完整 HTTP 请求。MCP 的工具执行错误与 JSON-RPC 协议错误也要区分:工具运行后报告业务错误,与请求无法按协议处理,并不是同一层问题。

11. 推荐给应用内部使用的错误信息

下面是自定义业务结果示例,不是 OpenAI、Claude 或 MCP 的统一标准:

{
  "operation_id": "op_example_001",
  "status": "unknown",
  "error_code": "RESPONSE_TIMEOUT",
  "execution_confirmed": false,
  "retry_allowed": false,
  "next_action": "query_operation_status",
  "message": "提交后未收到响应,尚未确认是否执行。请先查询已有操作状态,不要创建新操作。"
}

retry_allowed 和 next_action 应由执行层根据接口约定计算。模型可以利用这些信息调整计划,但不能靠修改字段给自己授予重试权限。

12. τ-bench 与 pass^k

τ-bench 是研究工具 Agent 在业务规则下与用户交互、执行任务的评估环境。评估会检查最终数据库状态,而不只检查模型是否声称完成。

论文中的 pass^k 考察同一任务在多次独立执行中都成功的可靠性;不要与“尝试 k 次,有一次成功就算通过”的 pass@k 混淆。

正文引用的 “think” tool 数字来自 Claude 3.7 Sonnet 的历史实验。Anthropic 当前已在该文章顶部说明,多数情况下推荐使用 extended thinking,而不是专门增加一个 think 工具。引用该实验是说明中间推理会影响任务完成率,不是推荐照搬旧模型配置。

对应资料