跳到主要内容

持久化目标 (/goal)

/goal 为 Hermes 提供一个跨轮次存续的长期目标。每轮对话结束后,一个轻量级的评判模型(judge model)会检查助手最近的回复是否已满足该目标。如果未满足,Hermes 会自动将延续提示(continuation prompt)反馈回同一会话并继续工作——直到目标达成、你暂停或清除它,或者轮次预算耗尽。

这是我们对 Ralph loop 的实现,直接灵感来源于 Eric Traut (OpenAI) 的 Codex CLI 0.128.0 的 /goal。其核心理念——在轮次间保持目标活跃且直到达成前不停止——归功于他们。此处的实现是独立的,并适配了 Hermes 的架构。

何时使用

对于希望 Hermes 自行迭代而无需你在每轮重新提示的任务,请使用 /goal

  • “修复 src/ 中的所有 lint 错误并验证 ruff check 通过”
  • “从仓库 Y 移植功能 X,包括测试,并确保 CI 变绿”
  • “调查为什么会话 ID 在运行中压缩时有时会漂移,并撰写报告”
  • “构建一个小型 CLI 工具,根据 EXIF 日期重命名文件,然后针对 photos/ 文件夹进行测试”

代理执行一轮即停止的任务不需要 /goal。那些*否则你需要说三次“继续”*的任务才是它的用武之地。

快速开始

/goal Fix every failing test in tests/hermes_cli/ and make sure scripts/run_tests.sh passes for that directory

你将看到:

  1. 目标已接受⊙ Goal set (20-turn budget): <your goal>
  2. 第 1 轮运行 — Hermes 开始工作,就像你将目标作为普通消息发送一样。
  3. 评判运行 — 轮次结束后,评判模型决定 done(完成)或 continue(继续)。
  4. 必要时触发循环 — 如果为 continue,你将看到 ↻ Continuing toward goal (1/20): <judge's reason>,Hermes 会自动采取下一步。
  5. 终止 — 最终你会看到 ✓ Goal achieved: <reason>⏸ Goal paused — N/20 turns used

命令

命令作用
/goal <text>设置(或替换)长期目标。立即启动第一轮,因此你无需发送单独的消息。
/goal/goal status显示当前目标、其状态以及已使用的轮次。
/goal pause停止自动延续循环,但不清除目标。
/goal resume恢复循环(将轮次计数器重置为零)。
/goal clear完全丢弃目标。

在 CLI 和所有网关平台(Telegram、Discord、Slack、Matrix、Signal、WhatsApp、SMS、iMessage、Webhook、API 服务器和 Web 仪表板)上工作方式相同。

在目标进行中添加条件:/subgoal

当目标处于活动状态时,你可以使用 /subgoal <text> 追加额外的验收条件,而不会重置循环。每次调用都会向目标的子目标列表添加一个编号项;代理在下一轮看到的延续提示包括原始目标以及一个“用户在循环中途添加的附加条件”块,并且评判提示会被重写,以便裁决必须考虑每个子目标——只有当原始目标每个子目标都满足时,目标才会被标记为完成。

命令作用
/subgoal <text>向活动目标追加新条件。需要活动的 /goal
/subgoal(无参数)显示当前编号的子目标列表。
/subgoal remove <N>移除第 N 个子目标(基于 1 的索引)。
/subgoal clear丢弃所有子目标,但保持原始目标完整。

子目标与目标一起持久存储在 SessionDB.state_meta 中,因此它们在 /resume 后依然保留。设置新的 /goal <text> 会替换目标并清除子目标列表;/goal clear 也会执行相同的操作。

当你启动一个循环(“修复失败的测试”)并在中途注意到你还希望它“为你刚刚修补的错误添加回归测试”时,请使用此功能——/subgoal add a regression test 可以在不中断运行中的循环的情况下收紧成功标准。

行为细节

评判模型 (The judge)

每轮对话后,Hermes 会调用一个辅助模型,提供:

  • 长期目标文本
  • 代理最近的最终回复(最后约 4 KB 的文本)
  • 一个系统提示,指示评判模型回复严格的 JSON:{"done": <bool>, "reason": "<one-sentence rationale>"}

评判模型故意保守:仅当回复明确确认目标已完成、最终交付物清晰产生,或者目标无法实现/受阻(视为 DONE 并附带受阻原因,以免在不可能完成的任务上浪费预算)时,它才会将目标标记为 done

故障开放语义 (Fail-open semantics)

如果评判模型出错(网络波动、响应格式错误、辅助客户端不可用),Hermes 会将裁决视为 continue——损坏的评判模型永远不会阻碍进度。轮次预算是真正的后盾。

轮次预算

默认值为 20 次延续轮次(config.yaml 中的 goals.max_turns)。当达到预算时,Hermes 会自动暂停并告诉你确切的操作方法:

