Claude Codeのエージェント設計パターン — 分割の判断基準と報告フォーマットの作り方
Claude Codeでサブエージェントに切り出すかどうかを決める3つの判断基準、代表的な4つの分担の型、構造化された報告を返させるプロンプト設計、避けたい分割をまとめます。
サブエージェントに切り出すかは3点で決まる
ある作業をサブエージェントへ切り出すべきかどうかは、独立性・コンテキスト量・検証可能性の3点を順に見れば判断できます。3つとも満たすなら切り出す価値があり、1つでも欠けるとメインで直接やったほうが速い、という関係になっています。
切り出す前に見る3点
独立性
他の作業の途中結果を必要としないかどうかです。サブエージェントは起動時に渡されたプロンプトだけを入力に動き、メインの会話履歴も他の子の状態も見えません(forkを除く。後述)。前段の出力を前提にする工程を並べると、整合が取れなくなります。直前の判断を踏まえて進めたい作業は、メインで直接やるほうが速くなります。
コンテキスト量
作業の過程で読み込む情報と、最終的に必要な情報の差です。50本のファイルを読んだ末に必要なのが3行の結論なら、差は大きく、切り出す価値があります。1ファイル読んで1つの値を取り出すだけなら差はほぼゼロで、起動のオーバーヘッドだけが乗ります。
検証可能性
返ってきた結果の正しさを、メイン側で判断できるかどうかです。「ファイルパスと行番号」「テストの合否」「該当件数」は、必要なら再確認できます。「このコードは読みやすいと思います」のような評価は、根拠が子のコンテキストの中にしか残りません。
3点のうち検証可能性は、後から効いてくる割に見落とされがちです。切り出すと決めたら、その時点で「何をどんな形で返させるか」まで一緒に決めておく。この順序が設計を安定させます。
定義ファイルの書き方はClaude Code Sub-agents完全ガイドにまとまっています。ここでは、作ると決めた後の設計判断に絞ります。
分担の型は4つに収れんする
実務で繰り返し現れる分担は、ほぼ次の4つに収まります。それぞれ切り出す理由が違うため、設計の力点も変わります。
| 型 | 切り出す理由 | 並列化 | 報告に求めるもの |
|---|---|---|---|
| 調査のfan-out | 切り出す理由読む量が多い | 並列化する | 報告に求めるもの事実とファイルパス |
| 多視点レビュー | 切り出す理由観点を混ぜたくない | 並列化する | 報告に求めるもの分類済みの指摘 |
| 大量変換 | 切り出す理由単調な繰り返し | 並列化条件付き | 報告に求めるもの処理件数と例外 |
| 検証の分離 | 切り出す理由ログが膨らむ | 並列化しない | 報告に求めるもの合否と失敗箇所 |
調査のfan-out(1つの依頼を複数の子へ枝分かれさせる形)は、独立した観点をそれぞれ別の子に投げる型です。読み取りしかしないため衝突の心配がなく、最も気軽に使えます。設計上の要点は観点の切り分けで、重なると同じファイルを複数の子が読み直す無駄が出ます。
多視点レビューは、1つの差分を観点ごとに別の子へ渡す型です。1体に「品質を確認して」と投げると観点が毎回ぶれますが、セキュリティ・互換性・可読性のように分けると、指摘の粒度が揃います。子は実装時の会話履歴を持たず、渡された差分だけを見ます。
大量変換は、同じ規則を多数のファイルへ適用する型です。書き込みを伴うので、担当ファイルが重ならないことの確認が前提になります。ファイル単位で綺麗に割れるなら並列化でき、割れないなら1体に順次処理させます。
検証の分離は、テストや実機確認のログをメインから隔離する型です。並列化の旨味は小さく、狙いはコンテキストの保護に絞られます。失敗したときだけ詳細が欲しくなる工程なので、報告は合否と失敗箇所に絞り、詳細が要るときだけメインから改めて実行すれば足ります。並列実行そのものの具体パターンはサブエージェント完全活用で扱っているので、ここでは触れません。
4つの型は排他ではなく、1つの作業の中で順に現れます。調査でfan-outし、実装で大量変換を回し、最後に多視点レビューと検証をかける。どの局面にいるかを意識すると、その時点で並列にしてよいかが自然に決まります。
報告フォーマットを決めると成果が安定する
サブエージェント運用でいちばん効くのに、いちばん省略されがちなのが報告フォーマットの指定です。指定しなければ、子はそれらしい散文を返しがちです。散文はメインで読み直す必要があり、複数体を束ねると形式の違いが統合の手間になります。
設計の考え方はシンプルです。メインが次の判断に使う情報だけを、機械的に読める形で返させます。具体的には次の3つを指示文に書き込みます。
- 返す項目(何を含めるか)
- 返さない項目(何を含めないか)
- 該当が0件のときの返し方
3つ目が抜けると、該当なしの場合にたとえば「調査しましたが見つかりませんでした。念のため周辺も確認したところ……」という長い弁明が返ってくることがあります。「該当なしとだけ返す」と一行足すだけで防げます。
事実収集に使う報告フォーマット
報告は次の表だけで返してください。前置き・総括・所感は不要です。
| ファイル:行 | 該当する記述 | 確度(確実/推定) |
- 推定の行には、なぜ推定なのかを「該当する記述」列に1文で書く
- 該当が0件なら「該当なし」とだけ返す確度の列を分けているのは、子が推測と事実を混ぜて返すのを防ぐためです。メイン側は「確実」の行をそのまま採用し、「推定」の行だけ再確認すればよくなります。確度を1列足すコストで、検証すべき対象が絞り込めます。
レビューに使う報告フォーマット
指摘は次の形式で、重要度順に並べてください。
[Must|Want|Nit] ファイル:行 — 指摘内容(1〜2文)
修正案(あれば1文)
- Must は「マージ前に直さないと壊れる」もののみ
- 指摘が0件なら「指摘なし」とだけ返す
- コード全体の要約は書かない3段階の定義を指示文の中で与えているのが要点です。Must・Want・Nitという言葉だけ渡すと、子ごとに閾値が変わります。「マージ前に直さないと壊れる」という判定条件を書いておけば、複数体のMustを横並びにしても意味が揃います。
変換作業に使う報告フォーマット
処理が終わったら次の3行だけ返してください。
処理件数: N件
スキップ: M件(理由ごとに件数)
要確認: ファイルパスの一覧(判断に迷った箇所のみ)
変更後のコードは貼らないでください。差分はメイン側で確認します。「変更後のコードは貼らない」は、大量変換では特に効きます。50ファイルを変換した子が全ファイルの差分を返してくると、コンテキストを節約するために切り出した意味が消えます。差分の確認はメイン側のgit diffで足ります。
報告フォーマットが効く理由
3つの例に共通するのは、報告が次の行動に直結する単位になっていることです。表の行はそのまま確認対象のリストになり、Mustの一覧はそのまま修正タスクになり、要確認のパスはそのまま目視対象になります。散文の報告は、読んでからこの変換を人間かメインエージェントが行う必要があり、その分だけ手数とコンテキストを消費します。
もう1つの効果は、子の振る舞いが安定することです。返す形が決まっていると、子は形式を満たすために必要な作業を逆算します。「ファイル:行」を必須項目にしておけば、メイン側は行番号から裏取りを始められます。
会話ごと引き継ぐforkは白紙の子と何が違うか
通常のサブエージェントは白紙から始まります。入力はClaudeが書いた依頼文だけで、独立性の判断もそれが前提でした。forkはこの前提を外した分身です。
白紙の子とforkの違い
通常のサブエージェント
会話履歴は渡りません。専用のシステムプロンプトとツール制限、モデルを定義ファイルで持たせられます。
fork
メインと同じシステムプロンプト・ツール・モデル・会話履歴を引き継ぎます。途中の呼び出しはメインに残らず、最終結果だけが返ります。
依頼文に書ききれないほど背景が長い作業や、同じ出発点から複数の方針を並列で試したい場面は、forkのほうが噛み合います。forkからさらにforkは作れません。書き込みを伴うときは、起動時にisolation: "worktree"を渡すと、編集が別のworktreeに書かれます。Claudeにforkを使わせたくないなら、permissions.denyにAgent(fork)を入れます。
ツール権限とモデルは責務から逆算する
サブエージェント定義ではtoolsでツールを制限でき、modelで使うモデルを指定できます。この2つは、責務を決めた後に逆算して埋める項目です。
toolsを指定すると、書かれていないツールは使えなくなります。調査専任ならRead・Grep・Globだけで足り、書き込み系を外しておけば、並列で何体走らせてもファイルが壊れる経路がありません。権限の制限は、注意深さではなく仕組みで衝突を防ぐ手段として働きます。逆に、必要なものを書き忘れると動かないため、責務に必要な最小集合を意識して展開します。
子がさらに別の子を起動できるかどうかにも、toolsが関わります。既定では、サブエージェントも別のサブエージェントを起動でき、メインの下に3階層までです。上限は環境変数CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTHで変えられ、2なら第2層まで、1なら入れ子なしになります。v2.1.217から218までは既定が1で、v2.1.219で3に引き上げられました。
読み取り専用のレビュー担当のように起動を止めたい子は、toolsにAgentを入れないか、disallowedToolsに入れます。
modelの選び方は、判断の性質で分かれます。
| 作業の性質 | 向くモデル帯 | 例 |
|---|---|---|
| 判定軸が明文化された機械的処理 | 向くモデル帯軽量モデル | 例該当箇所の抽出、形式変換 |
| 曖昧な基準での評価・採点 | 向くモデル帯上位モデル | 例独自性の判定、設計の妥当性 |
サブエージェントのモデルが決まる順番
- 1
呼び出しごとの model パラメータ
Claudeが個別の起動で渡した値が最優先です。
- 2
定義ファイルの model
inheritならメインの会話のモデルを使います。 - 3
環境変数 CLAUDE_CODE_SUBAGENT_MODEL
モデルのエイリアスかモデルIDで設定してあるときに使われます。
- 4
メインの会話のモデル
どれも無ければ、メインと同じモデルで動きます。
軽量モデルで済む作業を上位モデルに投げるとコストが乗り、逆に微妙な判断を軽量モデルに投げると精度が落ちます。前者は無駄で済みますが、後者は結果が信用できなくなるため影響が大きくなります。判定軸を指示文に書き切れたかどうかが、軽量モデルへ落とせるかの目安になります。
ほかにisolation(編集をgit worktreeへ隔離するか)、memory、maxTurnsといったフィールドも定義で指定できます。書き込みを伴う子にはisolation: worktreeを付けておくと、一時的なworktreeへ作業領域が切り替わり、複数体を並列にしてもファイルが踏み合いません。worktreeの分岐元は親セッションのHEADではなくデフォルトブランチで、子が何も変更しなければ自動で片付けられます。
maxTurnsに達した子の出力は「途中まで」の印が付いて返り(v2.1.246以降)、Claudeが続きを再開できます。メイン側は、打ち切られた報告を完了報告と取り違えずに済みます。
定義ファイルを作らずに試すなら、claude --agentsにJSONを渡します。v2.1.289のclaude --helpには、次の例が載っています。
claude --agents '{"reviewer": {"description": "Reviews code", "prompt": "You are a code reviewer"}}'--printと併用するときは、JSON本体の代わりにJSONを書いたファイルのパスも渡せます(対話セッションではパスは受け付けません)。名前が近いclaude agentsは、同じヘルプでは「Manage background agents」と説明されるバックグラウンドエージェントの管理コマンドです。
descriptionは呼ばれ方そのものを決める
定義ファイルに切り出したサブエージェントは、descriptionを根拠に選ばれます。Claudeは各エージェントの説明文を読んで「今この責務を呼ぶべきか」を判断するため、説明が抽象的だと、似た定義が複数あるときに選択がぶれます。呼ばれないエージェントは、中身がどれだけ丁寧でも動きません。積極的に呼ばせたいときは、説明に「use proactively」のような句を入れます。
説明文は短く保ちます。標準搭載を除く定義のdescriptionの合計が15,000トークンを超えると、起動時に合計トークン数つきの警告が出ます。定義は読み込まれるので、動かなくなるわけではありません。詳細はシステムプロンプト側に書けば、その子が動くときだけ読み込まれます。
書き分けのコツは、責務・入力・出力・観点数の4つを1文に詰めることです。
# 選択がぶれる書き方
description: コードをレビューします
# 判別できる書き方
description: 差分コードをセキュリティ・互換性・命名の3観点でレビューし、
指摘を Must / Want / Nit に分類して ファイル:行 付きで返す。
新規実装の設計相談には使わない。最後の一行のような否定形も効きます。「何に使わないか」を書いておくと、責務が近い定義との境界がはっきりし、誤って呼ばれる頻度が下がりやすくなります。定義を増やすほど、この境界の記述が重要になります。
ここまでの設計は、エージェント1体ごとの話です。複数体をどう束ね、どんな順序で走らせるかというメイン側の運用はオーケストレーター設計にまとめています。
切り出さないほうがよいケース
分割が裏目に出るパターンも、いくつか決まった形があります。
段階的に詰めていく作業は切り出しに向きません。「書いてみて、見て、次を決める」進め方は、判断のたびにメインへ戻る必要があり、投げて1通返す構造と噛み合いません。この種の作業をサブエージェントに渡すと、途中で分かれ道があっても、確認のためにメインへ戻ることができません。
責務が重なる子を並べるのも避けたいところです。「コードレビュー担当」と「品質チェック担当」のように説明が近い定義が複数あると、どちらを呼ぶかの選択がぶれます。サブエージェントはdescriptionを読んで選ばれるため、責務・入出力・観点が1文で判別できる粒度に書き分けます。名前が似ているだけで実質が同じなら、統合したほうが運用は安定します。
1〜2回のツール呼び出しで終わる作業も、切り出す価値がありません。ファイルを1つ読む、grepを1回かける、といった作業では、プロンプトを書く手間と起動のオーバーヘッドが本体を上回ります。
最後に、結果の正しさをメインで確かめられない作業です。冒頭の検証可能性がここに戻ってきます。「いい感じに整えておいて」のような依頼は、返ってきた報告が正しいかどうかを判断する材料がなく、結局メインで全部読み直すことになります。切り出す前に、報告を受け取った自分が何をもって合格と判断するかを1文で言えるか確かめておくと、この失敗は避けられます。
よくある質問
汎用エージェントと専用エージェントはどう使い分けますか
その責務を繰り返し使うかどうかが分かれ目です。一度きりの調査なら、汎用のサブエージェントに詳しいプロンプトを渡せば足ります。同じ観点のレビューを毎回走らせるなら、定義ファイルに切り出したほうがプロンプトを書き直す手間が消え、観点の揺れもなくなります。切り出す判断の全体像はClaude Code Sub-agents完全ガイドの早見表が参考になります。
報告フォーマットを厳しくすると情報が落ちませんか
落ちます。ただし落ちるのは、メインが次の判断に使わない情報です。想定外の発見を拾いたい場合は、フォーマットの最後に「上記に収まらない重要な発見があれば、最大3行で追記してよい」と逃げ道を1つだけ用意します。無制限の自由記述にしないことが要点です。
子に渡すプロンプトはどれくらい詳しく書くものですか
前提は省略せずに全部書きます。子はメインの会話履歴を見られない(forkを除く)ため、こちらが当然と思っている条件ほど抜けやすくなります。対象のファイルパス、すでに決まっている方針、触ってはいけない範囲、そして報告フォーマット。この4つが入っていれば、プロンプトが長くなっても手戻りより安く済みます。逆に「さっきの件で」「例のファイルを」といった指示語は、子には解決できません。
サブエージェントが期待と違う動きをするときは何を疑いますか
まずプロンプトに前提が書かれているかを確認します。メインで共有したはずの情報も、子には渡っていません。編集中のファイル、直前の調査結果、採用済みの設計判断は、毎回プロンプトへ明示的に含める必要があります。
次に疑うのは定義の読み込みです。descriptionの無いファイルは読み込まれず、maxTurnsやdisallowedToolsのようなフィールド名は表記が違うと、エラーなしで無視されます。toolsに書いた名前がどれもツールに解決できない場合は、通常は起動に失敗し、would be spawned with zero tools — refusingというエラーで名前つきで拒否されます。
まとめ
切り出すかどうかは独立性・コンテキスト量・検証可能性で決まり、返させる報告の形はその時点で一緒に決めておきます。入口には、読み取り専用の調査エージェントに表形式で返させる構成が扱いやすい範囲です。