大多数 AI agent 是一次一回合的。你打字,它回应,它等下一句。循环是你在跑,agent 只是被调用的那个函数。
Hermes Agent 默认就是这一种。但它还带了另一种叫 /goal 的模式——这次反过来,循环交给 agent 自己跑。你设一个目标加几条验收标准,agent 就一轮一轮地提案、执行、自评、重试,跑到另一个 judge 模型确认条件达成为止。v0.14.0(2026 年 5 月 16 日)又补了一个 /subgoal,让你能在跑到一半的循环里再叠新的判据上去,不用重启(#25449)。
这篇文章把这件事拆开看:它底下到底在做什么,什么时候它是对的工具,什么时候它会反过来咬你。
默认模式(先拿来做对照)
Hermes 里每一段聊天,节奏都是一条用户消息对一回合。agent 把你的消息读完,需要的话调几个工具,把回应吐回来。任务没做完的话,得你来戳它:"接着做"、"再试一次"、"那 X 怎么办"。外层循环是你在跑。
干探索性的活儿这套挺好——"解释一下这段代码"、"起草一份备忘"、"帮我找个 bug"。你就是想让 agent 每走一步停一下,方便你随时拨方向。
但碰上那种成败说得清、路径又得反复磨的活儿,这套就不灵了。"把这个模块重构到 pytest 通过"——你一回合一回合手动推,是个三十回合的活。换成 /goal,一条命令就够了。
/goal 到底做了什么
/goal Make all tests in tests/api/ pass. Don't change the test assertions. Done when pytest exits 0.
你把这条丢过去之后,三件事会发生:
- 1.目标文本变成 worker 的 target prompt。 接下来的每一轮,worker 模型会拿到一条系统消息,里面带着目标和当前的最佳尝试。
- 2.每跑完一轮 worker,会单独再调一次"judge"模型。 judge 看到的是目标、当前状态、worker 给的这版完成稿。它要么回 "done"(循环退出),要么回 "继续,还差这些"。
- 3.判定是 judge 说的算。 它不点头循环就不停——直到 judge 同意为止,或者你用
/stop自己叫停,或者打到配置好的迭代上限。
judge 是整套东西的关键。它和 worker 不是同一次 LLM 调用,它也看不到 worker 的思维链——它只看目标和当前状态。这层分离正是 /goal 能成立的原因:一个已经被自己说服答案是对的 worker,是个糟糕的法官。一次没有任何上下文、白纸一张被叫起来的 LLM,做这件事好太多了。
这套模式在 Hermes 代码库内部被叫作 "Ralph loop",名字来自那一段经典伪代码——while not done: do(work); ralph = judge(work)。v0.14.0 加的 /subgoal 扩展,是让用户能把新的判据塞进一个还在跑的循环里。
/subgoal —— 跑到一半再追加判据
你起了一个 /goal 来重构一个模块。跑到第三轮你忽然想到——这次重构最好顺便把每个函数的圈复杂度压到 10 以下。你又不想停掉重来。
/subgoal Each function must have cyclomatic complexity <= 10.
judge 下一次跑的时候,会把这条新约束一起算进来。当前最佳尝试如果没过这一条,循环继续。如果过了,循环退出。
这种功能在 release notes 里只是一行 bullet——"用户可以往进行中的 /goal 追加判据"——但你一旦真用过这个循环,会发现它是一根承重柱。真实的目标是你看着 agent 干活时一边看一边精细化出来的。没有 /subgoal,你要精细化只能 /stop + 重新写 + 再 /goal 一次——跑到一半的状态全丢了。
几个实际例子
重构到测试通过
/goal Refactor src/api/users.py so the User class follows the new naming convention in src/conventions.md. Don't break any existing tests. Done when:
1. pytest exits 0
2. The User class matches the convention rules in conventions.md
worker 一轮一轮试重构,judge 检查这两条。两条都绿了,循环退出。
反复调一个 UI
/goal Make the button on /pricing more prominent. Done when:
1. The button is the largest interactive element above the fold on desktop
2. It uses the primary brand color (#FF5A50)
3. Existing Lighthouse accessibility score doesn't drop
worker 改 CSS,judge 用 browser 工具截图来核对。可以跑很多轮迭代——你不用一直盯着。
揪一个 bug
/goal Find the cause of the intermittent test failure in tests/auth/test_session.py::test_logout_clears_cookie. Done when you produce a minimal failing repro and a one-paragraph explanation.
这里 judge 要核对的是交付物的两部分都得在——最小复现和一段解释——而不是只要凑齐一边就行。如果第一稿的解释太虚,/subgoal 让你能补一条比如"解释里必须引用到对应的请求/响应链路"。
什么时候不该用它
/goal 在下面这些任务里是错的工具:
- •成败判据本身是糊的。 "把这个写得更优雅一点"——judge 没法稳定打分,循环要么来回震荡,要么直接盖章放行。这种用回逐回合。
- •你想边看边介入。 每一轮都得跑完 worker 再起 judge,过程中没有逐步可见度。要中途审,用回逐回合,或者上
/handoff。 - •你更在乎成本,不是速度。 一轮 = 一次 worker 调用 + 一次 judge 调用。十轮的目标就是二十次 LLM 调用。重构活儿值这个钱,"帮我想个变量名"就是浪费。
- •你根本没认真想成功标准。 判据糊弄 → 循环也糊弄。
/goal奖励的是写得具体;判据有漏洞,agent 会从漏洞钻过去。
/goal 怎么和 /handoff 一起用
v0.14.0 同时也出了 /handoff——它能在不丢上下文的前提下,把一个正在跑的会话从一个模型搬到另一个(#23395)。这两个能拼起来用:一个跑着的 /goal 撞到快模型搞不定的地方,你可以把它热迁到一个更擅长深推理的模型上。judge 还是按同一套判据打分,只不过 worker 换成更靠谱的那个了。
/sessions(#20805)也类似——你可以把一个 /goal 临时打断,去别的会话里转一圈,回头再续上。循环状态有 checkpoint。
它在 agent 这一整套谱系里的位置
自治程度从低到高,agent 干活有三种形状:
- 1.逐回合 —— 你驾驶,agent 应答。对话式。
- 2.
/goal—— 你定判据,agent 自己跑到判据达成。有边界的自治。 - 3.Cron 调度 —— agent 按点无人值守地跑,结果投递到聊天平台。时间维度上没边界的自治。
/goal 占在中间这一格。它适合那一类原来你要么得一直盯着、要么得自己写脚本的活儿。v0.14.0 那个 /subgoal 让循环跑着也能拨方向——就这一下,它从"挺有意思的功能"变成了日常工具。