第9章: サブエージェント ─ コンテキストを分裂させる
ある朝、こんな指示を Claude Code に出してみる。
「この monorepo の 12 個のパッケージを順に調べて、依存関係の地図を作って」
しばらくして戻ってくると、最初の方のパッケージの分析は丁寧だが、後半に進むにつれて記述がやせ細っている。 最後にはこんな弁解が混じる ── 「context が長くなったので、残りは要約で済ませます」。
調査の品質が、残りトークン数の関数になっている。 人間がやれば、調べる対象ごとに新しいノートを開くだろう。 エージェントも同じことができる ── それが本章の主役、サブエージェント だ。
9.1 そもそも、なぜ「一人で全部やる」と詰まるのか
第4章で見たとおり、LLM の context window は有限だ。 入力 + 出力 + これまでの会話 + ツール結果が、すべて一つの帯に詰め込まれる。
長いタスクで何が起きるか:
- 序盤の調査結果が、終盤のコード生成のときも まだ context に居座る
- ツール呼び出しが増えるほど、観測結果 (Bash 出力、ファイル中身) が 膨らみ続ける
- 8 万トークン、16 万トークン ── どんなに広いウィンドウでもいずれ限界が来る
- 限界の手前ですでに context rot (第4章 context rot の節で扱った現象) が起きる
長いタスクの最大の敵は「賢さ不足」ではない。“見ているものの多さ” だ。
人間でも、机の上に資料を 100 件積み上げた状態で意思決定はできない。 エージェントの限界も、ほぼ同じ場所に来る。
ここで素直に思いつくのが、こうだ:
「調査は別の Claude に任せて、結論だけ受け取れば、こっちの机は散らからない」
これがサブエージェントの動機だ。
9.2 サブエージェントの正体 ── 新しいコンテキストで動く別の Claude
サブエージェントは、難しい言葉でいうと「新しい LLM セッションを立ち上げ、別のシステムプロンプトと別のコンテキストで動かす仕組み」だ。
平たくいうと:
- 親の会話履歴は 一切渡さない
- ゼロから始まる 新しい context window を持つ
- 指示文 (タスク) と、必要なら少しの参考情報だけ受け取る
- 自分の中で think → act → observe を回す
- 終わったら 最終結果のテキストだけ を親に返す
サブエージェント (sub-agent)親エージェントから起動される、別コンテキストの Claude。親の会話履歴を引き継がず、ゼロから始まる新しいセッションを持ち、タスクを終えると 結論のテキストだけ を親に返す。親はサブの内部で起きたことを直接見ない。
ここで重要な誤解を一つ潰しておく。
サブエージェントは 別プロセス・別マシン で動いているわけではない。 親のループから見れば、サブエージェントは 「Task」という名前のツールを呼んだだけ だ。
ここで道具立てを一つ補足しておく。Claude Code には Task という名前のツール ── サブエージェント起動専用のツール があらかじめ用意されている (第6章のツール一覧でも顔を出した)。親はこの Task ツールを呼ぶことで、新しい Claude セッションを起動する。
つまり構造は単純で、第2章の function calling と何も変わらない:
- 親 Claude が「
Taskツールを呼びたい (引数: 調査タスクの説明)」と出力する - ハーネスがそれを受け取り、内部で新しい Claude セッション を起動する
- そのセッションが独立に think → act → observe を回す
- 結果テキストがハーネス経由で親に 「ツール実行結果」として 渡る
- 親はそれを観測して、続きを考える
サブエージェントは「魔法の並列処理」ではなく、親の agentic loop における一つの ToolCall に過ぎない。 特殊なのは、その ToolCall の中身が「ファイルを読む」ではなく「別の Claude を一回まるごと走らせる」ことだけ。
このシンプルさが、Claude Code の設計の良さでもある。
9.3 なぜ「コンテキストを分裂させる」と効くのか
サブエージェントの真価は、親の context を太らせない ことにある。
親の机の上に積まれるのは、サブが返した 最終結論のテキスト 1 本だけ。 サブが内部で 30 回ツールを呼んでいようと、20 ファイル読んでいようと、親の目には入らない。
机の比喩に戻ると、こうなる:
| 一人でやる場合 | サブエージェントに分ける場合 |
|---|---|
| 親の机に資料が 12 パッケージぶん積み上がる | 親の机には「12 件の要約レポート」だけ |
| 後半にいくほど序盤の資料に圧迫される | サブはそれぞれ自分の机を持つので干渉なし |
| 残りトークン量で品質が落ちる | サブごとに新品の context window |
これが context isolation の効能だ。
context isolation親と子のコンテキストが完全に分離されていること。子の中の試行錯誤・失敗・大量のツール出力が、親の context window を圧迫しない。サブエージェントの最大の利点。
9.4 並列起動 ── 1 メッセージで複数 Task
サブエージェントの嬉しさは context 分離だけではない。
第2章で見たように、LLM は 1 回の応答で複数のツール呼び出しを並べる ことができる。 これをサブエージェント起動に応用すると、こうなる:
親 Claude の 1 メッセージに
Task(packages/a 調査)、Task(packages/b 調査)、Task(packages/c 調査)の三つを並べる → ハーネスは三つの Claude セッションを 本当に並行起動 する → 結果が揃ったら、まとめて親に戻す
シーケンシャルに「a を調べる → 終わったら b → 終わったら c」と回すより、所要時間がほぼ 1/N になる (ネットワーク・API レート制限の範囲で)。
複数のドキュメントから情報を集める、複数のファイルに同じパターン修正を入れる、複数のテスト戦略を比較する ── これらは並列サブエージェントの典型的な出番だ。
逆に 「A の結果を見てから B を決める」 ような直列依存があるタスクは、並列にしても意味がない。設計するときは「依存関係があるか」を最初に問う。
9.5 専門エージェント ── 役割ごとに違う Claude を持つ
ここまでは「同じ Claude を分身させる」話だった。 もう一歩進むと、役割ごとに別の system prompt と別の道具セット を渡したくなる。
たとえば:
| 専門エージェント | 役割 | 道具セット (例) |
|---|---|---|
| code-reviewer | コード変更の品質と安全性をレビュー | Read、Grep、Glob (書き込み禁止 ── 詳しくは次章 permissions で) |
| explorer | コードベースを探索して構造を地図化 | Read、Grep、Glob、Bash (読み取りのみ) |
| researcher | Web や社内ドキュメントから情報収集 | WebFetch、WebSearch |
| test-runner | テストを書いて走らせる | Read、Write、Edit、Bash |
それぞれに専用の system prompt を書いておけば、親は呼ぶときに 「code-reviewer でこの変更を見て」 と一言指示すればよい。
サブの中の Claude は、その役だけの心構えと道具 で考える。
これは人間のチームに似ている。 PM が全工程を一人でやる代わりに、レビュアー・調査担当・実装担当 に分ける ── 役の境界と道具の境界を明確にすると、それぞれが自分の仕事に集中できる。
エージェントの世界でも同じ原理が効く。「全部できる万能 Claude」より、「役を絞った専門 Claude」のほうが個別タスクでは強い ことが多い。
専門エージェントの定義は、ユーザー側の設定ファイル (詳細は第Ⅱ部「コマンド: 拡張機能」の /agents で扱う) や、プロジェクトの .claude/agents/ 配下に書いて共有できる。
9.6 リスク ── 親はサブの中で何が起きたか分からない
サブエージェントは万能の道具ではない。最大のリスクは 透明性の喪失 だ。
サブの中で:
- どんな仮説を立てて捨てたか
- 何回失敗してリトライしたか
- どのファイルをどんな順で読んだか
- 途中で道具の使い方を間違えたか
これらは、親には 基本的に見えない。返ってくるのは結論テキスト一本だけだから。
落とし穴サブエージェントは「親のデバッグ性を犠牲にして、context の節約と並列性を買う」トレードオフだ。
うまく仕事した時は嬉しい。だが結果が変だった時、原因究明は格段に難しくなる。 特に「サブが幻覚を含む結論を返し、親がそれを信じて次の手を打つ」と、エラーは見えない場所で連鎖する。
実務上の対策は、こうなる:
- タスクの境界を明確に渡す ── 曖昧な指示はサブの中で迷子になる
- 戻り値のフォーマットを指定する ── 「JSON で
{found: [...], missing: [...]}を返せ」のように - 重要な変更はサブに任せない ── 「探索・調査・レビュー」はサブ向き、「最終的な書き込み」は親で
- 失敗を疑えるよう、結論だけでなく根拠の引用も求める
これは第10章 (権限とブラスト半径) の話と地続きで、取り返しのつかない操作はサブに任せない という原則につながる。
9.7 この章の振り返り
- 長いタスクで品質が落ちる主因は、context window の圧迫 と context rot
- サブエージェントは 新しい context で動く別の Claude。親には結論だけ返る
- 構造的には「Task という名前の ToolCall」に過ぎず、特別な並列処理機構ではない
- context isolation によって、親の机を散らかさずに大量の作業ができる
- 1 メッセージに複数の Task を並べれば 並列起動 され、所要時間は約 1/N
- 役割ごとに 専門エージェント (code-reviewer、explorer 等) を定義できる
- 最大のリスクは 透明性の喪失 ── サブの中の試行錯誤は親に見えない
この章で読めるようになるツイート / ブログ
- 「
code-reviewerサブエージェントに常駐させて、main agent はコード書きに集中させてる」 → 役割分離。レビューは別 context・別道具セットで、親の机を圧迫しない設計、と読める - 「並列ワークツリーで 4 本同時に走らせたら一気に終わった」 → 1 メッセージで複数 Task を並べた並列サブエージェントが、所要時間を約 1/4 に削ったケース
- 「サブエージェントに任せたら全然違う結論が返ってきた、何があったか分からない」 → context isolation の裏返し。透明性の喪失 という代表的な落とし穴
- 「親 agent の context rot を避けるため、調査系は全部 sub に投げてる」 → 本章の動機そのもの。長文 ToolCall を sub に閉じ込めて親を軽く保つ運用
次章では、サブエージェントを含むすべてのエージェントが直面する別の問題に進む ── 「rm -rf を実行しようとした時、誰が止めるのか?」。
取り返しのつかない操作と権限の話、permissions の章だ。