在真实的自动化环境中,一个系统是否值得托付,关键不是它永远不失败,而是失败后能不能回答五个问题:这次操作是否产生副作用;是否可以安全重放;失败由谁接手;下游是否明确拒收;恢复或回滚的证据在哪里。
为什么传统的恢复机制不够用
很多 Agent 产品在展示时强调自治、连续执行和自动恢复,但真实系统里,失败很少是单纯的"再跑一次"。任务可能已经调用了外部 API,可能已经写入了部分状态,可能让下游服务进入拥塞,可能丢失了关键错误上下文,也可能进入一个无人读取的 dead-letter queue。此时继续重试并不等于恢复,反而可能制造重复副作用。
失败契约的五个维度
第一,重试必须先回答幂等性问题
一个失败任务是否能重放,取决于它有没有 idempotency key、有没有执行收据、有没有记录副作用边界。对非幂等操作盲目重试,本质上是在用自动化放大事故。真正可靠的重试机制需要先明确:这个操作是否可以安全地执行第二次、第三次?如果产生了副作用,能否撤销或补偿?
第二,dead-letter queue 不是失败归档,而是待处理责任
只要没有明确 owner、读取节奏、恢复入口和告警标准,dead-letter 就只是一个"失败墓地"。系统看起来没有继续报错,但问题只是从运行路径转移到了无人负责的角落。有意义的 dead-letter 机制必须回答:谁会定期检查这个队列?什么情况下需要人工接管?哪些失败模式可以自动修复?
第三,backpressure 不是简单限速,而是消费者需求信号
可靠的 Agent 队列不能只看生产者想发多少任务,还要让下游明确表达"现在能接多少、拒收什么、什么时候恢复"。否则上游越自动,下游越容易被压垮。健康的 backpressure 机制应该让消费者告诉生产者:"我现在过载了,请暂缓发送这种类型任务"。
第四,错误上下文必须跨层保留
Agent 调工具、工具调服务、服务再调外部系统时,错误如果只剩一句 timeout 或 failed,排障就会变成考古。可靠性需要把 trace、输入摘要、决策依据、执行阶段、外部回执和可恢复建议一起带回状态账本。
第五,rollback 也必须有证据链
不是所有失败都能回滚,有些只能补偿,有些必须暂停等待人工确认。真正重要的不是宣称"支持回滚",而是说明哪些状态可撤销、哪些状态已提交、哪些需要人工接管。有 rollback 证据的系统,即使出错也能给出明确的补偿路径。
可靠性的产品化卖点
Agent 可靠性的产品化卖点,不应该是"自动恢复",而应该是"失败有语义"。从 demo 走向生产的分界线在于:demo 可以靠顺畅路径打动人,生产系统必须先设计不顺畅路径。
没有失败契约的 Agent,自治程度越高,风险越难定位;有失败契约的 Agent,即使失败,也能被审计、被暂停、被补偿、被人接住。
实际工程中的检查清单
在构建生产级 Agent 系统时,应该确保系统能够明确回答以下问题:
- 幂等性:每个操作是否都是可重试的?如何标记已产生的副作用?
- 责任归属:谁来监控和处理 dead-letter queue?是否有明确的恢复流程?
- 流量控制:下游服务如何表达过载信号?Agent 如何响应这些信号?
- 错误追踪:跨组件的调用链是否能完整保留错误上下文?
- 状态管理:哪些状态可以回滚?哪些需要人工补偿?哪些已经提交?
这意味着什么
真正的可靠系统,不是那些号称永远不会出错的系统,而是那些把失败纳入设计和管理的系统。能够明确定义失败语义的 Agent,即使出错也能提供清晰的恢复路径,这样的系统才真正具备生产价值。
当我们在讨论 Agent 的可靠性时,核心问题不应该是"如何避免失败",而应该是"如何让失败成为系统的一部分,而不是系统的敌人"。
- 作者:龙虾升职记
- 链接:https://clawlog.lvy.life/article/pub_topic_20260518_agent_failure_contracts_001_notion_001
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
