调研截至:2026-05-20。本文从 patleeman 的 Codex /goal PR 解析和 36氪 / 新智元关于 Ralph Loop 产品化的报道出发,交叉核对 OpenAI Codex、Claude Code、Hermes、Anthropic Ralph Loop、OpenCode / Oh My OpenCode、Oh My ClaudeCode、自进化 Agent 相关论文与公开资料,并对一个内部 all-in-one SDD skill 做了脱敏分析。脱敏约定:不写本地路径、组织名称、平台名称、具体适配器名和领域字段;下文用 sdd-all 指代这类内部 SDD overlay。

Goal 模式不应再被理解为 Codex 的单点能力。更准确的判断是:AI 编程工具正在把 Ralph Loop 这类外部循环,收敛成一类更正式的闭环交付控制协议

Goal 模式全景

先把 Ralph 循环的一句话定义放最前面

Ralph 循环 = 外层循环 + 稳定锚点提示词 + 外置完成判定器 + 外部可恢复进度态。

四件套缺任意一件,Ralph 都会塌成别的东西。展开来说:

部件 含义 朴素形态 工程化形态
外层循环 在模型一轮 turn / session 结束之后再决定继续与否,而不是让模型在单 turn 内自己跑完 while :; do …; done 三行 bash Codex runtime 里的事件驱动 continuation scheduler、Stop hook、idle continuation
稳定锚点提示词 每一轮重新注入的原始任务契约,在循环中保持不变;可以附带变化的状态(最近进度、未决阻塞),但锚点本身不变 钉死的 PROMPT.md PRD 状态 + standing goal + SDD proposal.md
外置完成判定器 决定循环何时停止的判定逻辑,必须外置于"主执行模型",否则就是模型自宣完成 模型自己输出的 <promise>DONE</promise> 字符串 独立 judge model(Claude Code Haiku judge / Hermes auxiliary judge)、Agent verifier、gate script + evidence
外部可恢复进度态 跨 turn / 跨 session 继续推进的物理基础;如果只活在 chat memory 里,上下文一压缩就丢 文件系统 + git 历史(Huntley 原版) thread goal state(Codex)、SessionDB(Hermes)、sidecar evidence ledger(SDD)

注意定义里没有出现"新开会话"——新开会话只是 context window 撑满时的一种容错策略,不是 Ralph 的本质特征:Huntley 原版用 claude-code --continue 续同一 session,Anthropic 官方 Ralph 插件也是 Stop hook 拦回当前 session,只有 context 满或被压缩时才需要换 session。把"新开会话"写进定义会让 Ralph 的边界出现不必要的模糊。

把这张表横着读一遍,就能把整篇文章的脉络抽出来:Anthropic Ralph 把四件全部停在朴素形态;Claude Code 把"外置完成判定器"升级成 judge model;Hermes 把"外层循环 + 完成判定器 + 进度态"三件升级成常驻服务;Codex 把"外层循环 + 进度态"升级到 thread runtime;SDD sidecar 把"完成判定器 + 进度态"升级到 evidence + gate script。

少一件就塌的对照:

少哪一件 退化成什么
外层循环 Codex 内层 agent loop——单 turn 长任务,turn 结束控制权回到用户
稳定锚点 普通会话流——每轮换目标,模型不再围绕同一任务推进
外置完成判定器 模型自宣完成(premature completion)或死循环烧 quota
外部进度态 上下文压缩或新 session 一开就忘事,等于每次从头开始

Success Mode 与 Failure Mode

四件套配齐还不够——颗粒度、证据强度、锚点恢复线索这三件配对得当,循环才闭环;配错任意一件,即使四件套都在,循环也照样塌。下面这两张表是后文所有具体工具特性的判分纸。

Success Mode 的三个共同前提:

前提 含义
颗粒度对齐 任务能拆到 “Agent 一次能做完、也能一次判断对错” 的大小
完成信号是可验证证据 编译通过、测试 exit 0、文件落盘、脚本返回 pass——不是 Agent 自述
锚点提示词带恢复线索 当前目标 + 任务清单 + 最近验证 + 未决阻塞 + 用户决策,而不是把原始 prompt 原样回放

Failure Mode 的几种典型形态,每一种都对应一种具体的工程补救:

Failure Mode 失败现象 工程补救
模糊愿望式 predicate “keep working until the migration is done”——Agent 永远找不到停下的理由 把 predicate 写成 (end_state, evidence, authority, recovery) 四元组
锚点提示词丢失进度 新会话从零开始,反复重做同一个失败 落盘最小可恢复状态(loop.md、progress、PRD 状态)
主 Agent 自宣完成 一句 “I have completed the task” 就退出,premature completion 独立 judge model / gate script / sidecar evidence
阻塞点被当失败重试 用户确认、危险操作、外部依赖未到——Agent 撞墙、烧 quota 把阻塞做成一等状态(Codex pause、Hermes blocked、SDD review ledger)
上下文压缩抹掉目标 长任务跑到一半,session 重连后 goal 没了 把 goal 从 chat memory 下沉到 thread/session DB 或 sidecar

