恢复策略
为智能体提供明确的应对故障的计划。通过验证输出和捕获工具错误来检测故障;然后通过调整进行重试、回退到备用路径、回滚部分操作或进行升级。限制重试次数以避免失控循环和成本超支,使操作具备幂等性,并区分瞬态故障与永久故障。其目标是实现优雅降级,而不是崩溃或产生隐蔽的错误结果。
问题
智能体经常发生故障:工具超时、API 返回错误、模型输出格式错误、计划陷入死胡同,以及多步骤工作流留下部分副作用。如果没有明确的恢复路径,智能体要么在遇到第一个错误时崩溃,要么(更糟糕的是)继续使用错误的数据,并默默地产生看似笃定实则错误的输出。幼稚的重试循环会让情况变得更糟,不断冲击发生故障的依赖项、消耗 Token 并陷入无限循环。难点不在于捕获单个错误,而在于判断故障的类型以及采取何种应对措施才是安全的。
适用场景
在任何调用外部工具、运行多步骤计划或执行可能部分完成的重要操作的智能体中,都可以使用此模式。它对于无人实时监控的长期运行或自主工作流,以及具有副作用的操作(支付、写入、发送电子邮件,其中盲目重试可能会导致重复工作)最为重要。它假设您可以根据某种契约验证输出,并且至少某些操作可以实现幂等或得到补偿。对于单次、只读、低风险的提示词,该模式的关联性较低。
解决方案
将恢复视为围绕智能体正常执行构建的一等控制循环。每次工具调用和模型输出都要通过验证门:捕获异常和超时,并在信任输出之前根据 Schema 或契约对其进行检查。发生故障时,对其进行分类。瞬态故障(超时、速率限制、5xx 错误)将通过指数退避和抖动进行有界重试,最好是针对幂等操作,这样重复请求就是无害的。永久故障(无效参数、身份验证错误、契约违规)则跳过重试,直接转向备用方案:不同的工具、更简单的计划或回退答案。\n\n当进度至关重要时,对状态进行检查点记录,以便智能体可以从上一个正常步骤恢复,而不是重新启动。当某个步骤已经产生副作用且无法继续时,运行补偿操作以进行回滚——取消订单、删除草稿、撤销收费。将整个循环封装在硬性预算中:最大尝试次数、最大实际运行时间以及成本上限,外加一个熔断器,用于停止调用持续失败的依赖项。当所有恢复选项都耗尽时,进行干净的升级——将故障呈现给人类或主管智能体,并提供足够的上下文以便其采取行动,而不是凭空猜测。
组件
优势
- 智能体会产生部分或回退结果以及清晰的状态,而不是崩溃或返回看似笃定实则是垃圾的信息。
- 硬性的尝试次数、时间和成本限制可以阻止失控的重试循环在发生故障的依赖项上烧掉预算。
- 当工作流中途停止时,补偿操作和检查点可以保持外部系统和任务状态的一致性。
- 当恢复失败时,智能体在移交工作时会提供足够的上下文,以便人类或主管采取行动,而不是凭空猜测。
风险
- 对处于困境的依赖项进行激进的重试会增加负载,并可能将短暂的波动演变成级联故障。
- 如果不使用请求 Key,重试非幂等操作可能会导致重复收费、重复发送或重复写入。
- 过于急切的回退可能会掩盖系统性故障,使损坏的工具看起来正常,同时却在悄悄降低每个结果的质量。
- 回滚逻辑通常不完整,或者其自身也会失败,从而使系统处于难以检测的不一致状态。
不适用场景
- 对于没有副作用且没有多步骤计划的低风险提示词,简单的“重试或失败”就足够了;完整的恢复机制反而是额外开销。
- 当故障意味着任务确实无法完成时(例如缺少权限、API 已弃用),重试和回退只会浪费时间——应快速失败并进行升级。
- 如果某种副作用是不可逆的,且无法实现幂等,请勿跨越该步骤进行自动重试;相反,应要求确认或人工审批。
技术
示例
- 研究智能体的搜索工具返回 503 错误;智能体通过退避进行重试,在第三次尝试时成功,并在不导致运行崩溃的情况下继续执行。
- 代码智能体生成的 JSON 未通过 Schema 验证;验证门将其拒绝,并带上错误信息重新进行提示,而不是将格式错误的数据传递给下游。
- 预订智能体预订了机票,但酒店预订步骤发生永久性失败;补偿处理器会取消机票预订并进行升级,而不是留下一个只预订了一半的行程。
生产实践证据
- 上下文
- 在 57 天内(161 个会话 / 2,776 轮)观察到的单操作员、本地优先的 OpenClaw 部署,数据从智能体自身的轨迹追踪中聚合而来。
- 场景
- 自主轮次期间的错误、中止和超时会被重试/退避和模型回退链吸收,从而使智能体保持运行。
- 技术
- 具有指数退避和抖动的 retryAsync、runWithModelFallback、中止传播以及针对重复触发循环的 cron 自我保护。
- 负载
- 观察到 2,942 个终端轮次;其中包含 52 个错误、126 个中止、120 个超时和 31 个提示词错误。
- 结果
- 在 2,942 轮中,终端错误率为 1.77%;恢复原语吸收了瞬态故障,部署保持了 98.8% 的会话成功率。单操作员本地优先部署。
KPI
- 恢复成功率
- 在没有人工帮助的情况下,通过重试或回退自动解决的故障比例;健康的值应当较高且稳定,没有无声的下降趋势。
- 每个成功任务的平均尝试次数
- 成功需要尝试多少次;注意观察次数的攀升,这通常预示着依赖项性能下降,而非真正的恢复。
- 无限循环/预算超支率
- 运行达到重试、时间或成本上限的频率;这应该是罕见的,出现峰值意味着限制或分类需要调整。
- 补偿完整性
- 以一致状态结束的失败多步骤工作流的比例;目标是完全回滚,不留下孤立的副作用。
已观测到的失效模式
- 缺失或过高的尝试次数上限会导致智能体无限期地重试永久性故障,从而烧掉成本且永远无法取得进展。
- 将永久性错误视为瞬态错误会浪费重试次数;将瞬态错误视为永久性错误则会过早放弃并触发不必要的回退。
- 回退路径返回了一个看似合理但错误的答案,且没有发出已发生恢复的信号,导致下游使用者信任了错误的输出。
- 智能体在写入或执行外部操作之后、但在运行补偿之前发生故障,从而留下重复或悬空的记录。
经验教训
- 重试/回退/升级的决策取决于故障是瞬态的还是永久性的;在调整退避曲线之前,应先投入精力进行清晰的分类。
- 幂等 Key 可以将高风险的重试转化为安全的重试;应在前期进行设计,而不是在后期才强行加入去重机制。
- 对尝试次数、时间和成本的硬性限制是不可妥协的;没有这些限制的智能体最终总会找到一种无限运行下去的方法。
- 记录每一次重试、回退和补偿,以便将隐蔽的降级转化为可见的指标,而不是突发的意外事件。
常见问题
- 这与仅仅添加 try/except 和重试循环有什么区别?
- Try/except 只能处理单个错误;而恢复策略则负责判断故障的类型,并在硬性预算下在重试、回退、回滚和升级之间做出选择。其实质在于控制逻辑和幂等性,而非异常处理本身。
- 我应该允许多少次重试?
- 很少——通常是一个较小的固定上限,配合指数退避和抖动,外加独立的时间和成本上限。确切的次数取决于依赖项,但循环必须始终能够终止,且根本不应该对永久性故障进行重试。
- 如果某个操作无法撤销或无法实现幂等怎么办?
- 不要跨越该步骤进行自动重试。在不可逆步骤之前记录检查点,并在失败时升级给人类或主管智能体,而不是凭空猜测。不可逆性是放慢速度的信号,而不是加大重试力度的信号。