2026-08-24 · 主题:
/goal完成条件驱动的长任务自主推进 为什么是今天:第 3 课讲 subagent 分工、第 6 课讲复杂需求稳定交付、第 16 课讲 worktree 并行——都是「怎么把活派出去」。但派出去之后谁来判断活干完了?一直是同一个模型自说自话。/goal把「干活的模型」和「判定完成的模型」拆成两个,这是长任务能不能真正无人值守的关键一环。 前置:/goal需 Claude Code v2.1.234+(check-in 功能);idle check-in 需 v2.1.236+;--resume选择器恢复 goal 需 v2.1.239+。 官方文档:https://code.claude.com/docs/en/goal
技巧 1(入门):写一个「评审员能读懂」的完成条件
/goal 后面跟条件,设完立刻开一轮,不用再发 prompt:
/goal all tests in test/auth pass and the lint step is clean
关键在于:评审员是一个小快模型(Claude API 默认 Haiku),它不跑命令、不读文件,只读会话里已经出现的内容做判断。所以条件必须是「Claude 自己的输出能证明」的东西。
一个能撑过几十轮的条件通常有三要素:
| 要素 | 说明 | 例子 |
|---|---|---|
| 一个可度量的终态 | 测试结果 / 构建退出码 / 文件数 / 队列清空 | 「test/auth 全部通过」 |
| 明确的验证方式 | 告诉 Claude 怎么证明 | 「npm test exits 0」「git status is clean」 |
| 不可动的约束 | 路上什么不许变 | 「不修改其他测试文件」 |
写全了大概长这样(条件上限 4000 字符):
/goal npm test exits 0 and npm run lint exits 0, proven by pasting the exit code of each; no file outside src/auth/ is modified; or stop after 20 turns
结尾那句 or stop after 20 turns 是兜底闸门——把轮数写进条件本身,Claude 每轮汇报进度,评审员从对话里判断这个子句是否触发。没有它,一个写得含糊的条件可能烧掉一整晚的 token。
查看状态直接敲 /goal(不带参数),会显示条件、已运行时长、已评审轮数、当前 token 花费、评审员最近一次的理由:
/goal
提前收手:
/goal clear
(stop / off / reset / none / cancel 都是 clear 的别名;/clear 开新会话也会顺带清掉 goal。)
📖 https://code.claude.com/docs/en/goal
技巧 2(进阶):/goal + auto mode 才等于「无人值守」
这是最常见的误解:/goal 不改变权限模式。
auto mode解决的是「一轮之内每个工具调用要不要问你」——它不会主动开启下一轮,Claude 自认为干完了就停。/goal解决的是「一轮结束后要不要再开一轮」——但如果权限模式是 Manual,每轮里的npm test还是会停下来等你点同意。
两者是互补的,要真正整晚不管,必须同时开:
# 会话里先切到 auto mode(或启动时指定),再设 goal
/goal migrate every call site in src/api/ to the v2 client, until `npm run build` exits 0 and `rg "v1Client" src/` returns nothing; or stop after 30 turns
另外三种「让会话自己往下跑」的机制,选型别搞混:
| 机制 | 下一轮由什么触发 | 什么时候停 |
|---|---|---|
/goal |
上一轮结束,或后台任务把 goal 挂起时的 idle check-in 到期 | 评审员判定 met / impossible;或遇到需你修的错误;或 /goal clear |
/loop |
时间间隔到了 | 你停它,或 Claude 认为做完了 |
| Stop hook | 上一轮结束 | 你自己的脚本或 prompt 说了算 |
一句话选型:按条件收敛用 /goal,按节奏轮询用 /loop,要跨所有会话生效、要确定性脚本判定就写 Stop hook(/goal 本质就是一个会话级的 prompt-based Stop hook 包装)。
📖 https://code.claude.com/docs/en/goal · https://code.claude.com/docs/en/hooks-guide#prompt-based-hooks
技巧 3(进阶):后台任务会「冻住」评审,check-in 节奏可以自己调
一个坑:如果一轮结束时还有 subagent 或后台 shell 在跑,这一轮不评审,要等到下一个「结束时没有后台任务」的轮次。后台任务跑完了,Claude Code 会把结果当作新的一轮送给 Claude,你不用再敲字。
问题是长构建/长测试会让 goal 一直挂着。Claude Code 的应对是 check-in:
- 后台任务把 goal 挂了 30 分钟后,第一次 check-in 到期:Claude Code 列出正在跑的任务,让 Claude 去读输出——还在推进就继续等,卡死了就修或杀掉。
- 之后每次间隔翻倍,上限为首次间隔的 4 倍:默认即 30 分钟 → 1 小时 → 2 小时 → 2 小时……
- 交互式会话里,空闲时 Claude Code 会主动开一轮送达 check-in(需 v2.1.236+);
-p非交互会话只能在轮次结束时送达。
嫌 30 分钟太长(比如你的测试跑 5 分钟就该有结论)可以改:
# 首次 check-in 改成 8 分钟,后续按 8 → 16 → 32 分钟退避
export CLAUDE_CODE_GOAL_CHECKIN_MINUTES=8
claude
# 完全关掉 check-in
export CLAUDE_CODE_GOAL_CHECKIN_MINUTES=0
还有个安全阀值得知道:如果 Claude 连续几轮只回话不动工具(在跟评审员打嘴仗),Claude Code 会停下循环、打印警告、把控制权还给你,但 goal 仍然保留——你下一次发 prompt 后评审会自动恢复。看到这个警告,基本等于条件写得太主观,回去改条件。
📖 https://code.claude.com/docs/en/goal · https://code.claude.com/docs/en/env-vars
技巧 4(高阶):把 /goal 塞进 CI / 定时脚本
/goal 在非交互模式、桌面端和 Remote Control 里都能用。用 -p 设 goal,整个循环会在一次调用里跑到收敛:
claude -p "/goal CHANGELOG.md has an entry for every PR merged this week, proven by listing the PR numbers and the matching lines" \
--output-format stream-json --verbose
两个必须注意的点:
- 一定加
--output-format stream-json --verbose。默认文本输出在整个循环结束前什么都不打印,一个跑了 20 轮的 goal 在 CI 日志里看起来就像挂死了。 - 中途要停按 Ctrl+C——非交互 goal 没有
/goal clear可敲。
哪些失败会自动清空 goal(需要你介入修的那类),值得写进你的 runbook:
- 认证失败(且凭据由 Claude Code 自己管;桌面端 / VS Code 扩展 / cloud session 这类由宿主管凭据的,goal 会保留)
- 额度耗尽
- 自动压缩也救不回来的上下文溢出
- 模型不可用
除此之外的失败(限流、服务过载等瞬时错误)goal 都会保留、继续跑。被清空时的警告以 Goal cleared after an unrecoverable error 开头、以 Run /goal again to continue 结尾——CI 里 grep 这两句就能区分「该重试」还是「该叫人」。
最后一个细节:恢复会话会把还活着的 goal 一起恢复(--continue、--resume <id|name>、会话选择器都支持;选择器路径需 v2.1.239+),但轮数、计时器、token 基线会重置。所以如果你靠 or stop after 20 turns 兜底,resume 之后这个预算是重新开始算的——长期跑的任务记得改成时间或产物口径的约束。
📖 https://code.claude.com/docs/en/goal · https://code.claude.com/docs/en/headless
一句话回顾
/goal = 一个会话级的 Stop hook,用小快模型在每轮结束后判定你的条件是否成立。条件要可度量、可从对话里证明、带兜底子句;要无人值守就配 auto mode;后台任务会推迟评审,靠 CLAUDE_CODE_GOAL_CHECKIN_MINUTES 调节奏;进 CI 记得 stream-json,并区分「会清空 goal 的四类错误」和「会自动继续的瞬时错误」。
主页