Claude Code /goalの使い方—完了条件の書き方と打ち切り設計

Claude Code /goalの使い方—完了条件の書き方と打ち切り設計 | mohablog

/goal に完了条件を1行渡すと、条件が満たされるまでターンを跨いで走り続けます。ターンが終わるたびに小さく速いモデルが成立を判定し、満たされていなければ Claude が次のターンを自分で始める作りです。対象は Claude Code v2.1.139 以降、手元の CLI は claude --version2.1.220 を返す環境。

目次

ターンの継ぎ目で止まるのをやめさせる

auto mode は次のターンを始めない

API 移行のような作業を投げると、Claude は数十ファイル直したところで一度返してきます。承認プロンプトを消しても、この継ぎ目は残ったまま。公式ドキュメントの “Compare ways to keep a session running” の節が線を引いています。

Auto mode on its own approves tool calls within a single turn but doesn’t start a new one.

auto mode が消すのはツール1回ごとの確認、/goal が消すのはターン1回ごとの確認。担当範囲が重なりません。逆に /goal 自体は権限モードを触らないので、既定モードのままだと pytest の実行前で止まります。放置して回すなら両方が要ります。権限側の評価順序は Claude Code permissions—allow/denyの落とし穴と評価順序 に整理済み。

条件を渡した時点で1ターン走る

設定と同時に、条件文そのものが指示として使われます。別のプロンプトを送る必要はありません。

/goal all tests in test/auth pass and the lint step is clean

叩いた直後にステータス行へインジケータが出て、ゴールの経過時間を表示します。

◎ /goal active

1セッションにゴールは1つ。すでにアクティブな状態で叩くと、新しい条件が古いほうを上書きします。

状態と解除は同じコマンドで見る

引数なしで消費を確認する

引数を付けずに /goal だけを打つと、現在の状態が出ます。

/goal

表示される内容は条件、経過時間、評価済みターン数、その時点のトークン消費、評価器が返した直近の理由。ターン数と理由が載るのは最初の評価が走ってから。アクティブなゴールが無くても、セッション内で達成済みのものがあれば同じ項目が残ります。

clear とその別名

条件成立前に外すなら /goal clear です。

/goal clear
Goal cleared: all tests in test/auth pass and the lint step is clean

何も設定されていなければ No goal set が返ります。stop / off / reset / none / cancel も別名として同じ動作。会話をリセットする /clear でもアクティブなゴールは落ちます。

評価器はトランスクリプトしか読まない

ツールを持たないモデルが判定する

/goal の実体は、セッションスコープの prompt 型 Stop hook です。ターンが終わるたびに条件と会話履歴が小さく速いモデルへ送られ、yes / no と短い理由が返ります。Claude API での既定は Haiku“How evaluation works” の節に制約が書かれています。

It does not call tools, so it can only judge what Claude has already surfaced in the conversation.

評価器はコマンドを実行しません。ファイルも独立には読みません。会話に出ていない事実は、無いものとして扱われる前提。hook の型ごとの違いは Claude Code Hooksのprompt型/agent型とは—5つの使い分け にまとめてあります。

証明手段まで条件に書く

抽象的な完了宣言は判定材料になりません。

/goal 認証まわりのリファクタが完了している

評価器が受け取るのは「完了している」という文字列だけ。何をもって完了とするかが会話に出てこないので、Claude の自己申告で yes が返るか、延々と no が返り続けるかの二択になります。証明手段を条件へ埋め込むと、判定材料がトランスクリプト側に固定されます。

/goal test/auth 配下を pytest で走らせて全件パスし、ruff check が exit 0 を返すこと。
他のテストファイルは変更しない

Claude がテストを走らせ、結果が会話に載り、評価器はそれを読んで判定する流れ。test/auth 配下 とスコープを切っているのも効きます。「テストが全部通る」だけだと、Claude が対象を広げてリポジトリ全体の失敗まで拾い、条件が永遠に成立しません。

no が返ったときの理由は捨てられず、次のターンの指示として扱われます。ステータス表示にも直近の理由が出るので、ゴールが空回りしているときは、そこを見れば評価器と Claude のどちらの認識がずれているか切り分けられます。

長持ちする条件の形

“Write an effective condition” の節が挙げている要素は次の内容です。

  • 測れる終了状態: テスト結果、ビルドの終了コード、ファイル数、空になったキュー
  • 証明の手順: npm test が 0 で終わる、git status がクリーン、といった提示のしかた
  • 崩してはいけない制約: 途中で変わってほしくないもの

3つ目が抜けると、条件は満たすが別のところを壊す解に流れます。「マイグレーションを新規追加しない」「公開 API のシグネチャを変えない」あたりを制約として置いておくと、逃げ道が減ります。条件の上限は 4,000文字。設計書の受け入れ基準を丸ごと貼り込んでも収まる長さなので、要件が多いなら箇条書きのまま渡すほうが判定は安定します。

打ち切り条件は resume で数え直しになる

復帰するもの、リセットされるもの

ゴールを抱えたままセッションが終わった場合、--resume--continue で復帰します。ただし引き継がれるのは条件だけ。

項目resume 後の扱い
条件文そのまま引き継がれる
評価済みターン数リセット
経過時間タイマーリセット
トークン消費の基準リセット
達成済み・クリア済みのゴール復帰しない

