G GAN · AGENTIC RUNTIME NOTES

Claude Code 的 /goal,
不是一句“请别停”

更准确地说,它是一个“停止条件控制器”:主模型负责干活,独立评估器负责裁判,Hook/runtime 负责不满足就继续。

Claude Code v2.1.139+Stop hookEvaluator modelGoal state

01先给一个反直觉判断

一个 agent 能不能把任务做完,关键不在于它有多“自觉”,而在于运行时有没有权力阻止它过早停下。

很多人以为 `/goal` 是在 prompt 里加一句:“你要一直做,直到完成”。这当然有用,但不稳。因为主模型一旦觉得自己该结束,它还是会写总结、停下来。

真正的机制是:Claude 准备停时,运行时先触发 Stop hook,把目标和 transcript 交给一个评估器检查。没达标,就不许停。
🧑‍💻

Worker model

负责推进任务:改代码、跑工具、写总结、展示证据。

⚖️

Evaluator model

负责裁判:根据 transcript 判断目标是否已经被证明完成。

🪝

Hook / runtime

负责控制:允许停止,或者把 reason 注入下一轮继续跑。

02/goal 的官方机制,拆成一张图

它不是一个单轮命令,而是一个围绕“停止时刻”建立的控制环。

MERMAID-STYLE FLOW · GOAL CONTROL LOOP🌀
1 set goal完成条件 2 agent works正常执行任务 3 tries stop准备结束 4 Stop hook触发检查 5 evaluator看证据 ok?true / false false → continue注入 reason true → done清除目标 重点:检查发生在“准备停止”的那一刻;如果目标没有被 transcript 证明完成,就阻止停止。

03评估器到底看什么?

官方机制里,评估器不是第二个干活的 agent。它不自己跑命令、不读文件,只根据 Claude 已经展示出来的执行记录判断。

✅ 它会看

目标条件、当前对话记录、工具输出、最后一条 assistant 输出。比如 transcript 里有没有明确的测试通过证据。

❌ 它不会做

不会自己去跑 npm test,不会自己读文件,也不会替主模型补证据。

{ "ok": false, "reason": "Tests have not been run yet." }
所以一个好 goal 必须可验证:“npm test exits 0” 好;“代码质量很好” 差。前者有证据,后者只是感觉。

04为什么这比 prompt 里写“不要停”更稳?

因为它把“做事”和“判定是否能停”分开了。主模型可能会乐观、疲劳、遗漏检查;外部控制环不会因为一句总结就放行。

CONTROL ARCHITECTURE · WORKER / JUDGE / RUNTIME⚙️
Worker负责做事改代码/跑命令 Evaluator负责判断证据ok / reason Runtime负责放行/续跑block or stop 不满足:reason 回流给 Worker,继续下一轮
这就是 agentic runtime 的味道:不是让一个模型同时当工人和质检员,而是把执行、评估、控制拆开。

05/goal、/loop、Stop hook、Auto mode 的区别

机制
它解决什么
它不解决什么
/goal
目标完成判断。上一轮准备结束后检查是否满足 goal。
它不自己跑命令;只看 transcript 里的证据。
/loop
按时间间隔重复执行。
不是目标完成裁判。
Stop hook
底层拦截点:agent 要停时先触发。
本身不等于 goal;你要自己写判断逻辑。
Auto mode
减少工具审批,让执行更顺。
不负责跨轮续跑,也不判断目标完成。
压缩公式:/goal = Stop hook + goal state + evaluator + continuation

06社区实现 jthack/claude-goal 说明了什么?

社区实现不是官方机制,但它把这个模式讲得更“工程化”:目标状态存在本地,Stop hook 负责拦停,状态机决定 pause/resume/clear/complete。

🗃️

SQLite 存状态

例如 ~/.claude/goal/goals.sqlite 保存 active/paused/complete。

🪝

用户级 Stop hook

安装到 ~/.claude/settings.json,当 goal active 时 block 停止。

🛡️

Runaway guard

必须有最大续跑次数,防止目标永远不满足导致死循环。

07如果给 Codex/OpenClaw 做类似功能

最小可行设计不是“加一句 prompt”,而是给 runner 外面包一个循环。

while goal.active: result = run_codex_turn(prompt_or_continuation) evaluation = evaluate_goal( objective=goal.objective, transcript=result.transcript, last_output=result.final_message, ) if evaluation.ok: mark_complete() break prompt_or_continuation = ( "Continue working toward the goal. " f"Evaluator says not complete: {evaluation.reason}" )

稳定版评估器

先跑确定性检查:测试、lint、文件存在、git diff。再让 LLM 综合判断。

必须有保护

max_turns、max_wall_time、manual stop、permission blocker、rate limit blocker、needs-user-input blocker。

08最后一句话

/goal 的本质,是 agentic runtime 的停止条件控制器。主模型推进,独立评估器裁判,hook/runner 决定“不满足就继续”。