失败分类
工具失败、数据缺失、推理错误、规则冲突与环境异常。
一句话理解:失败要先分类再处理:工具失败就重试或换路,数据缺失就补数或如实标注“无法判断”,推理错误要靠外部验证拦截,规则冲突交给人裁决,环境异常就等待、刷新或降级。
“失败了就重试”是很多 Agent 的默认策略,也是最浪费的策略。接口超时重试一次也许就好了;可如果是数据本身不存在,重试十次结果还是一样;如果是业务规则互相矛盾,重试只会让 Agent 在两条规则之间来回摇摆,把预算烧完。
所以验证发现问题后,第一件事不是“再来一次”,而是判断这是哪一类失败。这一课讲运行时的失败分类与对应的恢复策略。重试、退避、断点续跑等实现机制见 错误恢复与重试;上线后对一批失败案例做离线归因,见 错误归因。
五类失败
| 类型 | 定义 | 通用例子 | 典型信号 | 默认恢复策略 | 重试有用吗 |
|---|---|---|---|---|---|
| 工具失败 | 工具调用本身没有成功 | 日志查询接口超时;参数格式错误被拒绝;被限流 | 超时、错误码、参数校验报错 | 修正参数后重试;临时错误退避重试;换备用工具 | 有用,但要限次 |
| 数据缺失 | 调用成功,但需要的信息不存在或不完整 | 工单没有关联订单号;操作日志为空 | 空数组、字段为 null、记录不存在 | 换数据源补数;向用户询问;输出“无法判断” | 没用 |
| 推理错误 | 数据齐全,但判断、计算或归因错了 | 把“支付回调失败”判成“用户未付款”;时区算错 8 小时 | 验证不通过、结论与证据对不上 | 用程序计算替代心算;补充上下文后重做;交给评审或人工 | 原样重试基本没用 |
| 规则冲突 | 规则之间矛盾,或规则没有覆盖当前情况 | SOP 写“超时超过 72 小时自动退款”,但企业客户须人工审批 | 多条规则同时命中、找不到适用规则 | 停下来,升级给规则负责人裁决 | 没用 |
| 环境异常 | 执行环境或依赖出了问题,与本次任务内容无关 | 访问令牌过期;沙箱磁盘满;下游系统维护中;后台页面改版 | 认证失败、资源不足、维护公告、选择器失效 | 刷新凭据;等待后恢复;降级到其他执行方式;通知运维 | 视情况,通常要先修环境 |
边界不清时,可以问一个问题:**“换个参数,或者过一会儿再试,能不能好?”**能好的,多半是工具失败或环境异常;不能好的,就是数据、推理或规则问题。
分类决策树
拿到一次失败,可以按下面的顺序逐个提问:
让工具帮 Agent 分类
分类最难的一步,是 Agent 能不能看懂失败信号。如果工具只返回一句 Internal Error,模型根本无从判断。Anthropic 在关于为 Agent 编写工具的工程文章中建议,错误信息要具体、可行动,告诉 Agent 应该如何调整请求或参数;工具设计原则一课也讲过这一点。
一个对分类友好的错误返回(示例):
{
"error": {
"category": "data_missing",
"code": "ORDER_NOT_FOUND",
"message": "工单 T-20260917-0042 未关联订单号",
"retryable": false,
"suggestion": "可改用 get_orders_by_user 按用户 ID 查询近期订单;仍缺失时请输出 undetermined"
}
}
这里有两个关键字段:category 使用固定枚举,而不是自由文本,方便 Harness 按类别走不同的恢复分支,也方便事后统计;retryable 由工具层判断,避免 Agent 对不可重试的错误反复尝试。
有了这两个字段,恢复流程就可以交给 Harness 按类别分流:
五份恢复剧本
工具失败。 参数类错误,按错误信息修正后重试一次;超时、限流这类临时错误,退避后重试,设置上限(例如同一工具连续失败 3 次,示例数字)。写操作重试前先检查是否已经执行,避免重复创建工单。超过上限后,按什么时候停下来找人的规则升级。
数据缺失。 先看有没有替代数据源:订单号查不到,能不能从用户的近期订单反查?仍然没有,就如实输出“无法判断”,并写明缺了哪些字段。绝对不能让模型“根据经验推断”补上缺失的数据。
推理错误。 运行时很难靠 Agent 自己发现,通常依赖验证层拦截:证据回溯对不上、程序重算结果不一致、评审不通过。拦截之后,可以把验证结果作为新信息交给 Agent 重做一次;如果是计算类错误,从根上改成由程序计算。
规则冲突。 这不是 Agent 该自己拍板的事。停下来,把冲突的规则、命中的条件、当前案例的数据打包交给规则负责人。事后更新 SOP 或指令,把这个案例加入评测集。
环境异常。 不要把它当成“任务失败”丢给业务用户,业务用户处理不了令牌过期。凭据类问题刷新后恢复;依赖系统维护中,就暂停任务、记录断点,恢复后继续执行;页面改版导致界面操作失败,考虑降级到 API,或者通知工程团队。
“无法判断”是一种正确的结果
数据缺失时,最危险的不是 Agent 失败,而是 Agent 自信地给出错误结论。因此,要在输出契约里把“无法判断”设计成正式状态(示例):
{
"ticket_id": "T-20260917-0093",
"status": "undetermined",
"missing": ["operation_logs", "order_id"],
"tried": ["get_ticket", "get_logs", "get_orders_by_user"],
"next_step": "请用户确认下单时使用的账号"
}
假设在 100 个客服工单案例上评测,结果是正确 87、错误 8、无法判断 5(示例数字)。那 5 个“无法判断”的价值,往往比把它们硬猜出来更高:猜对了省一点人工,猜错了可能导致错误退款或错误追责。
让分类沉淀为数据
每次失败都按固定枚举记录类别,一段时间后就能看到分布(示例):
| 失败类别 | 本周次数 | 占比 | 说明 |
|---|---|---|---|
| 工具失败 | 120 | 48% | 其中七成来自日志查询接口超时 |
| 数据缺失 | 70 | 28% | 集中在历史迁移的老工单 |
| 环境异常 | 30 | 12% | 周三令牌轮换导致集中失败 |
| 推理错误 | 20 | 8% | 主要是跨时区时长计算 |
| 规则冲突 | 10 | 4% | 企业客户退款规则 |
这张表直接告诉团队:优先修的是日志查询接口的稳定性,而不是换模型。这类统计放进看板的方法见日志、指标与告警。
常见误区
- 所有失败统一重试。 对数据缺失和规则冲突重试,只会浪费预算,还可能让模型在反复尝试中编造结果。
- 把数据缺失当成推理问题,让模型“再想想”。 缺的数据想不出来,只会被编出来。
- 失败类别让模型用自由文本描述。 “接口好像出了点问题”无法统计,也无法驱动恢复分支。类别必须是固定枚举。
- 把环境异常报告给业务用户。 用户看到“任务失败”却无能为力,信任迅速下降。环境问题应该路由给运维或自动恢复。
产品经理检查清单
- 你的 Agent 是否为失败定义了固定的类别枚举?
- 每一类失败有没有对应的默认恢复策略和重试上限?
- 工具返回的错误信息是否足以让 Agent 分辨类别,是否标注了可否重试?
- “无法判断”是不是输出契约中的正式状态,用户能否看到缺了什么?
- 规则冲突和环境异常分别升级给谁?
- 失败类别是否被记录并统计,能否按周查看分布?
练习
给下面 8 条失败记录分类(工具失败 / 数据缺失 / 推理错误 / 规则冲突 / 环境异常),并写出你建议的恢复动作:
- 调用
get_logs返回 504,第二次调用成功。 - 工单查询成功,但
contact_email字段为空,Agent 需要联系提交人。 - Agent 计算超时时长为 20 小时,实际为 28 小时,日志时间是 UTC,当前时间取的是北京时间。
- 所有工具调用都返回 401,提示令牌已过期。
- 客户是企业客户,SOP 第 3 条要求自动退款,第 7 条要求人工审批。
- Agent 调用
create_ticket时priority传了"紧急",工具要求取值为P0到P3。 - 日志中有“用户已撤销”事件,Agent 却判断为“仍在处理中”。
- 通过浏览器操作后台系统时,找不到“提交”按钮,后台当天刚发布新版本。
参考答案:1 工具失败;2 数据缺失;3 推理错误(应改为程序计算);4 环境异常;5 规则冲突;6 工具失败(参数类);7 推理错误;8 环境异常。
延伸阅读
- Writing effective tools for agents — with agents(Anthropic):包括如何让工具返回具体、可行动的错误信息。
下一步
失败分了类,有些能自动恢复,有些必须交给人。下一课「什么时候停下来找人」讨论重试上限、置信度阈值,以及升级到人工时该交出什么。