再開手段そのものの違いは Claude Codeのチェックポイントとrewindの使い分け方 側の話。

ターン上限を効かせる書き方

回しすぎを防ぐ手段は、条件に or stop after 20 turns のような節を混ぜること。Claude が毎ターンその節に対する進捗を報告し、評価器が会話から判定します。

判定材料は会話なので、進捗報告がトランスクリプトに残っていれば復帰後も読めます。一方でステータス表示のターン数とタイマーは 0 から数え直し。--continue を挟む運用では、条件文の「20ターン」と画面のターン数がずれていきます。上限を時計やカウンタに預けるより、「進捗を1行ずつ会話に残す」形で書いておくほうが、セッションを跨いだときの読み違えは減ります。

ゴール自体に有効期限はありません。条件が成立するか /goal clear を打つまで走り続ける仕様で、/loop の7日失効のような自動停止は入っていません。打ち切りを条件文に書くかどうかは、そのまま放置時間の上限を決めるかどうかの判断になります。

評価モデルを差し替えると会話要約まで乗り換わる

環境変数の適用範囲

評価器を別モデルにするなら ANTHROPIC_DEFAULT_HAIKU_MODEL を設定します。効く範囲は /goal の評価だけではありません。公式にも警告として書かれています。

Claude Code reads ANTHROPIC_DEFAULT_HAIKU_MODEL everywhere it uses the small fast model, not only for /goal evaluation.

haiku エイリアスの解決先も同時に変わり、会話の要約といったバックグラウンド機能もそのモデルで走ります。評価の精度を上げる目的で重いモデルを指定すると、/goal を使っていない場面のコストまで上がる、という副作用。1つの環境変数で2箇所が動くので、切り替えるならバックグラウンド側の消費も一緒に見ます。

評価コストの見積もり

評価トークンの課金先は、プロバイダに設定された小さく速いモデル。公式は本ターンの消費と比べて無視できる水準と書いています。内訳を追うなら Claude Code /usage—使用量と制限の内訳をスキル単位で確認する の見方がそのまま使えます。既定モデルはプロバイダごとに違うため、サードパーティ経由なら各プロバイダのページで確認。

起動しない環境と、動いているのに無音のとき

hooks を止めていると使えない

評価器が hooks の仕組みに乗っているので、/goal は hooks が生きている環境でしか動きません。落ちる条件は次の通り。

  • ワークスペースの trust ダイアログを承認していない
  • disableAllHooks がいずれかの設定レベルで有効になっている
  • managed settings で allowManagedHooksOnly が有効になっている

いずれのケースも、黙って何もしないのではなく理由を表示して落ちます。組織の managed settings で hooks を絞っている環境だと、手元の設定を疑っても原因に届きません。

-p は完了まで何も出ない

非対話モードでもゴールは使えて、1回の起動でループを完走します。

claude -p "/goal CHANGELOG.md has an entry for every PR merged this week"

既定のテキスト出力では、条件が満たされるまで標準出力に何も出ません。20ターン回るゴールは、外から見ると固まったプロセスと区別がつかない状態。

claude -p "/goal ..." --output-format stream-json --verbose

これでループ中の各メッセージが1件ずつ流れます。途中で止めるなら Ctrl+C。このブログの投稿フローも claude -p にプロンプトファイルを丸ごと渡してセッション外で走らせていて、標準出力をログへ落とす前提だとこの無音がそのまま「進捗ゼロのログ」になります。

/loop・Stop hook との役割分担

次のターンを何が起動するか

セッションを走らせ続ける手段は、起動の契機と停止の判断で見分けます。

手段次のターンが始まる契機止まる条件
/goal前のターンが終わったときモデルが条件成立を確認したとき
/loop一定時間が経過したとき自分で止めるか、Claude が完了と判断したとき
Stop hook前のターンが終わったとき自分のスクリプトかプロンプトが判断したとき

/goal と Stop hook はどちらも毎ターン後に発火します。違いはスコープと自由度。/goal は打ち込んだセッション限定のショートカット、Stop hook は設定ファイルに置くのでスコープ内の全セッションに効き、スクリプトによる決定論的な判定も書けます。判定ロジックを固定したいなら後者、その場の作業を走り切らせたいなら前者。

間隔で回すなら /loop

/loop は間隔を省略すると、Claude が毎回 1分〜1時間 の遅延を選んで自走します。セッションスコープのタスクは 7日で失効し、待機中に Esc を押せば止まる仕組み。前提はセッションを開いたままにしておくこと。マシンもセッションも空けたくない用途は Claude Code Routinesでcronを置き換える—クラウド無人実行の設定 の領域です。

まとめ

  • /goal はターンの継ぎ目を消すコマンド。権限モードは変えないので、放置するなら auto mode と併用する
  • 評価器はツールを呼ばない。会話に出ていない事実は判定材料にならないため、証明手段を条件に書き込む
  • 条件は 4,000文字まで。測れる終了状態・証明の手順・崩してはいけない制約を入れる
  • --resume で戻るのは条件だけ。ターン数・タイマー・トークン基準はリセットされるので、上限は会話に残る形で書く
  • ANTHROPIC_DEFAULT_HAIKU_MODEL は評価器だけでなく、小さく速いモデルを使う全機能に効く
  • 非対話モードは --output-format stream-json --verbose を付けないと完了まで無音
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次