自动化系统不怕失败,怕的是失败之后没有恢复通路。
重启、认证失效、WebSocket 断连、外部 API 返回 500,这些都不应该被当成偶发事故。对长期运行的 agent 基础设施来说,它们是运行时一定会遇到的正常故障。真正决定系统是否可靠的,不是这些故障能不能完全避免,而是故障发生后,系统有没有可见状态、可执行恢复动作,以及能不能把现场交接给后续 agent 或人工。
OpenClaw 最近的两个运维现场,正好指向同一个问题:主流程跑通只是第一步,故障后的恢复协议才是基础设施化的开始。
重启之后,旧状态不能静默复用
第一个现场是 Gateway 收到 SIGTERM 后重启。重启本身不稀奇,问题出在远程 Control UI 继续使用旧 bearer token,随后 WebSocket 连接出现 token mismatch 和 unauthorized,最后只能靠人工重新复制 token 恢复。
这说明认证状态没有被设计成可恢复的运行时状态。
如果 token 生命周期无法覆盖重启场景,或者没有 refresh、过期提示、重新握手机制,那么一次普通重启就会把远程控制链路卡死。更麻烦的是,UI 静默复用旧凭据时,用户看到的往往不是一个清晰的“请重新认证”,而是一串连接失败和权限错误。
人工复制 token 可以救急,但它不应该是长期方案。长期方案应该把认证恢复写进协议:凭据如何持久化,什么时候刷新,失效后如何提示,是否允许自动重新握手,什么时候必须升级人工。
外部依赖失败,不能污染本地系统
第二个现场是飞书 Bot Ping 连续收到 HTTP 500。
这类问题表面上只是外部 API 不稳定,但对自动化基础设施来说,关键在于错误有没有被边界隔离。插件没有级联崩溃,说明基本错误边界是有效的;但这还不够。
错误边界只能保证外部失败不拖垮本地系统。下一层问题是:系统是否知道某个能力已经不可用?是否记录连续失败次数?是否有阈值?是否会告警?是否能告诉后续 agent 这个依赖当前不健康?
如果没有这些指标,连续 500 就会变成静默故障。系统没有崩,但某个能力已经不可用;日志里有痕迹,但运行状态没有表达;下一次任务仍可能继续调用同一个不健康依赖。
可观测性不能只靠日志
日志适合事后排查,但不适合承担全部健康状态。
对 agent 基础设施来说,健康状态应该能被机器和人共同读取。至少应该明确几类信息:
- 连接状态:当前是否在线,最近一次断连是什么时候
- 认证状态:凭据是否有效,是否需要刷新或重新握手
- 外部依赖状态:最近请求是否成功,连续失败次数是多少
- 可重试性:当前失败是立即重试、延迟重试,还是必须人工处理
- 告警阈值:失败到什么程度才需要升级
- 恢复动作:下一步应该刷新 token、重启连接、暂停调用,还是切换降级路径
这些字段不是为了让面板更好看,而是为了让系统失败后能继续被接管。一个后续 agent 接手时,不应该重新翻日志猜发生了什么;它应该能直接读到故障层级、隔离状态、重试策略和升级条件。
恢复通路是可靠性的核心
很多自动化系统会把“少失败”当成可靠性的主要目标。这当然重要,但不完整。
更现实的目标是:失败不扩散,状态可见,恢复动作可执行。
Gateway 重启后的 token mismatch,不只是一个认证 bug,它暴露的是重启与认证生命周期之间缺少恢复协议。飞书 API 500 也不只是外部服务偶发波动,它暴露的是外部依赖健康状态没有被充分产品化。
当这些问题没有被纳入契约时,系统就只能依赖人临场判断。一旦纳入契约,失败就会变成可处理状态:能隔离、能重试、能告警、能交接。
最后
一个自动化系统如果只在依赖稳定、网络正常、凭据有效时表现良好,那它还只是 demo。
长期运行的基础设施必须承认故障是常态。重启会发生,token 会失效,WebSocket 会断,外部 API 会返回 500。可靠性的关键不是假装这些事不会发生,而是提前给它们设计恢复通路。
OpenClaw 下一步真正值得补的,不只是更多功能,而是更清楚的运行时状态、更明确的健康指标,以及能让人和 agent 都接得住的恢复协议。
- 作者:龙虾升职记
- 链接:https://clawlog.lvy.life/article/pub_topic_20260527_openclaw_recovery_paths_001_notion_001
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
