最近在把 Hermes Agent 当作长期工作助手使用时,我遇到过一种很有代表性的故障:某个工具连续返回相同错误,系统为了防止死循环触发保护,然后整个任务停在那里,必须由人再发一句“继续”。
表面上看,这是护栏在正常工作;但从任务体验看,它只阻止了重复调用,没有帮助 Agent 改走另一条路。更关键的是,错误信息虽然已经生成,模型却可能还没看到,执行循环就提前结束了。Hermes Agent 上游的公开 Issue #64322 描述的正是这个问题。[1]
证据说明:本文区分官方文档、上游公开 Issue/PR 与个人实践。公开 Issue 是可核验的问题线索,不代表每个 Hermes 版本都必然存在相同行为;软件状态请以阅读时的官方资料为准。
护栏应该阻止错误路径,而不是终止目标
Agent 的工具循环保护非常必要。没有它,模型可能把同一个失败命令调用几十次,浪费时间、额度,甚至放大副作用。
但“停止重复调用”和“放弃整个任务”并不是一回事。更合理的处理应该是:
- 识别连续出现的同类失败;
- 禁止继续使用当前失败路径;
- 把结构化错误反馈给模型;
- 允许模型换一种工具、参数或实现方式;
- 如果换路后仍触发同类保护,再进行受控停止。
上游 PR #64363 提出的思路也是这样:首次命中 hard stop(硬停止)后,不立即结束整个工具循环,而是让模型得到一次“回弹”机会;同一轮第二次再次命中,才真正停止。[2]
第一次重复失败
↓
封锁当前路径
↓
把原因交给模型
↓
允许换路一次
↓
再次失败才受控停止
为什么浏览器自动化更容易误判
命令行工具通常有清楚的退出码和错误文本,而浏览器操作可能连续点击同一位置、等待页面状态变化,或者多次读取相似 DOM。参数看起来一样,不代表没有进展。
Hermes Agent 的另一个公开 Issue #64804 记录了交互式浏览器会话中的无进展误判,以及停止时部分成果可能没有被保留的问题。[3]
这说明“调用参数重复”只能作为风险信号,不能单独证明任务陷入死循环。更可靠的判断还应结合:
- 页面 URL、DOM 或可访问性树是否变化;
- 是否出现新的下载、对话框或网络响应;
- 工具返回的是相同错误,还是同一操作的不同阶段;
- 已经取得的结果能否先保存,再决定是否停止。
我最后采用的原则
同一路径可以被阻止,但 Agent 应继续为原目标负责。
如果失败是可恢复的,Agent 应自动换路,而不是把“请用户手动继续”当成恢复机制;如果操作涉及付款、删除、未知副作用或安全边界,则必须真正停止,不能为了连续性绕开确认。
这两类情况不能混为一谈:
| 情况 | 合理动作 |
|---|---|
| 相同查询、相同参数、相同只读错误 | 阻止重复路径,自动改用其他方法 |
| 浏览器状态尚在变化 | 先读取新状态,不机械判定无进展 |
| 已产生部分成果 | 先保存证据和中间结果 |
| 未知副作用或高风险操作 | 停止并向用户说明对象、后果与恢复方式 |
这类 Bug 给我的启发
Agent 可靠性不只是“有没有保护机制”,还取决于保护机制阻止的对象是否正确。最差的护栏会让系统看起来很安全,却把所有恢复成本转嫁给用户;好的护栏则会缩小失败范围,让 Agent 在边界内继续完成目标。
因此,未来评价一个 Agent 的稳定性,我会重点看三件事:它能否识别重复失败、能否自动换路、能否在最终停止前保留已有成果。单纯增加重试次数,既不是可靠性,也不是智能。
参考资料
- Hermes Agent Issue #64322:Tool loop guardrail hard-stop silently halts task
- Hermes Agent PR #64363:give the model one rebound before halting
- Hermes Agent Issue #64804:browser no-progress false positives