Goal 模式深度解析:Ralph Loop、Claude Code、Hermes 与 SDD Sidecar
调研截至:2026-05-13。本文引用 OpenAI Codex、Claude Code、Hermes、Anthropic Ralph Loop、OpenCode / Oh My OpenCode、Oh My ClaudeCode 等公开资料,并对一个内部 all-in-one SDD skill 做了脱敏分析。脱敏约定:不写本地路径、组织名称、平台名称、真实 adapter 名称和任何业务字段;下文用
sdd-all指代这类内部 SDD overlay。
Goal 模式不应再被理解为 Codex 的单点能力。更准确的判断是:AI 编程工具正在把 Ralph Loop 这类外部循环,收敛成一类更正式的“持久目标协议”。
这类协议的最小内核很朴素:循环继续执行,加上一个完成信号。但工程难点从来不在 while true 本身,而在完成信号由谁判断、能看到什么证据、是否允许误判、状态放在哪里、预算和用户打断怎么处理、以及长任务恢复后会不会忘掉原始规格。

核心判断
从 Ralph Loop 到 Codex /goal、Claude Code /goal、Hermes /goal,再到 SDD sidecar,真正演化的是三件事:
| 层次 | 要解决的问题 | 典型形态 |
|---|---|---|
| 继续执行 | Agent 不要每个 turn 结束就停 | Stop hook、idle continuation、runtime continuation |
| 完成判定 | Agent 什么时候真的该停 | completion promise、judge model、model tool、gate script |
| 证据与恢复 | 下一轮如何知道前面做过什么、凭什么算通过 | transcript、thread state、SessionDB、sidecar evidence、task ledger |
因此,Ralph 循环的原型确实可以压缩成“loop + 完成信号”。可一旦进入真实工程,完成信号就不能只是一句 DONE。它至少要绑定可验证证据;如果跨 session、跨部署平台、跨人工签收,还需要一个不会随上下文压缩丢失的外部状态层。
sdd-all 的 sidecar 正是在这个位置出现的。它不是第二套需求文档,也不是业务记忆库;它更像一个轻量 harness:记录当前循环、测试证据、用户签字和检查脚本可消费的完成态材料。它的存在价值取决于流程复杂度。简单改动不需要它,带部署验收、文档漂移、人工签收和归档沉淀的 SDD 变更需要它。
最小内核:Loop + Completion Predicate
Ralph Loop 的流行,是因为它抓住了 Agent 编程最常见的失败模式:模型并非不会做,而是太容易在还没完成时停下,或者在上下文里反复修同一个局部问题。
Anthropic 官方 Ralph Loop 插件的机制很直接:Claude Code 结束一个 session 时,Stop hook 拦截退出,把原 prompt 再喂回去,同时保留文件修改和 Git 历史;循环直到模型输出 completion promise,或达到 max iterations。OpenCode 生态里的 /ralph-loop 也走类似路线,用 <promise>DONE</promise> 作为完成信号,如果 Agent idle 但没有看到 DONE,就注入 continuation prompt 继续工作。
中文社区里那篇新智元转载文章把这个模式讲得很传播化:给任务清单,拿一个小任务,写代码,测试,失败就修,成功就保存进度,再拿下一个,直到满足条件退出。这个表述虽然带着强营销味,但技术上抓住了重点:任务必须拆到“Agent 一次能做完、也能一次判断对错”的颗粒度。
问题在于,DONE 不是证据。一个 completion promise 只能解决“循环何时停止”的接口问题,不能解决“停止是否可信”的判断问题。真正决定生产可用性的,是 completion predicate 的来源。
完成信号可以分四档:
| 完成信号 | 判断者 | 优点 | 风险 |
|---|---|---|---|
| 字符串承诺 | 主 Agent 自己 | 极轻量,容易移植 | 最容易误报完成 |
| 独立 judge model | 小模型 / 快模型 | 与执行模型分离,成本低 | 只能看 transcript 时,证据不足 |
| Agent verifier | 独立子 Agent | 可读文件、跑测试、检查 diff | 成本高,可能变成第二个复杂 Agent |
| 脚本 + evidence | 确定性检查脚本 | 最稳定,可审计,可恢复 | 需要先设计证据 schema 和落盘边界 |
这说明“完成信号是否需要精细中间记忆”要分场景。短任务不需要,completion promise 或 judge reason 足够。长任务也不一定需要一个复杂记忆模块,但必须有最小可恢复状态:当前目标、任务清单、最近验证结果、证据文件位置、未决阻塞、用户签收。状态越靠近可验证事实,越适合作为完成信号;状态越像自然语言备忘录,越容易演变成影子规范。
Goal 模式已经不是 Codex 独有
最早把这篇文章写成“Codex Goal 模式”并不完全错,因为 Codex 的 /goal 确实是一个重要节点。错在容易让读者以为 goal mode 是 Codex 的专属发明。到 2026-05-13,公开资料已经能看到至少三条正式化路径:Codex、Claude Code、Hermes。
Codex:把目标放进 runtime
OpenAI 官方文档把 Codex /goal 定义为 long-running work 的 durable objective:任务需要跨 turn 持续推进,并且有明确的 verifiable stopping condition 时使用。Slash command 文档也写明它仍是实验特性,需要启用 features.goals,命令包括 /goal <objective>、/goal、/goal pause、/goal resume 和 /goal clear。
从 OpenAI/Codex 的几组 PR 看,Codex 的设计更偏 runtime integration,而不只是一个 hook:
| 层 | 公开实现线索 | 作用 |
|---|---|---|
| 持久状态 | thread_goals、goal status、budget accounting |
目标跟 thread 走 |
| app-server API | get / set / clear goal、通知、resume snapshot | 让客户端恢复目标状态 |
| 模型工具 | get_goal / create_goal / update_goal |
让模型读目标、在受限边界内标记完成 |
| core runtime | idle continuation、interrupt、resume、token budget、budget-limited | 由 runtime 决定何时继续 |
| TUI | 状态栏、pause / unpause、elapsed time、token 展示 | 给用户可见控制面 |
Codex 的关键不是“它会循环”,而是循环成为 core runtime 的职责。PR #18076 的描述很明确:长目标的生命周期、工具完成边界、中断、恢复、token 记账和预算控制,都应该由 core 处理,而不是每个客户端自己实现。
这套设计的好处是控制态正式:pause、resume、budget-limited、interrupt 都是 runtime 里的状态。风险也同样来自 runtime:如果“等待用户确认”没有成为显式阻塞状态,continuation 可能把阻塞点当成下一轮继续重试。OpenAI/Codex issue #22245 就报告过 /goal 在危险操作确认处重复提示并消耗 quota 的问题。
Claude Code:/goal 是 session-scoped Stop hook
Claude Code 现在也有官方 /goal 文档。它的定位很清楚:设置一个 completion condition,Claude 会跨 turn 持续工作,直到条件满足。
与 Codex 的 runtime 集成路径不同,Claude Code 文档直接把 /goal 解释成一个 session-scoped prompt-based Stop hook。每个 turn 结束后,条件和 conversation 会发给小而快的模型,默认是 Haiku,返回 yes/no 和简短理由。no 会让 Claude 继续下一轮,yes 会清除 goal 并在 transcript 里记录达成。文档还强调 evaluator 不调用工具,只能判断 Claude 已经在对话中呈现出来的证据。
这个设计的关键在于把“执行模型”和“完成判断模型”拆开。主 Agent 负责干活,小 judge 负责判断条件是否成立。它比 completion promise 稳,但仍然依赖 transcript 里有没有足够证据。如果测试命令跑了却没有把结果说清楚,judge 没法自己进仓库重跑。
Claude Code 文档还把 /goal、/loop、Stop hook 和 auto mode 分开:
| 机制 | 下一轮何时开始 | 何时停止 |
|---|---|---|
/goal |
上一 turn 结束后 | 模型确认条件满足 |
/loop |
时间间隔到达 | 用户停止或 Claude 自己结束 |
| Stop hook | 上一 turn 结束后 | 用户脚本或 prompt 决定 |
| auto mode | 不启动下一 turn,只放宽工具确认 | 当前 turn 内 Claude 自己停 |
因此,Claude Code 的 /goal 更像把 Ralph Loop 插件内建成一个轻量官方入口:仍建立在 Stop hook 生命周期上,但减少了用户自己写 hook 的成本。
Hermes:把 judge、预算、gateway 状态公开成文档
Hermes Agent 的 Persistent Goals 文档更直接地承认了血缘关系:它称 /goal 是对 Ralph loop 的实现,用户可见设计受 Codex CLI 0.128.0 /goal 启发,但实现独立适配 Hermes 架构。
Hermes 的公开设计有几个很工程化的细节:
| 设计点 | Hermes 做法 |
|---|---|
| judge 输入 | standing goal + Agent 最近 final response,约最后 4KB |
| judge 输出 | 严格 JSON:done + reason |
| judge 策略 | 保守判断;明确完成、交付物产出、或不可达/阻塞时才 done |
| judge 异常 | fail-open,按 continue 处理,真正 backstop 是 turn budget |
| 默认预算 | 20 continuation turns,耗尽后自动 pause |
| 用户抢占 | 用户真实消息优先于 continuation |
| 持久化 | goal state 存在 session state,key 按 session 组织 |
| prompt cache | continuation 是普通 user-role message,不改 system prompt / toolset |
Hermes 的价值不只是“也有 /goal”,而是把持久目标扩展到多 gateway 场景:CLI、Telegram、Discord、Slack、Matrix、Signal、WhatsApp、SMS、iMessage、Webhook、API server、web dashboard 都可以走相同控制语义。对这种常驻 Agent 来说,goal 不只是本地终端的长任务,也是跨入口的 session control plane。
Ralph、Goal、SDD Sidecar 的本质差异
把这些实现放在一起,会得到一个更清晰的分类:
| 系统 | 继续机制 | 完成信号 | 状态位置 | 最适合的任务 |
|---|---|---|---|---|
| Anthropic Ralph Loop 插件 | Stop hook 重喂 prompt | completion promise | 当前 session + 文件系统修改 | 小到中型、验收标准明确的迭代任务 |
| OpenCode / Oh My OpenCode Ralph | idle / hook 后注入 continuation | <promise>DONE</promise> |
项目 state file | 轻量复制 Ralph 手法 |
| Oh My ClaudeCode Ralph | skill + PRD 状态 + reviewer | story passes + reviewer approval | PRD / progress state | 多 story、需要签收的任务 |
Claude Code /goal |
session-scoped Stop hook | 小模型 yes/no judge | 当前 session transcript | 有明确条件、证据能写进对话的任务 |
Hermes /goal |
continuation prompt | auxiliary judge JSON | SessionDB state + gateway queue | 常驻跨平台 Agent |
Codex /goal |
core runtime continuation | goal tool / runtime state | thread goal + app-server API | 需要 runtime 预算、中断和恢复控制的长任务 |
sdd-all sidecar |
不直接循环,提供循环材料 | gate script + evidence + ledger | openspec/changes/<change>/_sdd/ |
需要 SDD 审查、部署验收、归档沉淀的工程变更 |
这张表说明一个关键点:所有 goal 模式都能还原成“循环 + 完成判断”,但不同系统选择的“完成判断器”不一样。Ralph 把判断交给字符串;Claude 和 Hermes 交给 judge model;Codex 交给 thread goal 的 runtime/tool 体系;SDD sidecar 把判断尽量推给脚本、evidence 和用户签收。
sdd-all Sidecar:不是第二套 SDD,而是验收 harness
脱敏分析的内部 sdd-all skill 有一个值得单独写的设计:它叠在 OpenSpec 之上,但不把所有增强都塞进原生 spec,也不让聊天上下文承载执行记忆。它把信息分成两层:
| 层 | 文件 | 职责 |
|---|---|---|
| 正式语义源 | proposal.md / spec.md / design.md / tasks.md |
需求、行为契约、技术取舍、任务拆分 |
| sidecar | _sdd/loop.md / _sdd/test-spec.md / _sdd/_evidence/*.json / 各类 ledger |
当前循环、测试历史、机器证据、人工签字 |
这条边界很关键。正式语义必须回到 native SDD 工件;sidecar 只能放执行记录和运行时证据。换句话说,sidecar 不应该回答“需求是什么”,它应该回答“执行到哪里了、拿到了什么证据、哪些失败被谁签字放行、检查脚本为什么通过或拒绝”。
sdd-all 里几个文件可以直接映射到 Goal/Ralph 的三层结构:
| sidecar 元素 | 对应 Goal/Ralph 问题 | 作用 |
|---|---|---|
loop.md |
下一轮继续做什么 | 极简 current goal + next iteration + 每轮摘要 |
test-spec.md |
什么场景需要验证 | 把 core / edge / exception / invariant cases 写成可执行计划 |
_evidence/*.json |
完成判断看什么证据 | 保存 pipeline、文档漂移、自审等机器可读证据 |
| skip / drift / review ledger | 谁允许例外通过 | 对失败、漂移、review finding 做逐条签字 |
check-*.sh |
什么时候进入下一阶段 | 用确定性脚本裁决阶段门禁 |
这就是“harness memory”的意义。它不是像人类笔记那样记录一大段过程,而是给下一轮 Agent 和检查脚本提供恢复所需的最小状态。相比普通 memory,它更接近可重放的执行账本。
但 sidecar 也有危险。如果把新的需求、设计决策、验收口径都写进 sidecar,而没有回融到 proposal/spec/design/tasks,它就会变成影子规范系统。那会破坏 SDD,因为实现阶段会同时面对两套真相:一套是已审查的 spec,一套是循环中慢慢长出来的 sidecar。一个健康的 sidecar 必须始终保持“窄”:只记录证据、状态、例外和历史,不夺走原生 SDD 工件的语义主权。
完成信号到底要不要精细设计
答案是:完成信号要精细,记忆模块未必需要复杂。
一个完成信号至少有三部分:
1 | |
end_state 是目标状态,例如“所有迁移调用点编译通过”。observable_evidence 是可观察证据,例如“npm test exit 0、pipeline stages 全部 success、页面截图存在”。authority 是谁有权判定,例如“judge model、gate script、用户签字、reviewer approval”。
很多 Ralph Loop 失败,并不是 loop 写错,而是 predicate 写得像愿望:
1 | |
sdd-all 的 sidecar 是一种更强 predicate 设计:完成态不是一句“done”,而是检查脚本读到 evidence 后返回 pass。比如 apply 只能说明“编码可进入测试”;真正 change 完成态要等外部测试 adapter 的成功判据全部满足。这个区分比“本地单测通过就完成”更稳,因为它把实现、测试、部署和验收拆成了不同权威。
更轻的项目可以不需要 sidecar。以下场景用 completion promise 或 Claude/Hermes judge 就够:
| 场景 | 推荐 |
|---|---|
| 单文件修 bug,有明确单测 | 普通 Agent turn 或轻量 /goal |
| 小型重构,证据都能进 transcript | Claude/Hermes judge-style /goal |
| 大迁移,需预算、中断、恢复 | Codex runtime-style /goal |
| 多 story、多验收、部署平台、人工例外签字 | SDD sidecar + gate scripts |
| 跨天任务队列、依赖、失败回滚 | harness-style task state |
这也是 sidecar 是否有必要的判断标准:如果完成态只依赖一个命令退出码,sidecar 过重;如果完成态依赖多轮 evidence、外部系统、人工例外和归档沉淀,sidecar 就不是装饰,而是 completion oracle 的输入层。
SDD 与 Goal 的正确组合
Goal/Ralph 解决“持续执行”,SDD 解决“执行什么才正确”。两者的最佳组合不是让 /goal 从一句模糊需求开始跑,而是先让 SDD 产出已审查工件,再把 goal 绑定到这些工件和检查命令上。
推荐链路如下:
1 | |
在这个链路里,Goal prompt 应该是执行契约,不是需求文档:
1 | |
如果用 sdd-all 这类 sidecar 设计,completion condition 还可以更硬:
1 | |
这条规则可以直接抑制 premature completion。它告诉 Agent:不要因为主观感觉完成就停,必须让外部完成判定器通过。
对工程实践的几条结论
第一,Ralph Loop 的“土法”并没有过时。Stop hook + prompt replay + completion promise 仍是最容易复制的 autonomous loop。它适合小项目、低风险迭代和一次性工具开发。
第二,Claude Code 和 Hermes 代表 judge-style goal:完成判定由另一个模型做,主 Agent 不能单方面宣布完工。这比 promise 更稳,但 judge 的视野通常受 transcript 限制。实践上必须让主 Agent 把测试输出、文件清单、失败原因和剩余项写清楚,否则 judge 只能猜。
第三,Codex 代表 runtime-style goal:目标、预算、中断、恢复和 continuation 被放到核心运行时里。它比外部 hook 更像产品能力,但也因此必须把用户确认、危险操作、预算软停等控制态处理好。
第四,SDD sidecar 代表 evidence-style goal:它本身不一定负责循环,却能给循环提供高质量完成信号。它把“完成”从自然语言声明变成可检查的 evidence + gate result。
第五,中间记忆不要为了记忆而记忆。优秀的状态文件不是长篇日志,而是下一轮执行和完成判定真正需要的字段。current goal、next iteration、last validation、evidence path、open blockers、user decisions 足够支撑大多数恢复场景。
第六,sidecar 的存在必须有成本意识。它会增加文件、脚本、签字和归档负担。只有当错误完成的代价高于流程成本时,它才值得引入。否则,轻量 /goal 或 Ralph Loop 就足够。
结论
Goal 模式的本质不是某个工具的 slash command,而是一类 Agent 控制协议:在 turn 结束之后,系统根据某个完成判定器决定是继续、暂停、清除还是归档。
Codex、Claude Code、Hermes、Ralph Loop 和 SDD sidecar 的差别,不在“会不会循环”,而在完成判定器和状态边界:
| 类型 | 最核心的完成判定器 |
|---|---|
| Ralph Loop | 主 Agent 输出的 promise |
Claude Code /goal |
session-scoped prompt-based Stop hook judge |
Hermes /goal |
auxiliary judge JSON + turn budget |
Codex /goal |
thread goal runtime + model tool + control state |
sdd-all sidecar |
gate scripts + evidence + user ledger |
因此,公开文章只写 Codex 会漏掉正在成形的通用模式。更准确的写法是:Codex 是 runtime 化样本,Claude Code 是 hook/judge 化样本,Hermes 是常驻 Agent/gateway 化样本,Ralph Loop 是最小可复制样本,SDD sidecar 是把完成信号工程化、证据化的样本。
真正值得带走的不是“让 Agent 一直跑”,而是:让 Agent 只在证据足够时停,并且在证据不足时知道下一步该验证什么。
参考资料
- OpenAI Developers - Follow a goal
- OpenAI Developers - Codex CLI slash commands:
/goal- openai/codex PR #18073 - Add goal persistence foundation
- openai/codex PR #18074 - Add goal app-server API
- openai/codex PR #18075 - Add goal model tools
- openai/codex PR #18076 - Add goal core runtime
- openai/codex PR #18077 - Add goal TUI UX
- openai/codex issue #22245 -
/goalrepeated dangerous-operation confirmation prompt- Claude Code Docs - Keep Claude working toward a goal
- Claude Code Docs - Hooks reference
- Claude Code Docs - How the agent loop works
- Hermes Agent Docs - Persistent Goals
- NousResearch/hermes-agent
- Anthropic Claude Plugin - Ralph Loop
- Oh My OpenCode features reference -
/ralph-loop- charfeng1/opencode-ralph-loop
- Yeachan-Heo/oh-my-claudecode -
skills/ralph/SKILL.md- 新智元转载参考:放羊大叔 Ralph Loop 传播文
- 本地脱敏分析:内部 all-in-one SDD overlay skill,重点参考 sidecar、phase gate、test-runner adapter、loop template 与 archive 设计。