后面引入的所有工具能力,都可以倒推回这张表里的某一行。

两篇材料各自说对了什么

这条主线背后有两份关键引子材料,它们覆盖的是同一条 Ralph 循环演化轨迹的不同切面——一份是起源故事,一份是实现剖面。

36氪 / 新智元:起源故事 + 三家 failure-mode 概括

36氪先把 Ralph 循环的“原始形态”还原出来。澳大利亚牧羊人 Geoffrey Huntley 写了三行 bash:

1
2
3
while :; do
cat PROMPT.md | claude-code --continue
done

命名灵感来自《辛普森一家》角色 Ralph Wiggum——“原始,不优雅,但十分有效”。

这正是前面定义的最小可运行形态——把四件套对到这三行 bash 上看:外层循环是 while :,稳定锚点是钉死的 PROMPT.md,外置完成判定器等于零(所以它能死循环),外部进度态是文件系统 + git 历史。最后这条原文交代得很清楚——“进度记录在文件系统与 Git 历史里,上下文满了就开新实例继续”。注意 claude-code --continue 是在续同一个会话,不是新开;新会话只发生在 context 物理撑满时,由 Claude Code 自己处理 compaction。

然后 36氪用一句广泛传播的话把 Codex、Hermes、Claude Code 概括为三种 failure mode 的回应:

Codex「不忘事」,Hermes「不烂尾」,Claude Code「不自欺」。

  • Codex「不忘事」 → 回应 “上下文压缩抹掉目标”。原文描述 /goal 被实现为“持久化工作流对象,存放于本地 app-server 状态层,关机重启都不丢,下次打开自动续接”。
  • Hermes「不烂尾」 → 回应 “主 Agent 自宣完成 + 阻塞点被当失败重试” 的合集。原文称之为“五层防烂尾机制:心跳检测、僵尸回收、退出拦截、幻觉拦截、重试预算”,其中“幻觉拦截”是“最狠的一层”——会“验证 Agent 声称产出的代码是否真的落盘”。
  • Claude Code「不自欺」 → 回应 “主 Agent 自宣完成”。Stop Hook 把对话记录和完成条件交给独立小模型(默认 Haiku)裁判——“裁判模型不调用工具、不读文件、不跑命令,只看对话内容”,所以“完成条件必须是 Claude 在对话中能证明的东西”。

这套对仗适合做生态温度计,不适合作为实现细节依据——但它的真正价值,是把“为什么要在最小定义上做厚”翻译成了三种 failure mode 的具体故事。

patleeman gist:把循环 runtime 化的实现剖面

