第7章: 計画する ─ Plan モードと TodoWrite の裏側
こんな経験はないだろうか。
Claude Code に「この関数のバグ直して」と頼むと、3 ステップで的確に直してくれる。 ところが「認証まわりをまるごとリファクタして」と頼むと ── 最初の 1 ファイルは丁寧に直すのに、途中から関係ない場所に手を出し始め、最後には「修正完了しました」と言いつつテストが落ちている。
小さなタスクは得意。なのに、大きなタスクで急に迷子になる。
同じ LLM、同じハーネス、同じ道具。何が違うのか。
7.1 そもそも、ループだけだと「次の一手」しか考えない
ここまで構造編で、ハーネス・コンテキストウィンドウ・ツール呼び出しといった「Claude Code を成り立たせている部品」を見てきた。 ここからの 制御編はその最初のテーマ ── 計画 から始める。エージェントを実際に動かして大きな仕事を任せようとした瞬間に、ほぼ全員がぶつかる課題だ。
復習として、本書ではエージェントの基本動作を agentic loop、すなわち think → act → observe の三拍子として説明してきた。 LLM が「次に何をするか」を考え、ツールを呼び、結果を見て、また考える ── この繰り返しだ。
このループには、ひとつ見落とされがちな性質がある。
agentic loop は、毎ターン “目の前の一手” を生成しているだけ。
ループ自体には「全体としてどこを目指していて、いま何合目にいるか」を見渡す機構が組み込まれていない。
小さなタスクであれば、これで十分機能する。 「fibonacci.py のバグを直す」程度なら、目の前の一手を 3 回繰り返せばゴールに到達する。次の一手が常にゴールに直結しているからだ。
ところが大きなタスクではこうはいかない。
「認証まわりをリファクタする」 = ① モデル層を直す → ② リポジトリ層を直す → ③ サービス層を直す → ④ ルーター層を直す → ⑤ テストを直す → ⑥ 動作確認
各ステップが終わらないと次に進めない。6 個の手を、順序を守って、しかも全体像を見失わずに 打たないといけない。 ここで「次の一手だけ考える」ループは、しばしば次のような失敗をする:
- ① をやり終えた直後、文脈の中で目立った別の関数が気になり、無関係なリファクタを始める
- ⑤ のテスト修正の途中で、テストの中で参照している無関係なモジュールまで書き換える
- ④ までやって満足し、テストを動かさずに「完了しました」と返してくる
要するに、全体俯瞰の不在だ。
人間のエンジニアは、複雑なタスクに着手するときまず 手を動かす前にメモを書く。 TODO リストでも、ホワイトボードでも、付箋でも構わない。 「①→②→③ の順でやる、いま①」と外に書き出すからこそ、途中で脇道に逸れずに戻ってこられる。
エージェントにも、これと同じ仕掛けが要る。
7.2 解決策 ── 計画と実行を分離する
ここでひとつ、ぶっきらぼうな解決策が出てくる。
そもそも、考えるフェーズと、動くフェーズを分けてしまえばいい。
エージェントに、まず 計画だけ立てさせる。手は出させない。 その計画を人間(あるいはエージェント自身)が眺めて、納得できたら 実行フェーズに切り替える。実行中は計画を参照して、脇道に逸れたら計画に戻る。
これを一枚の図にすると、こうなる。
Claude Code はこの「計画と実行の分離」を 二段構え で実装している。
- 大きな分離: Plan モード ── 実行ツールを丸ごと封じて、計画だけ立てさせるモード
- 小さな分離: TodoWrite ── 1 回の実行の中で、やることリストを書いて、進捗を更新する道具
順番に見ていく。
7.3 Plan モード ── 道具を封じて、考えさせる
Plan モード は、Claude Code に 計画を立てる時間 を強制的に設けるためのモードだ。
ユーザーが Shift+Tab を 2 回押す、あるいは Claude が自分でモードを切り替えると、エージェントは次のような状態になる。
Plan モードClaude Code の動作モードのひとつ。ファイル編集系・シェル実行系のツールを呼べない状態 で、コードベースを読み、計画を立て、それをユーザーに提示することだけが許される。承認すると通常の実行モードに戻り、計画を実行する。
ポイントは 「ツールを封じる」 ところだ。 ハーネスは、Plan モード中は LLM が Write / Edit / Bash のような副作用のあるツールを呼ぼうとしても、その呼び出しを通さない。LLM はそれを察して、代わりに次のような行動を取る:
- Read / Grep / Glob のような 読み取り専用ツール でコードベースを調べる
- 調べた結果を踏まえて、自然言語の計画書 を出力する
- 計画書をユーザーに提示し、「これで実行に移してよいか」と尋ねる
ユーザーが承認すれば、ハーネスは Plan モードを解除する。Claude はそのまま計画に沿って実行に入る。
Plan モードの本質は「LLM に 手を動かす前に考える時間 を強制的に与える」こと。 ループの一段上に 計画フェーズ という別のレイヤーを差し込んでいる。
なぜわざわざモードを分けるのか。 「いきなり実行モードでも、最初に頭の中で計画してから動けばいいのでは?」と思うかもしれない。 ところがこれが、人間と LLM の両方で観察される現象として うまくいかない。
理由はシンプルで、ツールが使える状態にあると、LLM は「とりあえず Read してみる、とりあえず 1 行直してみる」という行動に流れやすい。 手段が見えていると、考えるより先に手が出る。ツールを封じるという物理的な制約をかけてはじめて、計画らしい計画が出てくる。
7.4 TodoWrite ── 思考を外部化する道具
Plan モードが「実行に入る前」の分離だとすると、もうひとつの仕掛けは「実行中」の分離だ。 Claude Code は TodoWrite という特殊な道具を持っている。
TodoWriteClaude Code が長めのタスクに着手するとき、サブタスクのリストを作って外部に保存する ための専用ツール。各サブタスクには「未着手 / 進行中 / 完了」のステータスがあり、進捗に応じて Claude 自身が更新する。ユーザーには進行状況がリアルタイムで見える。
使い方の典型はこうだ。
- ユーザー「認証まわりをリファクタして」
- Claude が TodoWrite で 6 個のサブタスクを書き出す(モデル層 → リポジトリ層 → … → 動作確認)
- 最初のサブタスクを「進行中」に更新して、実装に取りかかる
- 終わったら「完了」に、次のサブタスクを「進行中」に
- 6 個すべて「完了」になるまで繰り返す
ここで重要なのは、TodoWrite はサブタスクをただ表示するためだけのものではないということだ。 書いた瞬間、そのリストは Claude 自身のコンテキストにも残る。 次のターンで「次は何をすべきだったか」を判断するときに、自分が書いたリストを参照できる。
TodoWrite は、LLM に “外部のホワイトボード” を持たせる仕掛け だ。
LLM の頭の中(コンテキスト)はトークンが増えると劣化する。 だが「①〜⑥のリスト、いま③をやっている」というメモを 明示的なテキストとして 持っておけば、コンテキストがどれだけ膨らんでも自分の現在地を見失わない。
これは思考を外部化するという、人間と同じ古典的な認知の戦略だ。 紙に書き出した瞬間に頭が整理されるのと同じことを、LLM に対しても道具として用意してある。
サブタスクという最小単位
ひとつ補足しておくと、TodoWrite のリストの 1 要素を本書では サブタスク と呼ぶ。粒度の感覚は「LLM が数ターンで完了できる」「単独で 1 つの完了基準を持てる」「他との依存順序が明確」あたりだ。
粗すぎれば(「認証まわり全部」)ループは迷子になる。細かすぎれば(「ファイル A の行 12 のコンマを消す」)リストの管理コストばかり膨らむ。 ちょうどよい粒度を見つけることは、計画フェーズの暗黙のゴールでもある。
7.5 なぜ「LLM 自身に計画を書かせる」のが効くのか
ここで少し立ち止まって、そもそも論 に戻ってみたい。
計画フェーズで出てくる計画書は、結局のところ LLM が生成した自然言語のテキストだ。 ハーネスがそれを解釈してタスクスケジューラに乗せているわけではないし、特別な構造を持っているわけでもない。
なのに、なぜそれを書かせるだけで挙動が改善するのか?
理由は三つある。
理由 1: コンテキストに乗る LLM はテキストとして書き出されたものしか参照できない。頭の中で考えただけのことは、次のターンでは思い出せない。 計画を テキストとして書き出した瞬間 に、それは以降のすべての推論で参照できる材料になる。
理由 2: 自己レビューが効く 書かれた計画は、LLM 自身が次のターンで読み返せる。 「あれ、③のステップは ② の結果が必要なのに、② をスキップしようとしている」と 自分で気づける。書かないで頭の中だけで考えていると、この自己レビューは起きない。
理由 3: 全体俯瞰が手に入る 計画書を作る瞬間、LLM は 「最初から最後まで」 を一度に考える必要に迫られる。 これは「次の一手」だけ考えているときには得られない視点だ。最後のステップを意識しているからこそ、最初のステップを正しく選べる。
計画を書く ことは、エージェントにとって記憶・自己レビュー・俯瞰を一度に手に入れる行為だ。 仕組みは単純(テキストを出力するだけ)なのに、効果が大きいのはそのため。
7.6 計画は完璧でなくていい ── 「動的な計画」という運用前提
最後に、現場でよく誤解される点を 1 つ。
「計画フェーズを置くなら、最初に完璧な計画を立ててから実行に入るべきだ」 ── そう思いたくなる。 だが Claude Code (および似た系統のエージェント) の設計は、その逆を行く。
計画は実行中に書き換えてよい。むしろ書き換える前提で設計されている。
実装に入ってから「あ、このファイルの構造、想定と違った」「思ったよりリポジトリ層が密結合だった」と気づくことは普通にある。 そのとき Claude は、TodoWrite を呼んで サブタスクのリストを書き換える。途中まで進めた進捗はそのままに、残りのステップを現実に合わせて差し替える。
これは ── ループだけのエージェントが脇道に逸れていく挙動とは、似ているようでまったく違う。
| 計画なしで脇道に逸れる | 計画を更新して進む |
|---|---|
| 無関係なファイルを触り始める | 関連ファイルが想定外に多いと気づく |
| 何をやっていたか忘れる | TodoWrite を呼んで残りを書き直す |
| 「完了しました」で打ち切る | 残ったサブタスクを意識した状態で進む |
両者の差は 「外部にメモがあるかどうか」 だ。メモがあれば、現実とのズレを反映して進める。なければ、ズレに呑まれて脇道に消える。
私は最初、Plan モードは「面倒な確認ステップ」だと思っていた。早く動かしたいのに、なぜわざわざ計画を読まされるのかと。 ところが何度も使っているうちに、計画フェーズで提示された TodoWrite のリストを眺める数十秒が、実行中に発覚する大事故を防ぐ最大の保険 だと分かってきた。
計画を見て「ここ違うな」と思った瞬間に直せる。実行が始まってから直すのは、コードがすでに書き換わっているぶん、戻すコストが高い。
これは余談だが、人間のチーム開発の 設計レビュー や PR テンプレート が機能するのと同じ理屈だと思う。 書いてからレビューするより、書く前にレビューしたほうが、結局は速い。
7.7 この章の振り返り
- agentic loop は「次の一手」しか考えない。大きなタスクで迷子になるのはそのため
- 解決策は 計画と実行を分離する こと。Claude Code は二段構えで実装している
- Plan モード は実行ツールを封じて、計画だけ立てさせるモード
- TodoWrite はサブタスクのリストを外部に保存する道具。実行中の現在地を見失わない
- LLM 自身に計画を書かせると、コンテキストに乗る・自己レビューが効く・全体俯瞰が手に入る
- 計画は完璧でなくていい。実装中に書き換える前提で運用する
この章で読めるようになるツイート / ブログ
- 「大きなタスクは Plan モードで一回挟まないと、絶対に途中で逸れる」 → 計画と実行の分離が大規模タスクで効く理由が、構造として読める
- 「TodoWrite が伸びすぎてコンテキストを食ってる、もう少し粗く刻んだほうがよさそう」 → サブタスクの粒度設計がエージェント運用の暗黙のチューニングポイントだと分かる
- 「Claude が自分で TODO 書き直してくれた、人間より計画修正が早い」 → 計画を動的に書き換える運用前提が、エージェントの長所として効いていると読める
次章は、計画というテーマと地続きの 記憶 の話に進む。
セッションを閉じたら消える会話の記憶と、リポジトリに住み続けるプロジェクト記憶、そして PC に張り付くユーザー記憶 ── Claude Code が持つ三層の記憶構造を、CLAUDE.md から腑に落としていく。