⏸ Goal paused — 20/20 turns used. Use /goal resume to keep going, or /goal clear to stop.

/goal resume 将计数器重置为零,因此你可以以可控的块状方式继续。

用户消息始终优先

在目标(goal)处于活动状态时,你发送的任何真实消息都优先于延续循环。在 CLI 中,你的消息会进入 _pending_input,排在队列中的延续之前;在网关中,它同样通过适配器 FIFO 处理。在你的回合结束后,裁判(judge)会再次运行——因此,如果你的消息恰好完成了目标,裁判将会捕获这一状态并停止。

运行中的安全性(网关)

当代理已经在运行时,/goal status/goal pause/goal clear 都是安全可执行的——它们仅触及控制平面状态,不会中断当前回合。在运行中途设置目标(/goal <new text>)会被拒绝,并提示你先执行 /stop,以防止旧的延续与新的目标发生竞争。

持久化

目标状态存储在 SessionDB.state_meta 中,键为 goal:<session_id>。这意味着 /resume 可以从你离开的地方无缝继续——设定一个目标,合上笔记本电脑,第二天回来执行 /resume,目标状态仍将保持原样(活动、暂停或已完成)。

提示缓存

延续提示是一条附加到历史记录中的普通用户角色消息。它不会修改系统提示、交换工具集,或以任何使 Hermes 提示缓存失效的方式影响对话。运行一个 20 轮的目标在缓存成本上与 20 轮正常对话相同。

配置

添加到 ~/.hermes/config.yaml

goals:
# Max continuation turns before Hermes auto-pauses and asks you to
# /goal resume. Default 20. Lower this if you want tighter loops;
# raise it for long-running refactors.
max_turns: 20

选择裁判模型

裁判使用 goal_judge 辅助任务。默认情况下,它会解析为你的主模型(参见 辅助模型)。如果你希望将裁判路由到一个廉价且快速的模型以降低成本,可以添加以下覆盖配置:

auxiliary:
goal_judge:
provider: openrouter
model: google/gemini-3-flash-preview

裁判调用产生的输出很小(约 200 个输出 token),且每轮运行一次,因此使用廉价快速的模型通常是正确的选择。

示例演练

You: /goal Create four files /tmp/note_{1..4}.txt, one per turn, each containing its number as text

⊙ Goal set (20-turn budget): Create four files /tmp/note_{1..4}.txt, one per turn, each containing its number as text

Hermes: Creating /tmp/note_1.txt now.
💻 echo "1" > /tmp/note_1.txt (0.1s)
I've created /tmp/note_1.txt with the content "1". I'll continue with the remaining files on the next turn as you specified.

↻ Continuing toward goal (1/20): Only 1 of 4 files has been created; 3 files remain.

Hermes: [Continuing toward your standing goal]
💻 echo "2" > /tmp/note_2.txt (0.1s)
Created /tmp/note_2.txt. Two more to go.

↻ Continuing toward goal (2/20): 2 of 4 files created; 2 remain.

Hermes: [Continuing toward your standing goal]
💻 echo "3" > /tmp/note_3.txt (0.1s)
Created /tmp/note_3.txt.

↻ Continuing toward goal (3/20): 3 of 4 files created; 1 remains.

Hermes: [Continuing toward your standing goal]
💻 echo "4" > /tmp/note_4.txt (0.1s)
All four files have been created: /tmp/note_1.txt through /tmp/note_4.txt, each containing its number.

✓ Goal achieved: All four files were created with the specified content, completing the goal.

You: _

四轮交互,一次 /goal 调用,零次来自你的“继续”提示。

当裁判出错时

没有裁判是完美的。需要关注两种失败模式:

假阴性——目标实际上已完成,但裁判说继续。 轮次预算会捕获这种情况。你会看到 ⏸ Goal paused,此时可以执行 /goal clear 或直接发送新消息。

假阳性——工作尚未完成,但裁判说已完成。 你会看到 ✓ Goal achieved,但你清楚事实并非如此。发送后续消息以继续,或者更精确地重新设定目标:/goal <more specific text>。裁判的系统提示被故意设计得保守,以使假阳性的发生率低于假阴性。

如果你觉得裁判的裁决缺乏说服力,↻ Continuing toward goal✓ Goal achieved 行中的原因文本会准确告诉你裁判看到了什么。这通常足以诊断是目标文本存在歧义,还是模型的响应存在歧义。

归属

/goal 是 Hermes 对 Ralph loop 模式的实现。其面向用户的设计——在多轮对话中保持目标活跃,直到达成目标才停止,并提供创建/暂停/恢复/清除控制——由 OpenAI Codex 团队的 Eric Traut 在 Codex CLI 0.128.0 中推广并发布。我们的实现是独立的(中央 CommandDef 注册表、SessionDB.state_meta 持久化、辅助客户端裁判、网关侧的适配器 FIFO 延续),但理念源于他们。特此致谢。