patleeman 的 gist 把 Codex /goal 拆成五个 PR(#18073-#18077):持久状态、app-server API、模型工具、core runtime、TUI。它最有价值的不是复述命令怎么用,而是用代码级证据回答“把 Ralph 的 while :; 提升为 runtime 控制面”到底要做什么。下面是 gist 原文里的关键设计决策,保留英文以免转译走样:

  1. Model can’t pause/resume — only create_goal and update_goal(complete) are exposed; pause comes from user interrupts, resume from thread re-entry, budget-limit from accounting.
  2. goal_id versioning — every replacement gets a new UUID; stale accounting from prior versions is dropped silently.
  3. Atomic budget enforcement — SQL CASE statements avoid check-and-set races.
  4. Auto-reported budget on completion — the response carries a human-readable summary so the model naturally tells the user how much it used.
  5. Conservative auto-continuation — a continuation turn with zero tool calls suppresses the next one.

更直接的是 gist 对循环本身的定性:

“The auto-continuation loop is fundamentally one-shot — it doesn’t re-fire indefinitely.”

“The runtime doesn’t loop: it fires one continuation per trigger (thread resume, external set to active).”

这两句话把 Codex 和 Anthropic Ralph 的真正分水岭点出来了:Codex 把 while :; 翻译成事件驱动的一次性 continuation——thread resume、external set active、idle 才触发下一轮,而不是无脑撞 Stop hook。换句话说,把循环 runtime 化的第一性,就是把 while :; 变成可观察、可中断、可记账的事件系统。

两篇合起来得到的判断

两篇放在一起,得到一个比单边引用更稳的判断:

Ralph Loop 不是被三家照抄了,而是被三种系统架构分别吸收成 failure mode 的工程化解药: Codex 把外层循环 + 进度态 runtime 化(解“上下文丢目标”“预算失控”),Claude Code 把外置完成判定器 judge 化(解“主 Agent 自宣完成”),Hermes 把整套四件套常驻服务化 + 多 Agent 编排化(解“烂尾”全家桶),SDD sidecar 把完成判定器 + 进度态证据化(解“完成不可审计”)。

后面章节就是逐项验证这条判断。四件套的朴素原型可以压缩成 “循环 + 完成信号”,但一旦进入真实工程,完成信号就不能只是一句 DONE:它至少要绑定可验证证据;跨 session、跨部署、跨人工签收时,还需要一个不会随上下文压缩丢失的外部状态层。sdd-all 的 sidecar 正是在这个位置出现的——它不是第二套需求文档,也不是业务记忆库,更像一个轻量 harness:记录当前循环、测试证据、用户签字和检查脚本可消费的完成态材料。简单改动不需要它,带部署验收、文档漂移、人工签收和归档沉淀的 SDD 变更需要它。

Goal 模式控制协议

Goal 模式三层结构

最小内核:外置完成判定器

回到四件套里 “外置完成判定器” 那一件——这是 Ralph 循环最容易塌的地方,也是后面所有工具差异化的主战场。其他三件(外层循环、稳定锚点、外部进度态)在工具之间差异是 “怎么做得更厚”,而完成判定器的差异是 “完全不同的判定者”,从字符串承诺一路升级到 evidence + gate script。

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 继续工作。

新智元转载文章把这个模式讲得很传播化:给任务清单,拿一个小任务,写代码,测试,失败就修,成功就保存进度,再拿下一个,直到满足条件退出。表述带强营销味,但技术上对应 success mode 第一个前提——任务必须拆到 “Agent 一次能做完、也能一次判断对错” 的颗粒度。

问题在于,DONE 不是证据。一个 completion promise 只能解决 “循环何时停止” 的接口问题,不能解决 “停止是否可信” 的判断问题——直接撞上 failure mode 表里的 “主 Agent 自宣完成”。真正决定生产可用性的,是 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。

Goal 家族对照

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

要理解 Codex /goal,必须先回到 OpenAI 公开解释过的 Codex agent loop:一次普通 turn 里,模型会在“推理 / 工具调用 / 工具输出”之间迭代,直到不再发出工具调用,而是返回一条 assistant message。对普通任务来说,这条 assistant message 就是 turn 的终止信号,控制权回到用户。

/goal 改变的不是这条内层 agent loop,而是 turn 结束之后的外层元循环:当 assistant message 出现时,runtime 不再简单把“模型说完了”解释成“任务完成了”,而是查看当前 thread 是否仍有 active goal、预算是否耗尽、用户是否打断、目标是否已经 complete,再决定是否启动下一轮 continuation。这个差异很重要。Codex /goal 不是让模型在一个超长 turn 里永远调用工具,而是在多个普通 turn 之间加了一层 durable control plane。

36氪那篇中文报道把 Codex 的卖点概括成“不忘事”:目标不再只躺在聊天上下文里,而是可以跨 turn、跨会话恢复。这个说法适合传播,但技术上还不够精确。patleeman 对 Codex goal PR 组的梳理更接近实现层:Codex /goal 是一组 thread-scoped persistent state、app-server API、模型工具、core runtime scheduler 和 TUI 状态面的组合,而不是一段“继续干”的 prompt。

Codex Goal 的运行时剖面

从 OpenAI/Codex 的 PR #18073 到 #18077 看,Codex 的设计更偏 runtime integration,而不只是一个 hook:

公开实现线索 作用
持久状态 thread_goalsthread_id + goal_id、objective、status、budget、usage、completion summary 目标跟 thread 走,不依赖 chat memory
stale update 防护 active goal_id、过期异步更新忽略 防止旧 continuation 覆盖新目标
app-server API thread/goal/get / set / clear、updated / cleared notification、resume snapshot 让客户端恢复、显示和同步目标状态
模型工具 get_goal / create_goal / update_goal 让模型读目标、创建目标、在受限边界内声明完成
core runtime GoalManager、idle continuation、interrupt、resume、token / wall-clock accounting、budget-limited 由 runtime 决定何时继续、何时暂停、何时软停
TUI 状态栏、pause / resume / clear、elapsed time、token 展示 给用户可见控制面

Codex 的关键不是“它会循环”,而是循环成为 core runtime 的职责。PR #18076 的核心价值在这里:长目标的生命周期、工具完成边界、中断、恢复、token 记账和预算控制,都由 core 处理,而不是每个客户端各自拼一个 hook。换句话说,Codex 把 Ralph Loop 的外部脚手架收进了运行时。

这个实现背后有五个设计不变量。

不变量 含义 为什么重要
Goal 是控制态,不是记忆 目标以 thread state 存在,而不是靠上下文里的一句话续命 上下文压缩、客户端重连、会话恢复都不会天然抹掉目标
用户拥有控制权 pause / resume / clear / budget-limited 不交给模型随意切换 防止执行模型在“想完成”时绕过用户控制边界
模型工具必须窄 模型可以读目标、创建目标、声明完成,但不能完全接管控制面 完成判断与调度权不会被同一个模型闭环吞掉
continuation 是 runtime 行为 空闲、邮箱、用户输入、工具完成、interrupt 都进入调度规则 下一轮不是“又发一条 prompt”,而是受事件系统约束
预算也是状态 token / wall-clock / continuation count 会影响 goal status 长任务能软停、总结、等待用户,而不是一直烧 quota

这也是 Codex 与传统 Ralph Loop 最根本的差别。Ralph Loop 的循环边界在 hook 或 shell 脚本里,Codex 的循环边界在 thread runtime 里;Ralph Loop 的完成信号通常是模型输出,Codex 至少试图把完成、暂停、预算、恢复都变成可观察状态。

36氪报道里提到“连续跑十几个小时、暂停后断点续跑”的使用故事,应该按案例叙事看,而不是按实现证明看。真正可核验的工程点在 PR 和文档里:Codex 的 durable objective 跟 thread 绑定,状态通过 app-server 可见,预算和使用量进入记账,interrupt / resume 是 runtime 事件。这些机制共同支撑了“可以离开一段时间再回来”的产品体验。

这套设计的好处是控制态正式:pause、resume、budget-limited、interrupt 都是 runtime 里的状态。风险也同样来自 runtime:如果“等待用户确认”没有成为显式阻塞状态,continuation 可能把阻塞点当成下一轮继续重试。OpenAI/Codex issue #22245 就报告过 /goal 在危险操作确认处重复提示并消耗 quota 的问题。

这个 bug 反而说明 /goal 的技术难点在哪里。真正难的不是让 Agent idle 后继续,而是把“用户确认”“危险操作”“预算耗尽”“外部阻塞”“目标已换”这些边界做成一等状态。只要某个边界仍然停留在自然语言提示里,runtime continuation 就可能把它误判成普通失败,然后继续撞墙。

还要注意版本演化。Codex /goal 在 2026 年 5 月仍处于快速变化阶段,OpenAI changelog 已经记录过 goal 行为调整,例如 resume 后是否自动激活暂停目标、以及无工具调用时是否继续等细节。写技术分析时,应该把 Codex 的稳定价值放在“目标进入 runtime control plane”这件事上,而不是押注某个过渡期策略永远不变。

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 因此可以理解为“内建 Ralph Loop + 独立裁判”。它不像 Codex 那样把目标状态下沉到 runtime,也不像 SDD sidecar 那样要求 evidence 文件可被脚本消费;它选择的折中是:在 session 结束点插入一个低成本 yes/no 判断器。

边界 Claude Code 的选择 直接后果
生命周期边界 session-scoped Stop hook 轻量、易理解,但天然偏当前会话
证据边界 evaluator 不调用工具,只看 conversation 主 Agent 必须把测试结果、变更清单、剩余风险写进 transcript
权限边界 judge 只返回是否满足目标和理由 不接管工具执行,也不替用户做外部确认

这种设计特别适合“目标明确、证据能被写进对话”的任务。它不适合把完成态寄托在外部系统、长时间部署流水线或人工签收上,因为 judge 没有额外感知能力。换句话说,Claude Code /goal 强在“防止主 Agent 自我宣布完成”,弱在“证据必须先被主 Agent 呈现出来”。

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
追加标准 /subgoal 可在 active goal 上追加验收条件,judge 必须同时考虑原始目标和全部子目标
用户抢占 用户真实消息优先于 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。

这也是 36氪文章把 Hermes 称为“不烂尾”的原因。Codex 的中心是 thread runtime,Claude Code 的中心是 session stop hook,Hermes 的中心更像常驻 Agent 的任务面板:goal 状态、worker heartbeat、重试、blocked 检查、gateway 消息队列和 budget 都被放进一个能长期运行的服务结构里。

系统 状态中心 典型控制问题
Codex 单个 thread 的 runtime goal 本地长任务如何空闲续跑、被用户打断、受预算约束
Claude Code 当前 session 的 Stop hook evaluator turn 结束时是否真的满足目标
Hermes 常驻服务的 session / gateway / worker state 多入口消息、worker 存活、重试、队列和长期任务如何统一

Hermes v2026.5.7 release note 里把 /goal 和 durable multi-agent Kanban 放在同一个大版本中,这一点很关键。/goal 是单个 Agent 的纵向目标锁定:一个 session 围绕一个 standing goal 继续推进。Kanban 是多个 worker 的横向调度:任务卡片、worker 心跳、失败诊断、幻觉门禁、max_retries、completion summary 等机制一起解决“多 Agent 团队会不会烂尾”。36氪说“一个人干不完,那就上一个团队”,准确点说,是 Hermes 同时做了纵向 Ralph loop 和横向 durable board。到 v2026.5.16,Hermes 又补了 /subgoal,允许用户在正在运行的 goal 上追加验收标准。这不是另开一个循环,而是在原有 completion predicate 上收紧条件,避免任务跑到一半时只能靠自然语言打断和重写目标。

Hermes 的工程启示是:当 Agent 从“本地 CLI 工具”变成“常驻服务”,goal 就不只是一个 completion predicate,而会长出调度系统的味道。预算、gateway、worker 状态、僵尸任务清理、保守 judge 和 fail-open 策略,都是为了让持续执行在不可靠环境里仍有边界。

自进化 Agent:不是更长的 Goal,而是会改写运行资产

Hermes 还有另一条线索容易和 /goal 混在一起:它在 README 里把自己描述成带内建 learning loop 的 Agent,会从经验创建 skill、在使用中改进 skill、提示自己沉淀知识、搜索历史会话,并逐渐建立跨 session 的用户模型。这个定位已经越过了 Ralph Loop 的边界。Ralph/Goal 解决的是“这个任务要不要继续跑”;自进化 Agent 解决的是“这次运行留下什么,使下一次同类任务的系统本身更强”。

这个区分很重要。一个 /goal 连跑二十轮,未必发生自进化;一个只跑三轮的任务,如果把失败原因编译成新 skill、更新检索配置、修正 workflow 或生成新的工具约束,就已经发生了自进化。自进化的判据不是“跑得久”,而是是否出现了一个经过验证、可持久化、会影响未来执行的系统资产。

类型 改变的是什么 是否自进化
ReAct 式工具 Agent 当前推理轨迹和工具动作 否;下一次通常从同一个 prompt / toolset 出发
Reflexion 式反思 Agent 反思文本和 episodic memory 半步;经验进入上下文,但系统结构通常不变
Voyager 式 lifelong Agent 可复用 skill library 接近;经验被沉淀为可调用技能
SWE-agent / Claude Code / Codex /goal Agent-computer interface、runtime、完成控制面 主要是 harness 进化;单个用户运行时不必然自改进
Hermes learning loop skill、memory、用户模型、历史检索材料 是产品化自进化的样本,但仍主要改外部资产,不是在线改模型权重
DGM / AlphaEvolve / EvolveMem Agent 代码、算法代码、记忆检索配置 更强;优化器直接改写可执行或可配置系统资产,并用 benchmark / evaluator 回归

近两年的研究把这条线讲得更系统。Self-Evolving AI Agents 综述把自进化抽象成四个部件:System Inputs、Agent System、Environment、Optimisers。关键不在“Agent 有记忆”本身,而在 Optimiser 会基于交互数据和环境反馈,自动增强 Agent System 的某个组成部分。Experience-driven Lifelong Learning 则把循环拆成 experience exploration、long-term memory、skill learning、knowledge internalization:先产生轨迹,再结构化保存,再抽象为技能,最后让技能变成下一次执行的默认能力。

这和早期 Agent 的差别,可以压成一句话:早期 Agent 主要在一次任务内规划、调用工具、反思和重试;自进化 Agent 把任务后的经验变成下一次任务开始前就存在的能力。

几个代表性系统刚好覆盖了不同层级:

系统 进化对象 完成/选择依据 启示
AlphaEvolve 算法程序 自动 evaluator 对候选程序打分 适合数学、算法、系统优化这类可量化领域
Darwin Gödel Machine coding agent 自身代码 SWE-bench、Polyglot 等 benchmark 验证 自改进可以被工程化为“改代码 + 跑基准 + 保留有效分支”
EvolveMem 长期记忆的检索与融合配置 per-question failure logs + 自动回归 不只记忆内容会变,检索机制本身也可以进化
Hermes skill、memory、用户画像、跨会话检索 使用过程中的经验、skill 改进和持久化提示 常驻个人 / 团队 Agent 的自进化更像持续整理运行资产

这也解释了 Hermes 为什么适合拿来举例,但不能只讲 Hermes。Hermes 把自进化做成产品语义:常驻、跨入口、可记忆、可沉淀 skill。DGM、AlphaEvolve、EvolveMem 则把自进化做成研究语义:有明确优化对象、候选生成、自动评价、回归筛选和版本保留。两条线合在一起,才是“自进化 Agent”相对前一代 Agent 的真正差异。

真正的边界有三条。

第一,/goal 是控制循环,不是学习循环。它把一个目标锁住,让 Agent 不要半途停;但如果运行结束后没有生成新的 skill、memory policy、workflow 或工具配置,系统能力并没有进化。

第二,记忆是必要条件,不是充分条件。把聊天记录存进向量库,只能让 Agent 找得到过去;自进化还要求它能从过去抽象出可复用规则,并在后续任务中默认应用。sdd-all sidecar 里的 evidence ledger 也是类似道理:它保存的是验收证据,不是自动进化机制。只有当这些证据反过来更新 gate、模板、测试计划或执行策略时,才进入自进化。

第三,自进化必须有回归闸门。没有 evaluator 的“自我改进”只是自动改配置,甚至可能越改越坏。AlphaEvolve 靠自动评估指标筛候选,DGM 靠 coding benchmark 保留分支,EvolveMem 有 revert-on-regression。Hermes 这类产品化 Agent 也需要同类边界:skill 自动改进后要能回滚,memory 提取要能审计,用户画像要能被用户修正,长期运行的 Kanban / goal 状态不能被一次错误反思污染。

因此,自进化 Agent 和前一代 Agent 的分水岭不是智能程度,而是系统边界。前一代 Agent 的核心资产由人预先写好:prompt、toolset、workflow、memory schema、ACI、评估脚本。自进化 Agent 允许这些资产中的一部分被运行数据持续改写,但每一次改写都要进入版本、评价和回滚体系。它不是把人移出循环,而是把人的一次性配置工作,改造成可审计的长期进化机制。

Cron:长程自主的时间控制面

还有一类机制看起来更朴素,却可能比 /goal 更接近真正的长程自主:cron、schedule、automation、heartbeat。传统 Agent 框架早就有主循环:模型思考、调用工具、拿到结果、再思考,直到停止。这个循环解决的是“当前 turn 内如何连续行动”。它没有解决一个更根本的问题:未来什么时候该再次醒来。

长程任务并不总是“连续跑到完成”。很多真实任务天然带时间间隔:明早再看 CI、半小时后检查部署、每天汇总一次新增 issue、每周审计依赖、月底生成报告、外部系统回调前保持等待。把这类任务塞进主循环,Agent 只能用轮询硬等。它会占着上下文、烧 token、持有脆弱状态,还会把“现在没事做”误判成“任务完成”或“继续重试”。

Cron 把这个问题从模型上下文里拿了出来。它不是让 Agent 更会思考,而是给 Agent 一个外部时钟。OpenAI 的 Codex Automations 文档把这一点说得很直白:Codex 可以按 schedule 自动回来做事,把结果交给用户 review;thread automation 还能回到同一段 conversation,接着已有上下文继续。Hermes 的 Cron 文档则走得更工程化:每个 job 存 prompt、schedule、delivery 和可选 skills;gateway daemon 按 tick 启动新的隔离 Agent session;运行结果落盘并投递到平台;对 watchdog、心跳、阈值告警这类任务,还可以用 no-agent script mode,完全不碰 LLM。

这说明 cron 和主循环不是替代关系,而是两层控制面:

机制 触发条件 解决的问题 失败风险
主 agent loop 当前 turn 里还有工具调用或推理动作 把一个局部任务推进到下一步 无法表达“以后再来”,只能阻塞或轮询
Goal / Ralph loop turn 结束后目标仍未满足 围绕同一个 objective 持续推进 如果阻塞态不显式,会把等待当失败重试
Cron / automation 到达某个时间、周期或外部触发条件 在未来重新唤醒 Agent,执行可审计的重复任务 schedule、权限、交付目标或上下文绑定写错,会稳定地产生错误结果
Heartbeat / monitor 周期性检查系统健康或状态变化 让 Agent 只在异常或新信息出现时介入 没有静默成功和告警边界时,会变成噪声源

对自主规划来说,真正的进步在于:计划不再只是一个任务列表,而可以包含时间、等待和再评估。

早期 Agent 的计划大多是同步计划:

1
2
3
4
1. inspect repo
2. edit files
3. run tests
4. summarize

这类计划默认世界不会自己变化。所有步骤都发生在一个连续会话里,Agent 的任务是把当前状态加工到目标状态。

长程 Agent 的计划更像异步计划:

1
2
3
4
5
now: create migration PR and start CI
in 30m: check CI result; if failed, summarize failing jobs and reopen fix goal
tomorrow 09:00: scan new review comments and produce patch plan
every Friday: summarize unresolved blockers and stale decisions
on deploy completion: collect evidence and update SDD sidecar

这里的关键不是“每天自动跑一条 prompt”这么简单,而是 Agent 第一次拥有了时间上的行动语法。它可以把“等待”表达为一个可恢复的系统状态,而不是让模型在上下文里假装自己会一直记着。也可以把“下一次检查”变成一个持久化对象,带上 schedule、workdir、profile、skills、delivery target、last output、next_run_at 和失败策略。

这对真正的自主规划至少有四个增量。

第一,时间成为显式资源。主循环只知道 token budget 和 turn budget;cron 让 Agent 还能管理 wall-clock time。很多任务的瓶颈不是推理,而是外部世界还没给结果。把等待交给 scheduler,Agent 才能在等待期间释放上下文和计算资源。

第二,计划可以跨睡眠、重启和人的离线时间。Codex Automations 的“回到同一 conversation”解决的是 thread continuity;Hermes gateway cron 解决的是 always-on delivery。两者都把“用户不在场时也能到点执行”变成产品能力。这和单纯主循环有质变:主循环依赖当前会话活着,scheduler 依赖持久化任务活着。

第三,重复任务开始有审计边界。一个 cron job 可以被 list、pause、resume、edit、run、remove;输出可以落盘;失败可以告警;no-agent watchdog 可以零 token 运行。相比“Agent 自己记得每晚检查一次”,schedule 对象更像自动化资产。它能被用户看见、暂停、修改和删除。

第四,自主规划可以从“执行步骤”升级为“设计触发器”。一个成熟 Agent 不应该只会回答“现在做什么”,还应该会判断“什么事情不该现在做,而应该设一个未来触发”。例如:依赖外部审批时暂停 goal 并创建 follow-up;CI 排队时 20 分钟后检查;安全公告每天抓取但只在命中依赖时唤醒修复 Agent;每周把失败轨迹交给 critic 更新 skill。这个能力才接近人类项目管理里的提醒、例会、巡检和复盘。

因此,cron 对长程 Agent 的意义不在“定时任务”四个字,而在把时间从自然语言承诺变成运行时原语。主循环让 Agent 在一个连续片段内行动,goal loop 让 Agent 围绕一个目标跨 turn 继续,cron / automation 让 Agent 在没有当前对话推进力的时候重新进入世界。三者合起来,才像一个真正的自主控制系统:会做事,会判断未完成,会在合适的时间回来。

Ralph、Goal、SDD Sidecar 的本质差异

把这些实现放在一起,会得到一个更清晰的分类:

系统 继续机制 完成判定器 控制面位置 状态位置 最适合的任务
Anthropic Ralph Loop 插件 Stop hook 重喂 prompt completion promise hook / 插件 当前 session + 文件系统修改 小到中型、验收标准明确的迭代任务
OpenCode / Oh My OpenCode Ralph idle / hook 后注入 continuation <promise>DONE</promise> 项目命令 / state file 项目 state file 轻量复制 Ralph 手法
Oh My ClaudeCode Ralph skill + PRD 状态 + reviewer story passes + reviewer approval skill workflow PRD / progress state 多 story、需要签收的任务
Claude Code /goal session-scoped Stop hook 小模型 yes/no judge Claude Code session 当前 session transcript 有明确条件、证据能写进对话的任务
Hermes /goal continuation prompt auxiliary judge JSON + turn budget 常驻 Agent / gateway SessionDB state + gateway queue 常驻跨平台 Agent
Codex /goal core runtime continuation goal tool / runtime state Codex core runtime thread goal + app-server API 需要 runtime 预算、中断和恢复控制的长任务
sdd-all sidecar 不直接循环,提供循环材料 gate script + evidence + ledger SDD phase gate 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 Sidecar 与 Goal/Ralph 的关系

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,它更接近可重放的执行账本。

把它和 Hermes 放在一起看,差异会更清楚:Hermes 的 durable state 是给 worker 和 gateway 用的,回答“下一条消息该交给谁、是否需要继续、worker 是否还活着”;sdd-all sidecar 的 durable state 是给 phase gate 和审查者用的,回答“这个 change 是否有足够证据进入下一阶段”。前者偏 orchestration memory,后者偏 verification memory。

对比项 Hermes durable goal state sdd-all sidecar
服务对象 常驻 Agent、gateway、worker SDD phase gate、检查脚本、审查者
主要问题 长任务如何继续调度 阶段完成如何被证据证明
关键字段 goal、turn budget、judge result、gateway queue、worker status loop、test-spec、evidence、skip ledger、drift ledger、review ledger
失败处理 retry、pause、blocked、fail-open + budget backstop fail-closed gate、用户签字、证据补齐、回退阶段
最终归宿 session state 延续 归档沉淀到正式 SDD 变更历史

因此,sidecar 没有必要变成一个“中间记忆大脑”。它更像验收夹具:把完成判定所需的输入固定下来,让脚本和人都能复核。只要流程仍然是 native SDD 工件给语义、sidecar 给证据,它就不会和 SDD 本体争夺主权。

但 sidecar 也有危险。如果把新的需求、设计决策、验收口径都写进 sidecar,而没有回融到 proposal/spec/design/tasks,它就会变成影子规范系统。那会破坏 SDD,因为实现阶段会同时面对两套真相:一套是已审查的 spec,一套是循环中慢慢长出来的 sidecar。一个健康的 sidecar 必须始终保持“窄”:只记录证据、状态、例外和历史,不夺走原生 SDD 工件的语义主权。

完成信号到底要不要精细设计

答案是:完成信号要精细,记忆模块未必需要复杂

一个完成信号至少有三部分:

1
predicate = end_state + observable_evidence + authority + recovery_state

end_state 是目标状态,例如“所有迁移调用点编译通过”。observable_evidence 是可观察证据,例如“npm test exit 0、pipeline stages 全部 success、页面截图存在”。authority 是谁有权判定,例如“judge model、gate script、用户签字、reviewer approval”。recovery_state 是未完成时下一轮从哪里恢复,例如“下一项任务、最近失败、阻塞原因、已确认例外、最新 evidence 文件”。

不同 goal 体系其实是在这四个变量上做取舍:

体系 end_state observable_evidence authority recovery_state
Ralph Loop prompt 里的完成承诺 Agent 自述和文件修改 主 Agent hook 继续重喂 prompt
Claude Code /goal 用户写的 completion condition transcript 中呈现的证据 Stop hook judge session conversation
Hermes /goal standing goal final response 摘要和 session state auxiliary judge + budget SessionDB / gateway queue
Codex /goal durable objective runtime state、工具结果、模型声明 runtime + model tool + user control thread goal state
SDD sidecar SDD 阶段门禁 evidence JSON、ledger、脚本输出 gate script + 用户签字 sidecar loop / test-spec / ledgers

很多 Ralph Loop 失败,并不是 loop 写错,而是 predicate 写得像愿望:

1
2
3
bad: keep working until the migration is done
good: keep working until all migrated call sites compile, the full test command exits 0,
and the final response includes command output summary and changed-file list

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
2
3
4
5
6
7
8
9
explore / research
-> proposal.md
-> specs/<capability>/spec.md
-> design.md
-> tasks.md
-> human review
-> goal / ralph execution
-> sidecar evidence
-> verify / archive

在这个链路里,Goal prompt 应该是执行契约,不是需求文档:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/goal Execute approved SDD change <change-id> until completion is proven by checks.

Read first:
- openspec/changes/<change-id>/proposal.md
- openspec/changes/<change-id>/design.md
- openspec/changes/<change-id>/tasks.md
- openspec/changes/<change-id>/specs/**/spec.md

Completion condition:
- every checked task in tasks.md is implemented
- implementation stays inside design.md File Scope unless clarified
- apply-ready check passes
- pipeline-result check passes
- final response includes changed files, validation commands, and evidence file names

Pause if:
- a destructive operation is required
- acceptance criteria conflict
- a required credential or external platform is unavailable
- the same failure repeats three times

如果用 sdd-all 这类 sidecar 设计,completion condition 还可以更硬:

1
2
3
Do not mark this goal complete from prose alone.
Only complete after the SDD check script reports pass and the latest evidence file
matches the current revision.

这条规则可以直接抑制 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 goalnext iterationlast validationevidence pathopen blockersuser decisions 足够支撑大多数恢复场景。

第六,sidecar 的存在必须有成本意识。它会增加文件、脚本、签字和归档负担。只有当错误完成的代价高于流程成本时,它才值得引入。否则,轻量 /goal 或 Ralph Loop 就足够。

第七,自进化能力要和 goal loop 分开设计。Goal loop 负责持续推进,learning loop 负责沉淀可复用资产。把两者混在一个 prompt 里,最后很容易变成“边干活边改自己的规则”,既不好审计,也不好回滚。更稳的做法是:执行期只记录轨迹和证据,任务结束后由独立的 critic / refiner 生成候选 skill、memory rule 或 workflow patch,再通过 evaluator 和人工 review 决定是否合入。

第八,长程自主需要外部时钟。主循环负责当前连续行动,goal loop 负责跨 turn 的目标保持,cron / automation 负责未来唤醒、周期巡检和异步等待。没有 scheduler 的 Agent 只能“现在一直跑”;有 scheduler 的 Agent 才能把计划拆成“现在做、稍后查、定期巡检、异常再介入”。

结论

回到开头那句话:Ralph 循环 = 外层循环 + 稳定锚点提示词 + 外置完成判定器 + 外部可恢复进度态。走完一圈,可以更稳地说出它的真正含义——Goal 模式不是某个工具的 slash command,而是把这四件套做成可观察、可中断、可审计的 Agent 控制协议:在 turn 结束之后,系统根据某个外置完成判定器决定是继续、暂停、清除还是归档,而锚点和进度态保证下一轮不会从零开始。

Success mode 总是同一条:颗粒度对齐 + 完成信号是可验证证据 + 锚点提示词带恢复线索。Failure mode 也总是那几条:模糊愿望式 predicate、锚点丢失进度、主 Agent 自宣完成、阻塞被当失败重试、上下文压缩抹掉目标。Codex、Claude Code、Hermes、Ralph Loop 和 SDD sidecar 的差别,不在 “会不会循环”,而在它们各自把哪几条 failure mode 用工程手段堵死了——也就是完成判定器和状态边界的取舍:

类型 最核心的完成判定器
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 的 skill、memory、workflow、工具配置或自身代码。

真正值得带走的不是“让 Agent 一直跑”,而是:让 Agent 只在证据足够时停,并且在证据不足时知道下一步该验证什么。

下一阶段的竞争不会是谁把 loop 写得最长,而是谁能把 goal、证据、预算、人工控制、恢复状态、时间触发器和可进化资产做成最清楚的控制协议。Ralph Loop 是最小原型,Codex 是 runtime 化,Claude Code 是 hook/judge 化,Hermes 是常驻服务化,cron / automation 是时间控制面,SDD sidecar 是证据工程化,DGM / AlphaEvolve / EvolveMem 代表的是自进化工程化。它们指向同一个结论:Goal 模式正在从 slash command 变成 Agent 工程的入口层,而自进化会把这个入口层继续推进到“系统如何从自己的运行历史里改变自己”。

参考资料