基礎を習得したエンジニアから最もよく聞かれる質問は「サブエージェントとは何ですか?」ではない。「どのパターンをいつ使うか、そしてオーバーヘッドが割に合わないのはどんな場合か?」だ。この記事はその問いに答える。
当サイトではすでに サブエージェントのベストプラクティス(英語)と Agent Teams の実践ガイド(英語)を公開している。本記事はその繰り返しではない。それらの上位レイヤー——設計の判断軸、コストの実態、そして実際にシステムを動かして初めて見えてくる障害パターン——を扱う。
マルチエージェントシステムを設計・評価していて、今日具体的な設計判断が必要なエンジニアはここから始めてほしい。
根本的な違い:各メカニズムは何のためにあるか
判断フレームワークの前に、この区別を明確にしておく。
サブエージェント(Task ツールや AGENTS.md 委譲で呼び出す)は、コンテキスト分離メカニズムだ。主目的は並列化ではなく、ひとつのタスクに独自のフレッシュなコンテキストウィンドウを与えることにある。それにより、オーケストレーターのセッションを汚染せず、かつ汚染されない状態で作業を完遂できる。
Agent Teams は協調メカニズムだ。目的は、git ベースのタスク・クレームとブランチマージを通じて自己組織化する複数の独立セッションに、作業を分散させることにある。並列化は協調の副作用であって、それ自体が目的ではない。
この区別には実用的な結論がある。サブエージェントは逐次・非並列なワークフローで使っても価値がある——速度が不要でも、分離自体に意味があるからだ。Agent Teams は、セットアップコストに見合う真の並列性がある場合にのみ価値を発揮する。
サブエージェントを「貧者の並列化」として扱い、Agent Teams を「高度なサブエージェント」として扱うと、速くも綺麗でもないアーキテクチャになる。
判断マトリクス
マルチエージェントパターンを採用する前に、このマトリクスで確認する。各軸は実際の設計制約を表す。
| 制約 | サブエージェント寄り | Agent Teams 寄り | シングルエージェント寄り |
|---|---|---|---|
| タスク粒度 | 明確な I/O を持つ単一タスク | 似たサイズのタスクが多数、並列ワークロード | 1 つのタスク、扱いやすい規模 |
| コンテキスト依存 | 自己完結 or 制御されたハンドオフで足りる | タスクがほぼ独立している | 全体通して共有コンテキストが必要 |
| 並列化の価値 | 低〜中(逐次でも問題ない) | 高(実際の壁時計削減効果がある) | 不問 |
| 状態共有 | 分離 or 読み取り専用の共有状態 | ファイルシステムで分離可能(異なるモジュール/ディレクトリ) | 全体を通じた共有可変状態 |
| コスト許容度 | 中程度のオーバーヘッドは許容 | 高い並列トークン消費を許容 | コスト最小化が優先 |
| エラー耐性 | 定義済みフォールバックで部分的失敗を許容 | 独立タスクの失敗がブランチに隔離される | 単一失敗 = タスク全体が失敗 |
| 決定論的要件 | 予測可能な I/O が期待される | ある程度の出力のばらつきは許容 | 高い決定論性が必要 |
| CLAUDE.md の成熟度 | 問わない | 構造化された CLAUDE.md が必須 | 重要でない |
このマトリクスは傾向を示すものであり、答えではない。3 軸で「Agent Teams」、2 軸で「サブエージェント」が示唆される場合でも、最終判断は人間がする。マトリクスは解決すべき緊張関係を浮き彫りにする。
判断を絞り込む 2 つの問い
時間が限られているときは、この 2 つだけ問えばいい:
- 作業をファイルまたはモジュール境界で分割できるか? Yes で 3 チャンク以上あれば Agent Teams の検討に値する。No ならサブエージェントかシングルエージェント。
- 正確な実行順序が必要か? 全体を通じて Yes なら逐次サブエージェント。一部のステップで No なら並列サブエージェントか Agent Teams。
パターンカタログ
シンプルなものから複雑なものへ、7 つのパターンを示す。各パターンには実際のユースケース、協調モデル、コードスケッチ、コスト/複雑さのトレードオフを含む。
パターン 1:シングルサブエージェント(TaskTool 委譲)
使いどき: メインセッションで実行すると不釣り合いなコンテキストを消費する単一タスク、またはオーケストレーターの蓄積された状態なしにクリーンな環境で実行するメリットがあるタスク。
構造: オーケストレーター → 1 つのサブエージェント → 結果を返却 → オーケストレーター継続。
# CLAUDE.md またはインラインプロンプト
## doc-generator
TypeScript ソースファイルから API ドキュメントを生成する。
### Input
JSON オブジェクト:
- files: string[] — ドキュメント化する .ts ファイルのリスト
- output_dir: string — 出力先ディレクトリ
- format: "markdown" | "jsdoc"
### Output
- input ファイルごとに 1 つの .md または .jsdoc ファイルを output_dir に書き出す
- 返却値: { status: "done" | "failed", files_written: string[], errors: string[] }
### Constraints
- ソースファイルの読み取りのみ。変更禁止
- 1 回の呼び出しで最大 30 ファイル
- パースできないファイルはエラーをログに記録して続行 — 停止しない
トークンプロファイル: サブエージェントのタスクに合わせた 1 追加コンテキストウィンドウ。メインセッションは元のコンテキスト状態を維持する。純オーバーヘッド:協調プロンプト(約 200〜500 トークン)+サブエージェントの返却内容。
破綻するポイント: サブエージェントのスコープクリープ。タスクの説明がオープンエンドな判断を許容していると、サブエージェントが意図以上の作業をこなし、オーケストレーターのコンテキストを圧迫する巨大な結果を返すことがある。常に明示的なスコープ制限を設ける。
パターン 2:逐次サブエージェント
使いどき: ステップ N がステップ N-1 の出力に依存するパイプラインで、各ステップが独自の分離されたコンテキストから恩恵を受ける場合。
構造: オーケストレーター → サブエージェント A → ハンドオフ → サブエージェント B → ハンドオフ → サブエージェント C → 最終結果。
# 擬似コード:逐次パイプライン オーケストレーション
async def run_pipeline(source_dir: str) -> dict:
# ステップ 1: 分析
analysis = await invoke_subagent(
agent="codebase-analyzer",
input={"dir": source_dir, "depth": "deep-dive"}
)
if analysis["status"] == "failed":
return {"status": "failed", "stage": "analysis", "reason": analysis["reason"]}
# ステップ 2: リファクタ計画(分析出力を使用)
plan = await invoke_subagent(
agent="refactor-planner",
input={
"analysis": analysis["findings"],
"constraints": {"max_changes_per_file": 50, "preserve_api": True}
}
)
# ステップ 3: 実装(計画を使用)
result = await invoke_subagent(
agent="refactor-implementer",
input={"plan": plan["tasks"], "verification_cmd": "npm test"}
)
return result
ハンドオフの規律が最も重要な変数だ。 各ステップは前ステップの出力の構造化サマリーだけを受け取る——生の出力ではない。ステップ A の 3,000 語の生出力をそのままステップ B のコンテキストに流し込むと、トークンを浪費し焦点が散漫になる。ハンドオフ時に積極的に要約する。
トークンプロファイル: N 個の独立したコンテキストウィンドウ。ステップ A が 1,500 トークンの出力を生成し、それをステップ B が 200 トークンの構造化サマリーとして受け取ると、1 ハンドオフあたり 1,300 トークンの節約になる。3 ステップのパイプラインではこれが積み重なる。
破綻するポイント: エラーの伝播。ステップ A の出力に微妙なエラーが含まれていると、ステップ B と C はそのエラーの上に積み上げる。ステップ間に明示的な検証チェックポイントを設ける。
パターン 3:並列サブエージェント(ファンアウト / ファンイン)
使いどき: それぞれが集中したコンテキストを必要とする複数の独立タスクで、壁時計時間が重要な場合。
構造: オーケストレーターが N 個のサブエージェントに同時にファンアウト → 全完了を待機 → アグリゲーターにファンイン。
import asyncio
async def parallel_analysis(repo_dirs: list[str]) -> dict:
# ファンアウト:サブエージェントを同時起動
tasks = [
invoke_subagent(
agent="security-reviewer",
input={"dir": d, "output": f"review-output/security-{i}.md"}
)
for i, d in enumerate(repo_dirs)
]
results = await asyncio.gather(*tasks, return_exceptions=True)
# ファンイン:集約
successful = [r for r in results if isinstance(r, dict) and r["status"] == "done"]
failed = [r for r in results if isinstance(r, Exception) or r.get("status") == "failed"]
aggregated = await invoke_subagent(
agent="findings-aggregator",
input={
"reports": [r["output_path"] for r in successful],
"failure_count": len(failed)
}
)
return aggregated
アグリゲーターサブエージェントは省略不可だ。 これがないとメインセッションが N 個の結果をすべて取り込み、コンテキストが比例的に増大する。アグリゲーターサブエージェントは N 個の出力を受け取り、1 つの構造化サマリーを返す——何本の並列ブランチを走らせても、メインセッションのコンテキストは一定のままだ。
トークンプロファイル: N 個の並列コンテキストウィンドウ。総トークン消費はおおよそ N ×(タスクあたりのトークン数)。壁時計時間は sum(個別タスク時間) の代わりに max(個別タスク時間) になる——これが並列化の恩恵だ。コストは現実のものとして存在する。5 つの並列サブエージェントを走らせると、同じ総作業量を逐次実行した場合の約 5 倍のコストがかかる。ファンアウトに踏み切る前にこれを考慮する。
破綻するポイント: 「並列 = 安い」という誤解。ファンアウトは時間を削減する。トークンは削減しない。ボトルネックがレイテンシーではなくコストなら、タスクが独立していても逐次の方が良い場合がある。
パターン 4:Agent Teams(マルチセッション並列)
使いどき: ファイルまたはモジュール境界でタスクを定義できる大規模な作業で、各タスクが実質的な開発作業(単なるレスポンスではなく)を必要とし、割り当てをマイクロマネジメントせずにチームに自己調整させたい場合。
構造: 人間がゴールとチームサイズを説明 → Claude Code が N 個のワークツリーを作成し、各エージェントが共有タスクリストからタスクをクレーム → ブランチにコミット → 統合ブランチへの継続的マージ。
# 実験的機能を有効化
export CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1
4 人のチームメートで、/src/api/ 内のすべての REST エンドポイントを
Express から Hono に移行するエージェントチームを作成してほしい。
チームメートごとのスコープ:
- チームメート 1: /src/api/users/ と /src/api/auth/
- チームメート 2: /src/api/products/ と /src/api/orders/
- チームメート 3: /src/api/payments/ と /src/api/webhooks/
- チームメート 4: /src/api/admin/ と /src/api/middleware/ 内の共有ミドルウェア全体
各チームメートは:
1. 担当スコープ内の全ルートを Hono 構文に移行する
2. cd src/api && npm test -- --scope=<担当ディレクトリ> を実行する
3. テスト失敗があればマージ前に修正する
4. 担当スコープ外のファイルには触れない
統合順序: チームメート 4(共有ミドルウェア)が完了してマージした後に他がマージする。
並列サブエージェントとの主な違い: Agent Teams のエージェントはタスク完了後も持続する。結果を返した後にシャットダウンしない——次の利用可能なタスクをクレームする。これにより、多数の類似タスク(エンドポイント移行 20+ など)を持つ大規模ワークロードで、新しいサブエージェントをスポーンしてコンテキスト化するたびのオーバーヘッドが積み重なる問題を回避できる。
トークンプロファイル: 各エージェントが独立したフルセッションを実行する。4 エージェントのチームが各 30 分実行すると、同じ作業を逐次実行する 30 分のシングルセッションの約 4 倍のトークンを消費する。壁時計時間は約 1/4 に短縮されるが、コストは短縮されない。このトレードオフは時間短縮がコスト増を上回る場合(デッドラインプレッシャー、人間が結果を待っている)にのみ有利になる。
破綻するポイント: 共有可変状態。3 つのエージェントが全員 config.ts を変更する必要がある場合、またはデータベースマイグレーションを実行する必要がある場合、それは独立したタスクではない——協調の問題だ。それらのステップは明示的にシリアライズするか、チーム起動前に処理する。
パターン 5:ハイブリッド — Agent Teams 内の TaskTool
使いどき: バルクの並列作業に Agent Teams を使い、個々のエージェントが特定のフェーズでより深い分離が有益な場合に自身のサブタスクを TaskTool で委譲する。
構造: Agent Teams が N 個の並列セッションを設定 → 各チームメートが自身の集中サブタスクに TaskTool を使用 → 結果がマージされる。
## AGENTS.md 内(各チームメートが読み込む)
## subtask-doc-writer
リファクタリング完了後に単一モジュールの API ドキュメントを書く。
呼び出しタイミング: リファクタが完了しテストがパスしたとき。
### Input
- module_dir: モジュールディレクトリのパス
- style: "openapi" | "markdown"
### Output
- docs/<module_dir>/README.md にドキュメントを書き出す
- 返却値: { status, words_written }
### Constraints
- module_dir への読み取り専用アクセス(コードの変更なし)
- 最大出力 2,000 語
このパターンが存在する理由: Agent Teams セッション内のチームメートは独自のコンテキストウィンドウを持ち、作業とともに成長する。よく定義されたサブタスク(ドキュメント作成、検証、レポート作成)を TaskTool 呼び出しにオフロードすることで、チームメートのコンテキストをプライマリな作業に集中させ、長時間実行セッションでのコンテキスト枯渇を防げる。
トークンプロファイル: Agent Teams の基本コスト × N + 各チームメート内のサブタスクコスト。カタログ中で最もコストが高いパターン。作業が本当にチームのセットアップオーバーヘッドと各チームメート内のサブエージェントオーバーヘッドの両方を正当化するほど大きい場合に使う。
パターン 6:ステートレスマイクロエージェントプール
使いどき: 多数の入力に対して繰り返し呼び出される、よく定義されたステートレス操作——検証、分類、抽出、変換。
構造: オーケストレーターがキューを維持 → オンデマンドまたはバッチでサブエージェントをスポーン → 結果を収集 → 呼び出し間で状態は持続しない。
# バッチ検証パターン
async def validate_all(files: list[str], batch_size: int = 10) -> dict:
results = {}
for batch in chunked(files, batch_size):
batch_results = await asyncio.gather(*[
invoke_subagent(
agent="schema-validator",
input={"file": f, "schema": "product-v2.json"}
)
for f in batch
])
for f, r in zip(batch, batch_results):
results[f] = r
return {
"valid": [f for f, r in results.items() if r["valid"]],
"invalid": [(f, r["errors"]) for f, r in results.items() if not r["valid"]]
}
これはカタログ中で最もトークン効率の良いマルチエージェントパターンだ。 エージェントがステートレスでタスクが厳密に境界されているため、各呼び出しは小規模だ。オーバーヘッドは蓄積されたコンテキストではなく I/O にのみ比例する。
破綻するポイント: 「ステートレス」が嘘のとき。マイクロエージェントが正しく機能するために以前の呼び出しのコンテキストを実際に必要とする場合、それはステートレスではない——そして、そのように扱うと一貫性のない結果を生む。状態を入力に明示する。
パターン 7:ルーターとしてのオーケストレーター
使いどき: 適切なサブエージェントが最初に入力を分類することに依存する、マルチドメインタスク。オーケストレーターがルーティングし、サブエージェントが実行し、結果が集約される。
構造: オーケストレーターが多様な入力を受け取る → 各入力を分類する → ドメイン固有のサブエージェントにルーティングする → 出力を収集・統合する。
async def route_and_execute(tasks: list[dict]) -> list[dict]:
# フェーズ 1: 全タスクを分類(シングルサブエージェント)
classified = await invoke_subagent(
agent="task-classifier",
input={"tasks": tasks}
# 返却値: [{task, agent_type: "security"|"perf"|"api"|"data"}]
)
# フェーズ 2: エージェントタイプでグループ化し、並列グループで実行
groups = group_by(classified["tasks"], key="agent_type")
group_results = await asyncio.gather(*[
invoke_subagent(agent=agent_type, input={"tasks": group})
for agent_type, group in groups.items()
])
return flatten(group_results)
分類ステップが核心だ。 明示的なルーティングなしに、全入力タイプを自身で処理しようとするオーケストレーターは、肥大化した CLAUDE.md(全ドメインをカバーしようとする)を書くか、汎用的な出力を生成するかのいずれかになる。専用の分類器 + ドメインスペシャリストによる組み合わせは、よりクリーンなコンテキストでより正確な結果を生む。
コストとトークン分析
多くのガイドが省略する部分がここだ。実際の数値が判断を変える。
ベースライン計測値
以下の計測値は当サイト自身のワークロード(Claude Code Max 上の Claude Sonnet 4.5)から取得している。厳密なベンチマークではなく方向性を示すものだ——実際の結果はタスクの複雑さ、CLAUDE.md のサイズ、出力の冗長性によって変わる。
| パターン | 相対トークンコスト | 壁時計 vs 逐次 | 採用のしきい値 |
|---|---|---|---|
| シングルサブエージェント | 1.1〜1.3× | 同等(逐次) | 分離の恩恵がある 500 トークン超の任意タスク |
| 逐次サブエージェント(3 ステップ) | 1.2〜1.5× | 同等 | 各ステップのコンテキスト節約がステップあたり 0.2× 超 |
| 並列サブエージェント(4 ファンアウト) | 3.8〜4.2× | 約 0.25×(4× 高速) | レイテンシー削減 > コスト増の場合 |
| Agent Teams(4 エージェント) | 3.5〜4.5× | 約 0.3×(3× 高速) | タスクが約 20 以上の並列化可能な作業単位 |
| ハイブリッド TaskTool+Teams | 5〜7× | 約 0.25× | 真に階層的な並列性を持つ大規模リポジトリ |
| ステートレスマイクロエージェントプール | 呼び出しあたり 1.05〜1.1× | 設定可能 | 繰り返しの変換が必要な場合は常に |
| ルーターとしてのオーケストレーター | 多様性によって 1.2〜2× | 並列に類似 | ドメイン特化が意味のある出力向上をもたらす場合 |
トークン効率の計算式
任意のマルチエージェント設計について、構築前に見積もる:
期待総トークン数 =
オーケストレーションオーバーヘッド # エージェント起動あたり約 200〜800 トークン
+ sum(エージェントあたりのコンテキストウィンドウ) # 各エージェントのフルコンテキスト
- コンテキスト分離による節約 # メインセッションに追加されないトークン
+ ハンドオフオーバーヘッド # エージェント間で受け渡される構造化サマリー
(コンテキスト分離節約 - オーケストレーションオーバーヘッド - ハンドオフオーバーヘッド) < 0
の場合:
このタスクにマルチエージェントはコスト効率が良くない。
おおざっぱな計算式だが、多くのエンジニアが省略する問いを強制する:コンテキストを実際に節約しているのか、それとも単に再配分しているだけか?
並列化がコストを正当化する場合
並列パターンの実際の計算は、トークンコストだけでなく機会コストに関するものだ:
- シングルエージェントの実行が 40 分かかり人間をブロックする場合、4 エージェントの並列実行が 12 分でトークンコストが 4 倍かかるとする——問いは、人間の 28 分の待機コストが何かだ。デプロイをブロックするコードレビューなら、並列化はほぼ常に勝る。デッドラインのないバックグラウンド処理なら、たいていの場合勝らない。
- Claude Code Max プランのコストはプラン制限内では定額だ。トークン効率は、プラン制限に近い場合や従量課金 API を使用している場合により重要になる。
障害モードの分類
すべてのマルチエージェントシステムには、シングルエージェントの障害とは異なる障害モードがある。この分類を知ることで、デバッグ困難な方法で失敗するシステムの構築を防げる。
F1: コンテキストブリード
内容: あるエージェントセッションの状態が別のセッションに漏れる——意図的にではなく、共有ファイル読み取り、環境変数、または CLAUDE.md に焼き込まれた暗黙の前提を通じて。
例: 2 つの並列エージェントが共にセッション開始時に config.yaml を読む。エージェント A がタスク中にそれを変更する。A の変更後に開始したが再読み込みしていないエージェント B が、変更前の状態に基づいて判断を下す。
予防: 共有可変リソースを操作するエージェントは、操作前に再読み込みしなければならない。AGENTS.md にこれを明示する。
F2: カスケーディング仕様エラー
内容: 仕様が不正確なサブエージェントが微妙なエラーを含む出力を生成する。パイプライン内の次のエージェントはそれを有効として受け入れ、その上に構築する。エラーがチェーンを通じて増幅する。
例: リサーチエージェントが、サードパーティライブラリをアクティブにメンテナンスされていると誤って分類した知見を返す(実際はされていない)。実装エージェントは、リサーチ出力を信頼してライブラリを統合する。テストエージェントはそのライブラリに対してテストを書く。3 つのエージェント全てが「成功」——エラーは本番環境まで見えない。
予防: パイプラインステージ間に検証チェックポイントを挿入する。次のステージに渡す前に、フォーマットと可能な限りセマンティクスを検証する。
F3: 並列書き込み競合(サイレントデータロス)
内容: 2 つの並列エージェントが同じ出力先に書き込む。2 番目の書き込みが最初のものを静かに上書きする。どちらのエージェントもエラーにならない——競合はエージェント自身の視点では見えない。
例: 4 つのエージェントが全員 output/results.json に書き込むファンアウト。各エージェントの書き込みはその視点では成功に見える。最終ファイルは最後のエージェントの出力だけを含む。
予防: エージェントごとにユニークな出力パスを使う(ファイル名にエージェント ID を含める)。ファンインステップで明示的に集約する。並列システムでは共有書き込みパスが安全だと仮定しない。
F4: パイプライン途中でのトークンバジェット枯渇
内容: 逐次パイプラインが途中でコンテキストバジェットを使い果たし、最後のエージェントの利用可能なコンテキストが切り詰められるかセッションが早期終了する。
例: ステップ 1 が 4,000 トークンの出力を生成し、ステップ 2 がそれを受け取ってさらに 3,000 トークンの出力を生成し、ステップ 3 が両方を統合する予定の 3 ステップパイプライン——しかしステップ 3 の時点でコンテキストウィンドウが 95% 使用済みで、エージェントが品質低下した出力を生成する。
予防: 設計時にコンテキストをバジェット化する。各ステージの期待出力サイズとハンドオフオーバーヘッドの合計を計算する。合計がコンテキスト制限に近づく場合、ハンドオフをより積極的に圧縮するか、パイプラインを別のオーケストレーション実行に分割する。
F5: タスククレームの競合状態
内容: Agent Teams で、ロックファイルプロトコルが完全にコミットする前に 2 つのエージェントが同じタスクを同時にクレームする。
例: 2 つのチームメートが共にタスクリストを確認し、両方とも task-7 がクレームされていないことを確認し、両方がクレームファイルの作成を開始する。ファイルシステムのタイミングによって、一方または両方がタスクを所有していると信じる可能性がある。結果:作業の重複、同じファイルでの潜在的な競合。
予防: タスクのクレームにアトミックなファイル操作を使う。推奨アプローチは排他書き込みでクレームファイルを作成することだ——ファイルが既に存在する場合、2 番目のエージェントは作成に失敗し次の利用可能なタスクに移る。
# アトミックなクレーム: ファイルが存在する場合は失敗(ln はほとんどのファイルシステムでアトミック)
ln /dev/null .tasks/claimed/task-7.lock 2>/dev/null || echo "already claimed, skipping"
F6: 長時間実行チームでのエージェントドリフト
内容: Agent Teams で、長時間実行するエージェントがコンテキストを蓄積し、セッションが成長するにつれて元のタスク仕様から徐々に逸脱する。
例: 大規模なリファクタを 45 分進めたエージェントが、エッジケースや自分が行った決定についての大量のコンテキストを蓄積しており、新しいサブタスクに対する動作がオリジナルの仕様から逸脱し始める。ローカルコンテキストがシステムの規約を上書きしているため、アーキテクチャの選択が矛盾したものになる。
予防: セッション開始時にエージェントが読む CLAUDE.md に重要な制約を明示的に再記述する。重要な制約(命名規約、変更禁止の境界、検証コマンド)はコンテキストが成長するにつれて希釈される初期タスク記述だけでなく、CLAUDE.md にも記載する。
F7: アグリゲーションのハルシネーション
内容: アグリゲーターサブエージェントが N 個の結果を統合する際、コンテキストプレッシャー下で複数のソースの知見を捏造または混同する。
例: 5 エージェントのリサーチチームが各自レポートを作成する。アグリゲーターが全 5 つを受け取り統一された分析を統合する。簡潔にするプレッシャー下で、レポート 3 の知見をレポート 1 のドメインに帰属させたり、どのレポートにも明示的に存在しない結論を創作したりする。
予防: アグリゲーター入力の各ソースに明確なラベルを付ける。統合した主張ごとにソースを引用することをアグリゲーターに要求する:"知見: X(ソース: report-2.md、セクション: 'パフォーマンス')。" ソース素材に対する検証が可能になる。
マルチエージェントを使わない場合
多くのアーキテクトが省略するこのセクションを省略するとコストがかかる。
複雑性税
すべてのマルチエージェントシステムはオーバーヘッドを追加する:維持すべきプロンプトが増え、対処すべき障害モードが増え、推論すべき協調ロジックが増え、トークン消費が増える。この税は現実のもので継続的にかかる。任意のマルチエージェントパターンにコミットする前に、期待される利益が複雑性税を上回らなければならない。
シングルエージェントの方が良いことを示すレッドフラグ:
タスクが全体を通じてコンテキスト依存だ。 各ステップが実際に前のステップが行ったこと全て——サマリーだけでなく、実際の決定と推論——を知る必要がある場合、コンテキスト分離は助けるより害をなす。構造化されたハンドオフのオーバーヘッドが節約を超える。
タスクが小さい。 サブエージェントのオーバーヘッドは、サブタスク自体が少なくとも数百トークンの実際の作業である場合に意味を持つ。完了に 50 トークンかかるタスクを委譲する場合、協調オーバーヘッドがタスク自体より大きい。
構造化された CLAUDE.md がない。 強力な CLAUDE.md なしの Agent Teams は、N × 高価なコンテキスト探索だ。CLAUDE.md がまだ良い状態でない場合、先にそれを修正する。不明確な指示の上にエージェントを追加しない。
障害モードがリカバリー不可能だ。 タスクの間違ったステップが取り消せない場合(メール送信、本番データ変更、レビューなしのリリースブランチへのコミット)、マルチエージェントは人間がエラーに気づく前に誤って進む方法を増やす。人間のチェックポイントを明示的に追加するか、明示的な確認プロンプトを持つシングルエージェントを使う。
タイトな出力の決定論性が必要だ。 マルチエージェントシステムはシングルエージェントよりも多くのバリアンスを生成する。同じ入力から確実に同じ出力が必要な場合、並列・チームパターンは非決定的な実行順序によりバリアンスを追加する。
「速く感じる」錯覚
4 つの並列エージェントを実行すると生産的に感じる。ダッシュボードがアクティビティを表示する。物事が起きている。この感覚は現実のものだが、誤解を招く:問いは物事が起きているかどうかではなく、集合的な出力品質とコストが、同じ作業を行う単一のよく仕様化されたエージェントより優れているかどうかだ。
探索的な作業、ブレインストーミング、多様なドメインをまたぐリサーチには、並列エージェントが本当に優れたパフォーマンスを発揮する——コンテキストウィンドウの多様性がより独立した知見を生み出すからだ。よく理解されたコードベースでの集中した実装作業には、強力な CLAUDE.md を持つシングルエージェントがチームを上回ることが多い——全作業にわたって首尾一貫したアーキテクチャの意図を維持できるからだ。
マルチエージェント版の方が優れているという結論を出す前に、出力とコストの両方を計測する。
FAQ
Q: 同じワークフローでサブエージェントと Agent Teams を混在させることはできますか?
できる。パターン 5(ハイブリッド)がなぜこれが正しい答えになることがあるかを示している。重要なのは、どのレイヤーがどの種類の作業を扱うかについて意図的であることだ。Agent Teams がバルクの並列実行を処理する。TaskTool サブエージェントが各チームメートのセッション内で集中した分離を処理する。
Q: タスクの分解が本当に並列化可能かどうかはどうすればわかりますか?
依存関係グラフを描く。各ノードがタスク、各エッジが依存関係だ。グラフが最後まで収束しない複数のブランチを持つ DAG(有向非循環グラフ)なら、真に並列化可能だ。すべてのノードが前のノードに依存しているなら逐次だ。グラフにサイクルがあるなら、タスク定義に問題がある。
Q: AGENTS.md はシングルエージェントワークフローを基本として機能させる前と後、どちらに書くべきですか?
後だ。まずシングルエージェントでワークフローを構築する。コンテキスト分離が役立つ具体的なポイント——エージェントの蓄積されたコンテキストが速度を落としたり、より悪い結果を生んだりしている場所——を特定する。そのポイントに対して AGENTS.md エントリを書く。投機的に AGENTS.md を書くと、使われない過剰設計の委譲が生まれる。
Q: サブエージェントを考慮すべき実用的なコンテキストウィンドウの制限は何ですか?
コンテキスト使用率が約 60〜70% 前後でシングルエージェントのパフォーマンスが目に見えて低下し始めることがわかっている。セッションがすでに処理したコンテキストを再読み込みするために意味のあるトークンを消費しているとき、またはモデルが以前の決定と矛盾し始めているときは、インラインで継続するのではなく、次の主要なタスクをサブエージェントに委譲する時期だ。
Q: Agent Teams は 2026 年時点で本番利用に耐えますか?
条件付きで本番利用に耐える。協調メカニズム(ワークツリー分離、タスククレーム、ブランチマージ)は実際のコードベースに対して十分安定している。実験的フラグは、呼び出し API とデフォルトの動作が Claude Code リリース間で変わる可能性を示すものであり、基礎となるメカニズムが壊れているという意味ではない。それに基づいて自動化を構築する場合は Claude Code バージョンを固定し、アップデート後に再テストする。
Q: Agent Teams で実用的な最大チームサイズは何人ですか?
実際には、3〜5 エージェントがほとんどの並列ワークロードをカバーする。5 を超えると、重複しないタスク境界の定義、競合の防止、進捗の監視の複雑さが並列化の利益を上回ることが多い。稀な例外は高度に規則化された作業(200 の同一エンドポイントの移行、500 の独立したファイルの処理)で、タスク境界が完全に機械的でエージェントの協調が最小限の場合だ。
本番コードベースのリアルな AGENTS.md ファイルは Prompt Shelf ルールギャラリーで閲覧できる。マルチエージェントシステムのコスト面については Claude Code コスト最適化ガイド(英語)を参照。