AI Agent 容错机制对比:OpenClaw、Claude Code 与 Hermes
系列:AI Agent 架构设计(十四):异常处理与容错机制
目标:当 Agent 出现错误时如何应对——熔断、重试、降级,三种框架分别体现出的容错思路
适合:对 Agent 底层架构有兴趣,想深入理解“为何这样设计”的读者
预计阅读:15 分钟
Agent 遇到的错误与传统软件的错误并不相同
普通软件一旦报错,通常会看到错误提示、异常堆栈、HTTP 500。失败是显性的,出错位置明确,修复路径也比较清楚。
但 Agent 的错误则完全是另一回事。
当工具调用超时时,模型可能会选择重试,也可能改走别的路径,甚至直接静默继续——这取决于当前上下文中的信息,而不是固定不变的代码分支。遇到 API 限流时,下一步该等待还是切换模型?连续失败多少次才应该通知用户?用户不在线时又该如何处理?
这些问题并不存在统一标准答案,但不同架构会给出各自默认的处理方式。
三个框架在容错设计上的区别,主要集中在以下三个核心问题:
由谁发现错误——是依赖程序层面的监控,还是交给模型自行判断?
错误出现后如何恢复——重试、降级,还是提示用户等待?
如果恢复仍然失败怎么办——熔断停止,还是无限循环消耗资源?
OpenClaw 的错误处理在 GitHub Issue 中能看到一个非常典型的真实案例:
当工具调用被卡住(例如 RPC 死锁、Provider 超时、响应格式异常),Agent 会静默停在那里长达 600 秒——这是agents/timeout.js中
DEFAULT_AGENT_TIMEOUT_SECONDS的默认配置值。
在这 600 秒的挂起期间:Telegram / Feishu消息排队却不处理,Web UI 也没有任何活动,用户几乎完全不知道系统发生了什么。
2026 年 2 月,有用户提交了一个具体案例(Issue#8288):某一天内 Agent 三次卡死,累计宕机时间超过 8 小时。
唯一的恢复方式是:删除 sessions.json,然后重启 Gateway——这样会直接清空全部会话历史,Agent 失去完整对话记忆。
这暴露出 OpenClaw 在错误处理上的根本问题:没有内建看门狗机制,没有自动检测挂起状态,也没有在保留会话历史前提下优雅终止的方案。
当工具调用失败时,错误信息会以tool_result的形式注入上下文,再由模型决定后续怎么做——重试、换一种方案,或者向用户汇报。
这种方式在受信任环境下表现不错,但当多个失败叠加时,就容易引发连锁问题。同一个案例中:
主模型失败,Fallback 模型同样失败,Agent 就没有可靠路径完成当前轮次。由于缺少内置熔断机制,模型在这种情况下的行为变得不可预测。
Claude Code 的核心错误处理位于QueryEngine.ts——这是一个统一负责所有 LLM 调用、重试以及流式错误的中心模块。
把所有与模型 API 接触的逻辑收拢到一个模块中,是这套设计里最关键的架构决策。重试逻辑、速率限制处理、流式错误捕获,都在这里统一完成——不同工具无需分别实现重试,因此错误处理行为也能保持一致。
上下文压缩(Compaction)是 Claude Code 处理长 Session 的办法,但 Compaction 自身也有可能失败。
根据真实生产数据,Anthropic 内部借助 BigQuery 发现:2026 年 2 月,共有 1,279 个会话出现超过 50 次连续 Compaction 失败,单个会话最多重试了 3,272 次,每天白白浪费大约 25 万次 API 调用。
最终修复方案是在源码中增加了一行逻辑:
如果连续失败超过 3 次,就停止重试,并强制上报给用户。
这个阈值并非凭感觉设定,而是根据真实生产数据推导出来的。相比无限重试,3 次后熔断显著节省了资源,也避免 Agent 在失败状态中无休止循环。
Claude Code 对上下文窗口的管理采用了三级阈值设计:
这一设计的价值在于:系统在真正失败之前有三次介入机会,而不是等到彻底撞墙后才开始处理。
有效上下文窗口的计算方式同样值得注意——总窗口会减去为 Compaction 摘要预留的 20,000 Token,从而确保任何时候都有足够空间生成压缩摘要:
这部分预留空间不是浪费,而是为了确保容错机制本身能够正常运行的基础设施。
Hermes 最关键的容错机制是迭代预算——每个会话最多只能进行 90 次工具调用:
这一点正好解决了 OpenClaw 面临的核心问题:当 Agent 陷入循环(不断重复尝试失败的方法)时,迭代预算会强制结束流程,而不会无限制消耗资源。
两次预警的设计也很值得关注——不是等碰到上限才突然停止,而是提前让 Agent 感知“可用资源已经不多”,从而给它机会重新评估策略,在预算耗尽前自行收尾。
Hermes 默认带有 10 分钟超时机制,但这属于固定墙钟超时——从任务启动那一刻开始计时。
已知问题是:合法的长耗时任务(例如等待慢 API 返回的数据分析任务)可能会被误判并终止。社区讨论中的改进方向是活跃度超时——监测最近一次工具调用完成的时间,只有“静默”持续超过阈值才触发,这样才能区分“仍在工作”和“已经卡死”两种状态。这个改进截至 2026 年 4 月仍未落地。
Hermes 的ContextCompressor采用结构化摘要模板:
每次压缩并不是重新从零生成摘要,而是在上一次摘要的基础上做更新——这样既能保证摘要连续性,也能降低单次压缩的 Token 开销。
与此同时,Hermes 的系统提示会在 Session 开始时以冻结快照形式注入,整个 Session 期间都不会改动——这最大化了 Prompt Cache 的命中率,也意味着系统提示层不会因为中途变化而带来缓存失效成本。
取舍一:出现问题后,是让 AI 自己想办法,还是提前给它定规则
OpenClaw 更倾向于让模型自行决定——失败以后,是重试、换方法还是告知用户,都由它自己判断。这样做很灵活,但你并不清楚它到底是怎么处理的,有时它会悄悄绕开问题,最后告诉你“已经完成”,可原始问题其实并未真正解决。
Claude Code 和 Hermes 则制定了明确的硬规则:连续失败超过 3 次就必须停下并通知用户,工具调用超过 90 次则强制结束。灵活性少了一些,但一旦出问题,排查方向会清楚很多。
取舍二:发生错误时,用户是否能及时知道
OpenClaw 更偏向于让 Agent 自己内部消化——绕路处理,继续往前执行,最后再汇报“完成”。你未必能察觉中途出过问题,但最终结果也可能并不是你真正想要的。
Claude Code 会对不可恢复的错误进行强制上报,不把“要不要告诉用户”这件事交给模型自行决定。
Hermes 介入得更早——当达到 70% 的调用次数上限时就会主动提醒,而不是非要等到出错以后才反馈。
决定由谁知晓错误,本质上也是在决定由谁承担决策责任。
取舍三:错误发生后,要从哪里重新开始
OpenClaw 重启时需要删除会话记录,Agent 再次启动后什么都不记得——之前做过什么、说过什么,都会丢失。
Claude Code 会把任务清单保存在硬盘中,重启之后依然存在,系统知道已经做到哪一步,因此可以继续执行。
Hermes 则通过数据库保存全部历史记录,重启后数据仍在,可以从上次中断的位置继续推进。
错误造成的代价,最终取决于恢复之后能从哪个起点重新出发。