Lazy loaded image
Agent 工作流的可靠性应该写在失败边上
字数 1755阅读时长 5 分钟
2026-6-23
2026-6-23
很多 agent 工作流在 demo 里看起来很顺:一个节点接一个节点,工具调用、状态传递、平台发布都能串成完整路径。真正的问题通常不出现在这条顺风路径上,而是出现在某一步失败之后。
最危险的失败处理方式,并不是“没有重试”,而是用整图重放来掩盖失败边。系统不知道哪条边坏了,也不知道哪些副作用已经成立,于是把整个 workflow 重新跑一遍。表面上看,这是更积极的恢复;放到真实发布、写入、通知这些场景里,它很容易变成重复副作用的放大器。

整图重放为什么不够可靠

整图重放的诱惑在于简单:既然不知道哪里坏了,就从头再来一次。但 agent workflow 不是纯函数。它通常会调用外部工具、写数据库、发消息、创建页面、更新状态。一旦某些副作用已经成功,再从头运行就不只是“补一次”,而是在冒着重复发布、重复写入、重复通知的风险。
更麻烦的是状态本身。很多失败不会表现为明确的异常,而是表现为 partial state、stale state 或 silent null。上游 enrichment 超时,下游却继续消费半成品;跨组件 handoff 只传了结果,没有传依赖是否满足;工具 schema 发生漂移,字段缺失被解释成空值或 0。系统看起来没有崩,但已经在错误事实上继续前进。
这类问题靠更激进的 retry policy 很难解决。重试只是动作,真正决定动作是否安全的是契约:这一步需要什么输入,缺什么必须暂停,失败后能补偿哪一支,成功后哪些错误状态必须关闭。

恢复能力应该下沉到边

更可维护的恢复单位不是整条 workflow,而是边。
一条边连接了上游状态、当前动作和下游消费方。它天然知道自己依赖什么,也最适合声明自己失败后应该怎样恢复。至少有四类契约应该写在边上。
第一是输入契约。边需要说明自己依赖哪些上游状态,怎样验证这些状态是完整、最新且符合 schema 的。没有验证的 handoff,本质上是在把信任外包给下游。
第二是依赖契约。某些状态缺失时,系统应该暂停,而不是继续消费 partial state。这里的关键不是“尽量往前跑”,而是明确哪些缺口会让后续判断失真。
第三是补偿契约。失败后应该只重排哪一支,哪些已经成功的副作用必须跳过。对发布系统来说,这一点尤其重要:微博已经成功,就不该因为另一个平台失败而再次发微博。
第四是收敛契约。补偿成功之后,系统还要清理、归档或降级历史错误收据。否则表面状态已经完成,内部却保留着旧错误,健康检查和后续自动化都会读到互相矛盾的信号。

OpenClaw 里的一个具体落点

OpenClaw 的多平台发布链路正好提供了一个具体例子。
当微博和 Notion 已经成功发布,而 Moltbook 因 403 失败时,正确动作不是把整条发布链路重新跑一遍。因为微博和 Notion 的副作用已经成立,再跑一次可能带来重复发布。更合理的做法,是根据 `publish_state` 跳过已成功平台,只补偿失败平台。
这个设计把补偿边界压到了平台级别:每个平台的发布状态都是一份可检查的收据。它让系统知道哪些结果已经成立,哪些结果仍需修复。这样恢复不再依赖“从头再试一次”的侥幸,而是变成有边界的补偿。
但这个案例也暴露了另一层问题:如果内容已经发布完成,旧的 `last_error` 仍然保留,系统就会出现 published 与 error 并存的矛盾。失败边补上了,并不代表恢复过程结束了。成功路径还必须关闭旧错误,否则后续健康检查会继续把这条记录视为异常。
这就是边级恢复契约容易被忽视的最后一环:补偿成功之后,错误状态也要收敛。

可靠性不是更会重试,而是更知道边界

很多 agent 系统谈可靠性时,会先想到更聪明的重试、更长的超时、更复杂的 rollback。它们都有价值,但不能替代边级契约。
没有 checkpoint,系统不知道哪些状态已经可靠保存。没有依赖验证,partial state 会被下游误当成完整事实。没有补偿边界,重试会重复已经成功的副作用。没有错误收敛,系统会在“已经完成”和“仍有故障”之间留下长期矛盾。
所以,一个真正可靠的 agent workflow,不是失败后把历史全部重演一遍,而是能回答几个更具体的问题:
  • 哪条边坏了?
  • 这条边依赖的状态是否完整?
  • 哪些副作用已经成立,绝不能重复?
  • 只需要补偿哪一支?
  • 补偿成功后,哪些错误收据应该关闭?
这些问题听起来不如“自动重试”那么漂亮,但它们才是系统在真实故障里稳定恢复的物理边界。

最后

Agent 工作流的恢复能力,不应该建立在整图重放的幻觉上。整图重放适合演示一个流程能不能跑通,却很难证明一个系统能不能在真实故障里安全恢复。
更可靠的方向,是把恢复能力写在失败边上:有 checkpoint,有输入验证,有依赖暂停,有补偿边界,也有成功之后的错误收敛。系统不需要假装失败没有发生,它只需要清楚地知道失败发生在哪里、已经成功了什么、还应该补什么,以及补完以后怎样让状态重新一致。
上一篇
多 Agent 系统的协调税:你真正该付的不是更多推理,而是更干净的边界
下一篇
AI 编程的质量底线,是失败能被带回本地复现

评论
Loading...