はじめに:単一エージェントの限界
Claude Codeを日常的に使っていると、あるタイミングから出力品質が落ちる瞬間に気づきます。長い会話の中でコンテキストウィンドウが埋まっていき、モデルが「考えながら手を動かす」状態に陥るのです。
具体的には以下のような現象が起きます。
- 計画と実装が混在し、タスクの全体像を見失う
- 調査結果がコンテキストを圧迫し、肝心の実装フェーズで情報が薄まる
- 生成したコードを自分で評価すると「自画自賛」になりがちで、品質チェックが甘くなる
- コンテキストの残りが少なくなると、検証を省略して「たぶん動く」で終わらせようとする(いわゆる「コンテキスト不安」)
Anthropicのエンジニアリングチームはこの現象を context anxiety と名付け、自分たちのハーネス設計記事の中でも繰り返し言及しています。筆者が半年以上Claude Codeを日常業務に組み込んでみた肌感としても、単一エージェントで300〜400ターンを超えた頃からエージェントが「早く終わらせよう」として検証を省き、存在しない関数名を書いて押し切ろうとする挙動が明確に出始めます。
これは単一エージェントが「計画」「実装」「評価」を1つのコンテキストで全部やろうとしている構造的な問題です。人間のチーム開発でも、設計・実装・レビューを同一人物が一気にやると品質が下がるのと同じ構図で、計画のための思考と実装のための思考と評価のための思考が相互に干渉します。
なぜ「3エージェント分離」が生まれたのか
Anthropicのエンジニアリングブログを読むと、3エージェント分離という設計は最初からあったわけではなく、「単一エージェントをどこまで長時間走らせられるか」を徹底的に試した結果として追い込まれて生まれたものだと分かります。
最初期のハーネスは、Opus 4.5 1体にOS環境とgitを渡して、フルスタックアプリケーションを構築させるものでした。ベースラインの単体実行は20分・コスト9ドル程度で完走しますが、出来上がるアプリは一見動くものの、中核機能が壊れていたり、UIが不自然だったり、スタブ実装が本物の機能の顔をしていたりして、プロダクトとして使い物にならなかったと報告されています。
記事中には、単体実行の典型的な失敗として次のような事例が列挙されています。
- コア機能が壊れているのに表面上はエラーが出ない(静かに失敗する)
- ワークフローが硬直していて、人間のユーザーが直感的に使えない
- 機能が「スタブだけ実装」で終わっていて、ボタンを押しても何も起きない
- エッジケースがまったく考慮されていない
ここで興味深いのは、これらの失敗の多くが「コードの品質」というよりも「自己評価の品質」の問題だった、という分析です。Anthropicは次のように明言しています。
When asked to evaluate work they've produced, agents tend to respond by confidently praising the work—even when, to a human observer, the quality is obviously mediocre.
(エージェントに自分の作ったものを評価させると、人間から見れば明らかに凡庸な品質でも自信満々に褒めてしまう傾向がある)
そして決定打となったのが次の一文です。
Tuning a standalone evaluator to be skeptical turns out to be far more tractable than making a generator critical of its own work.
(独立した評価エージェントを懐疑的にチューニングする方が、生成エージェントに自分の仕事を批判的に見させるよりはるかに扱いやすい)
つまり「生成者に自己批判させる」というアプローチは、プロンプト工夫ではなかなか突破できない壁だった、という前提があります。3エージェント分離は、この壁を設計で回避するために選ばれた構造です。
Anthropic公式「計画・生成・評価」3エージェント設計
Anthropicは2025年末から2026年にかけて、長時間稼働エージェントのハーネス設計に関する一連の記事を公開しました。「Harness design for long-running application development」で紹介されたGAN(敵対的生成ネットワーク)にインスパイアされた3エージェント設計は、サブエージェント活用の実践的な指針になります。
3つのエージェントの役割
[ユーザー入力] → [Planner] → [Generator] ⇄ [Evaluator] → [成果物]
↑ |
└────── フィードバック ──────┘
1. Planner(計画エージェント)
ユーザーからの1〜4文の短い要件を受け取り、包括的なプロダクト仕様に展開します。ここで重要なのは「野心的なスコープを設定しつつ、細かい技術的詳細には踏み込まない」という設計思想です。Anthropicのチームは、Plannerの役割を product context and high level technical design rather than detailed technical implementation と表現しています。技術詳細を計画段階で詰めすぎると、下流でエラーが連鎖するためです。
Plannerの成果物はファイルとして書き出され、後続のエージェントはそのファイルを読んで作業します。これによりエージェント間の通信がメインスレッドのトークンを消費しません。ファイルは単なるメッセージ経路ではなく、「セッションをまたいで引き継ぐ共有記憶」としても機能します。
2. Generator(生成エージェント)
Plannerが作成した仕様に基づき、機能を1つずつスプリント形式で実装します。各スプリントの前にEvaluatorと「スプリント契約(sprint contract)」を結び、「何ができたら完了か」をテスト可能な基準まで事前に合意するのが特徴です。
契約の中身は次のような構造になります。
- このスプリントで実装する機能の一覧(ユーザーストーリー単位)
- 各機能の「動作確認の手順」(Playwrightで自動テストできる粒度)
- 完了と見なすための合否条件(数値や状態の期待値)
Generatorはgitでバージョン管理を行い、各機能の実装完了後にコミットします。これによりEvaluatorが git diff でレビューしやすくなり、問題があった場合のロールバックも容易になります。Anthropicの事例では、Generatorは React + Vite + FastAPI + SQLite/PostgreSQL を標準スタックとして採用しています。
3. Evaluator(評価エージェント)
Generatorが実装したコードを、実際にユーザーの視点でテストします。Anthropicの実装では Playwright MCP を使い、UIの動作確認、APIエンドポイントのテスト、データベースの状態検証まで行います。
評価基準は以下4軸で、基準を満たさない場合はフィードバックが戻り、再実装ループが回ります。
| 軸 | 見るポイント |
|---|---|
| Product depth | 機能が「スタブ」ではなく本物として成立しているか |
| Functionality | 全体のワークフローが一貫して動くか |
| Visual design | UIがユーザーに意味を伝えているか |
| Code quality | 保守性・可読性・構造は妥当か |
Evaluatorのフィードバックは、「良くない」といった抽象的な評価ではなく、具体的な現象として返されます。Anthropicが例示しているフィードバック文は次のようなものです。
Rectangle fill tool allows click-drag to fill a rectangular area with selected tile—FAIL — Tool only places tiles at drag start/end points instead.
(矩形塗りつぶしツールは選択タイルでドラッグ範囲を塗りつぶせるはず → FAIL → 実際にはドラッグの始点と終点にしかタイルが置かれない)
この具体性があるからこそ、Generatorは「どこが悪いか」ではなく「どこを直すか」に即座に着手できます。Anthropicは Opus 4.5 時代の実行で「solo 20分 $9 に対してフルハーネス 6時間 $200」とコスト差を明かしつつ、それでもハーネスを使う価値があったと述べています。Opus 4.6 世代ではスプリント分解の必要性が下がった一方、Evaluator自体の価値はむしろ上がり、「audio recording is still stub-only」「clip resize by edge drag not implemented」のような人間が見落としがちな欠落を拾い続けた、という報告があります。
なぜ3つなのか
「2つではだめか、4つならどうか」という疑問に、筆者なりの整理を加えておきます。
2分割(生成と評価)の構成も考えられます。ただしこれだけだと、生成エージェントが目の前のコードを書きながら頭の中で全体計画も維持しなければならず、結局は単一エージェントと同じコンテキスト圧迫問題を抱えたまま評価者だけが独立する形になります。計画を先に切り出すことで、Generatorは「この1機能だけ」に集中できます。
4分割(計画・設計・実装・評価)も試せますが、現行のClaude Codeはサブエージェントの入れ子呼び出しを禁止しており、オーケストレーション層の負担が急に重くなります。さらに「設計」と「計画」は実質的に同じ認知タスクで、モデルに分けさせてもトークンが2倍かかるだけで品質はほとんど変わらないというのが筆者の実感です。
結果として、「What を決める Planner」「How を決めて書く Generator」「動いているかを見る Evaluator」という3つに落ち着きます。それぞれの役割が人間の認知タスクとして独立しているため、分離のメリットがコストを上回ります。
なぜ評価を分離するのか
この設計の核心は「生成と評価の分離」にあります。Anthropicのブログでは次のように述べられています。
スタンドアロンの評価エージェントを懐疑的にチューニングする方が、生成エージェントに自分の仕事を批判的に見させるよりはるかに扱いやすい
自分で書いたコードのバグは人間でも見つけにくいものです。ここにはLLM特有の事情も重なります。生成エージェントのコンテキストには「自分がどういう意図でその行を書いたか」の痕跡が大量に残っており、評価のときもその意図バイアスを引きずってしまうのです。
評価を別プロセスに分離すると、Evaluatorの入力はコードと要件だけになり、書き手の意図は見えません。この「意図が見えない」という制約こそが、第三者視点の厳しさを再現しています。Anthropicも初期のEvaluatorが「問題を見つけておきながら、自分で大したことないと言いくるめて承認する」失敗をしたと書いていて、これを防ぐために評価者のプロンプトを「懐疑的に」寄せて繰り返し調整したと報告しています。
Claude CodeのAgent Toolの仕様と制約
ここからは、上記の3エージェント設計をClaude Codeで実装するための具体的な仕組みを見ていきます。
サブエージェントの基本構造
Claude Codeのサブエージェントは .claude/agents/ にMarkdownファイルとして定義します。YAMLフロントマターで設定を記述し、本文がそのままシステムプロンプトになります。
---
name: my-agent
description: このエージェントをいつ使うかの説明
tools: Read, Grep, Glob, Bash
model: sonnet
---
あなたは○○の専門家です。以下のルールに従って作業してください。
...
知っておくべき重要な制約
サブエージェントを効果的に使うために、以下の制約を理解しておく必要があります。
- サブエージェントはメインの会話コンテキストを見ることができない。受け取るのは自身のシステムプロンプトと、呼び出し時に渡されるタスク記述のみ
- サブエージェントは他のサブエージェントを起動できない(ネスト不可)
- 結果はサマリーとしてメインに返される。途中の思考過程やツール実行ログは返らない
- ビルトインのサブエージェント(Explore, Plan, general-purpose)が既に存在し、Claudeが状況に応じて自動的に使い分ける
なぜAgent Toolはコンテキストを共有しないのか
この仕様は初見では不便に感じますが、設計意図を知ると納得できます。もしサブエージェントがメインの会話をすべて読める設計だったとすると、次のような問題が起きます。
- サブエージェントが増えるたびにコンテキストが雪だるま式に膨らみ、長時間稼働でトークン消費が破綻する
- 「親の文脈」に引きずられて独立した評価や調査ができない
- キャッシュが効きにくくなり、レイテンシとコストが両方悪化する
つまり「共有しない」のではなく「共有させないことで独立した判断を担保している」のです。Anthropicの他記事でも、ファイルを通じた非同期通信を推奨する理由として、エージェント間の疎結合と再現性を挙げています。
この制約を前提にすると、3エージェントパターンにおけるファイル通信の必然性も理解できます。Plannerの成果物を .claude/plans/*.md に、Generatorの進捗を claude-progress.txt に、機能リストを feature_list.json に置くのは、単なる便利機能ではなく「コンテキスト汚染を防ぐ唯一の手段」だからです。JSONが選ばれるのもMarkdownより「不要な書き換え」が起きにくいためで、Anthropicも feature_list.json にステータスだけを書き換えさせる運用をしています。
効果的なプロンプト設計
サブエージェントがメインの会話を見られないという制約は、プロンプト設計に大きな影響を与えます。サブエージェントへの指示は「自己完結」していなければなりません。
悪い例:
さっき話した仕様に基づいてコードを書いて
良い例:
以下の仕様に基づいてユーザー認証APIを実装してください。
- エンドポイント: POST /api/auth/login
- 入力: { email: string, password: string }
- 出力: { token: string, expiresAt: string }
- バリデーション: emailは有効な形式、passwordは8文字以上
- 対象ファイル: src/routes/auth.ts
- 使用ライブラリ: jose (JWT), bcrypt
- 完了条件: 既存のvitestスイートが全件PASSすること
情報を冗長にでも含めることで、サブエージェントはコンテキストの欠如に悩まされず作業を完了できます。筆者は「迷ったらもう1段具体的に」を合言葉にしています。
並列実行と逐次実行の使い分け
Claude Codeのサブエージェントは並列実行が可能です。使い分けの基準は明確です。
- 並列実行:互いに依存関係のない調査タスク、複数ファイルの独立したレビュー、異なるモジュールの実装
- 逐次実行:前のエージェントの出力が次のエージェントの入力になる場合(計画 → 生成 → 評価のパイプライン)
3エージェントパターンでは、パイプライン全体は逐次実行ですが、Generator内で複数の独立した機能を実装する場合は並列化できます。判断基準は「このタスクは他のタスクのファイル出力を読む必要があるか」の一点だけです。読む必要がなければ並列、あれば逐次で、迷う余地はありません。
実装例:3エージェントパターンのサブエージェント定義
ここからは、実際に3エージェントパターンをClaude Codeのサブエージェントとスラッシュコマンドで実装する例を示します。筆者のリポジトリで実際に運用しているものを簡略化して掲載します。
計画エージェント
.claude/agents/planner.md:
---
name: planner
description: 機能追加や変更の要件を受け取り、実装計画を作成する。「計画して」「設計して」のようなタスクで使用する。
tools: Read, Grep, Glob
model: inherit
---
あなたは経験豊富なソフトウェアアーキテクトです。
## 作業手順
1. 要件を分析し、既存コードベースの関連部分を調査する
2. 以下の形式で実装計画を作成する
3. 計画を `.claude/plans/YYYYMMDD-<topic>.md` にMarkdownファイルとして保存する
## 計画フォーマット
| セクション | 内容 |
|-----------|------|
| 目的 | なぜこの変更が必要か(3行以内) |
| 変更対象 | ファイル・操作・変更内容のテーブル |
| 実装手順 | 番号付きリスト。各ステップで対象ファイル・関数を明記 |
| 検証方法 | チェックリスト形式(Generator自己チェック + Evaluator評価) |
| リスク | 副作用・破壊的変更・依存関係 |
## 制約
- 技術的な詳細を詰めすぎない。Generatorが判断できる余地を残す
- 各ステップは独立してテスト可能な粒度にする
- 既存のテストやCIを壊さないことを前提に設計する
- `sprint contract` として、完了条件をGeneratorとEvaluatorの両方が解釈できる形で書く
生成エージェント
.claude/agents/generator.md:
---
name: generator
description: 実装計画に基づいてコードを生成・編集する。「実装して」「コードを書いて」のようなタスクで使用する。
tools: Read, Write, Edit, Grep, Glob, Bash
model: inherit
permissionMode: acceptEdits
---
あなたは熟練したソフトウェアエンジニアです。
## 作業手順
1. `.claude/plans/` から該当する計画ファイルを読む
2. 計画の各ステップを順番に実装する
3. 各ステップ完了後、自己チェックを行う
4. 1機能ごとに `git commit` する(メッセージに計画のステップ番号を含める)
5. すべて完了したら `.claude/progress/YYYYMMDD-<topic>.md` に作業ログを残す
## コーディングルール
- 既存コードのスタイルに合わせる
- 型安全性を最優先にする
- エラーハンドリングを省略しない
- 各変更は最小限の影響範囲に留める
## 自己チェック項目
- [ ] 型エラーがないか(tsc --noEmit)
- [ ] lintが通るか
- [ ] 既存テストが壊れていないか
- [ ] 計画の「検証方法」に書かれた手順をすべて実行したか
評価エージェント
.claude/agents/evaluator.md:
---
name: evaluator
description: 生成されたコードをレビューし、テストを実行する。「レビューして」「評価して」のようなタスクで使用する。
tools: Read, Grep, Glob, Bash
model: inherit
---
あなたは厳格なコードレビュアーであり、QAエンジニアです。
生成エージェントの意図は一切考慮せず、コードと仕様書の事実関係だけで判断します。
## 評価基準
| 軸 | 重み | 判定ポイント |
|----|------|------------|
| Product depth | 高 | 機能がスタブでなく本物として成立しているか |
| Functionality | 高 | 要件の全ワークフローがエンドツーエンドで動くか |
| Visual / UX | 中 | UIが自己説明的か、エラー時の挙動が妥当か |
| Code quality | 中 | 可読性・保守性・DRY・エラーハンドリング |
## 作業手順
1. `.claude/plans/` から計画ファイルを読み、要件を把握する
2. `git diff <base>..HEAD` で変更全体を確認する
3. テストを実行する(`npm test` など)
4. 必要に応じてPlaywright経由で実ブラウザ動作を確認する
5. 以下の形式で評価レポートを出力する
## 評価レポート形式
### 判定: PASS / FAIL / NEEDS_REVISION
#### 良い点
- 具体的に
#### 問題点(FIXが必要)
- [重大度: HIGH/MEDIUM/LOW] 「事実 → 期待 → 実際」の順で記述。例:
`login 時に無効なメールを弾くはずが、空文字列でも200を返す (src/routes/auth.ts:42)`
#### 改善提案(任意)
-
## 重要なルール
- 生成エージェントの意図を好意的に解釈しない
- 「動くからOK」は許容しない。保守性と可読性も評価する
- テストが不足している場合は必ず指摘する
- 自分が出しかけた指摘を「大したことない」と取り下げない
最後の「取り下げない」という一文は、Anthropicが報告していた「Evaluatorが自分で自分を言いくるめてPASSにする」失敗を受けたものです。筆者のリポジトリでも、この1行を足す前と後でFAIL判定の精度が明確に変わりました。
パイプラインを統合するスラッシュコマンド
.claude/commands/feature-pipeline.md:
# 機能追加パイプライン
3エージェントパターンで機能追加を実行します。
## 手順
1. planner エージェントに $ARGUMENTS を渡し、実装計画を作成させる
2. 計画の内容をユーザーに確認する(承認されるまで進めない)
3. generator エージェントに計画ファイルのパスを渡し、実装させる
4. evaluator エージェントに計画ファイルのパスと差分範囲を渡し、レビューさせる
5. evaluator の判定:
- PASS: 完了レポートを出力
- NEEDS_REVISION: 指摘点を整理して generator に差し戻す
- FAIL (3回連続): planner からやり直すことをユーザーに提案する
6. 最大3イテレーションで収束しない場合はユーザーに判断を仰ぐ
## 引数
$ARGUMENTS を要件として使用する。
実行ログの例:ログイン機能を追加する
イメージを具体化するために、「ログイン機能を追加する」というタスクでこのパイプラインを回したときの典型的な流れを書き出しておきます。
-
ユーザー入力:
/feature-pipeline POST /api/auth/login を追加し、emailとpasswordでJWTを返す -
Planner:
.claude/plans/20260413-login.mdを生成。Zod でのバリデーション、jose での JWT 発行、エラー時のレスポンス形式までを「どんなテストがPASSすれば完了とみなすか」のリストに落とし込む - ユーザー確認:計画をレビューし、「パスワードポリシーは8文字以上 + 数字必須に」と修正指示。Plannerが再計画
-
Generator:
src/routes/auth.tsを作成、src/lib/password.tsにハッシュ処理、src/tests/auth.test.tsにユニットテストを追加し、3コミットに分けてgitに投入 -
Evaluator:
git diffを読み、npm testを実行。password.tsの空文字チェックが抜けていること、エラーレスポンスのJSON形式が仕様と微妙に違うことを2件のNEEDS_REVISIONとして返す - Generator(2周目):指摘箇所のみを修正。コミット追加
- Evaluator(2周目):PASS 判定。完了レポートをメインに返す
ここで大事なのは、メインの会話に返ってくるのはEvaluatorの最終レポートだけという点です。Plannerの途中調査ログも、Generatorのファイル編集ログも、Evaluatorのテスト実行出力も、すべてサブエージェント側のコンテキストで閉じています。つまり、メインスレッドは「計画を承認した」「完了レポートを受け取った」という2点しか覚えておらず、コンテキスト圧迫が劇的に減ります。筆者の感覚では、単一エージェントで同じタスクをこなしたときに比べて、メインに残るトークン量はおおむね1/4から1/5程度に収まります。
CLAUDE.md・Skills・サブエージェントの役割分担
筆者はこの3エージェントをCLAUDE.md、スラッシュコマンド(Skills)、サブエージェントと組み合わせて使っています。役割分担は次の通りです。
| 層 | 役割 | 具体例 |
|---|---|---|
| CLAUDE.md | 全セッションに効く不変ルール | 日本語で話す / です・ます調 / シンプル優先 / Planモードのトリガー条件 |
Skills(.claude/commands/*.md) |
ワークフローの入口とオーケストレーション |
/feature-pipeline / /deep-research / /daily-schedule
|
サブエージェント(.claude/agents/*.md) |
単一責務の実行ユニット | planner / generator / evaluator / research-web / research-critic |
CLAUDE.mdに書くのは「どんなタスクでも守るべきポリシー」だけに留め、個別タスクの手順はSkillsに、実際の作業者像はサブエージェントに分けています。こうするとCLAUDE.mdが肥大化せず、常時読み込まれるベースプロンプトが軽く保てます。
計画エージェントのフォーマット設計
Plannerの出力フォーマットは、後続エージェントの成否を左右する要素です。筆者が試した3つの形式を比較すると次のようになります。
| 形式 | 向いている場面 | 欠点 |
|---|---|---|
| チェックリスト付きMarkdown | 人間も読む計画、小〜中規模の機能追加 | 機械的に項目を引き出しにくい |
| YAML | 計画を別ツールに渡す場合、CI連携 | Generatorにコピペされやすく、YAMLの罠(インデント)を踏みやすい |
JSON(feature_list.json) |
長時間稼働、複数セッションでの進捗管理 | 人間には読みにくい。ステータス以外を編集させない運用ルールが必須 |
Anthropicは長時間ハーネスではJSONを選んでいます。理由は「Markdownだとエージェントが勝手に文面を書き換えてしまい、同じファイルを読んでいるはずの別エージェントが別物を見る事故が起きる」ためです。筆者の用途(1セッション完結の機能追加)ではMarkdownで十分ですが、数時間以上走らせる場合はJSONを選ぶべきです。
評価エージェントの評価基準を設計する
Evaluatorを「ただ厳しくしろ」と書いて投げると、結局は曖昧な返答で終わります。評価基準は次の3原則で設計します。
- 二値判定に落とす:各チェック項目を「PASSかFAILか」で答えさせる。グラデーションを許さない
- 観測可能な事実だけを聞く:「コードが良いか」ではなく「この関数はテストから呼ばれているか」のように、見れば分かる事実に変換する
- 発見事項を必ず位置情報つきで書かせる:ファイルパスと行番号を要求することで、推測ではなく読解ベースの評価を強制する
これは実は人間のコードレビューで「根拠を示せ」と言うのと同じ発想です。LLMも「根拠が必要だ」という制約を入れると、ハルシネーションした指摘を出しにくくなります。
Martin Fowler Guides/Sensorsフレームワークとの対応
Martin Fowlerは「Harness engineering for coding agent users」で、エージェントの行動を制御するための2つの概念を提唱しています。
- Guides(フィードフォワード制御):エージェントが行動する前に方向づける予防的な制御
- Sensors(フィードバック制御):エージェントが行動した後に自己修正を促す事後的な制御
それぞれに「計算的」(決定論的で高速、CPUで実行)と「推論的」(セマンティック分析、LLMベース)の2種類があります。Fowlerはこの構造を「サイバネティック・ガバナー(cybernetic governor)」と呼び、制御工学のフィードフォワード + フィードバックとまったく同じ図式でエージェント制御を説明しています。
3エージェントパターンをこのフレームワークに当てはめると、きれいに対応します。
| Guides/Sensors | 計算的(Computational) | 推論的(Inferential) |
|---|---|---|
| Guide(事前制御) | linter設定、型チェック、eslintrc | Plannerの実装計画、CLAUDE.mdのコーディング規約 |
| Sensor(事後制御) | テスト実行、CIパイプライン | Evaluatorのコードレビュー |
Plannerが作成する計画は「推論的Guide」として機能します。Generatorが実装を始める前に、何をどう作るべきかの方向性を与えるからです。一方、Evaluatorは「推論的Sensor」です。実装後のコードを観察し、問題があればフィードバックを返します。
Fowlerが強調している通り、GuideとSensorは両方必要です。Sensorだけ(フィードバックのみ)だと同じ間違いを繰り返し、Guideだけ(フィードフォワードのみ)だとルールが実際に効いたかを検証できません。3エージェントパターンはこの両方を自然に組み込んでいる点で、制御理論的にも筋の通った設計です。
実践で学んだ失敗と教訓
3エージェントパターンを実際のプロジェクトで運用して得た教訓をまとめます。いずれも筆者が実際に踏んだ穴です。
失敗1:プロンプトが曖昧でサブエージェントが迷走する
サブエージェントに「いい感じに実装して」のような曖昧な指示を出すと、コンテキストが不足しているため期待と大きくずれた成果物が返ってきます。
対策:サブエージェントへの指示には、対象ファイルパス、使用するライブラリ、入出力の型定義、制約条件を必ず含めます。冗長に感じるくらいでちょうどよいです。
失敗2:計画の粒度が細かすぎてGeneratorの自由度がなくなる
Plannerに「関数名やインターフェースまですべて決めろ」と指示したところ、Generatorが計画に縛られて柔軟な実装ができなくなりました。さらに、計画段階の小さな誤りが実装で連鎖的なエラーを生みました。
対策:Plannerは「何を作るか」と「なぜ作るか」に集中させ、「どう作るか」の技術的判断はGeneratorに委ねます。これはAnthropicのブログでも指摘されている設計原則です。
失敗3:Evaluatorが甘い
Evaluatorのシステムプロンプトに「厳格にレビューしろ」とだけ書いても、実際には問題を見逃すことがあります。Anthropicも「Evaluatorが自分で自分を言いくるめて承認する」失敗を報告しています。
対策:評価基準を具体的なチェックリストで定義し、各項目にPASS/FAILの二値判定を要求します。加えて「一度出した指摘を取り下げてはいけない」「判定の根拠をファイルパスと行番号で示す」というルールを明記します。これだけで体感3割ほど評価の精度が上がります。
失敗4:フィードバックループが無限に回る
EvaluatorがFAILを出し続け、GeneratorとEvaluatorの間でいつまでも修正が終わらないケースがありました。根本原因は、修正しきれない問題が「計画段階の欠陥」に起因していたためで、いくら実装を直しても収束しません。
対策:イテレーション回数に上限(推奨は3回)を設け、収束しない場合はユーザーに判断を仰ぎます。多くの場合、3回で収束しない問題は計画自体に問題があるので、Plannerからやり直す方が効率的です。
失敗5:サブエージェントのモデル選択を間違える
コスト削減のためにすべてのサブエージェントをHaikuで動かしたところ、Plannerの計画品質が大幅に低下しました。逆にすべてOpusで揃えるとトークン消費が3〜5倍に跳ねます。
対策:各エージェントの役割に応じてモデルを使い分けます。Plannerは高い推論能力が必要なのでOpusまたはSonnet、Generatorはコード生成に強いSonnet、Evaluatorは読解中心なのでSonnetで十分です。コスト最適化は調査系(Explore相当)のサブエージェントをHaikuにする程度に留めるのが安全です。
コストとのトレードオフ
3エージェント化はタダではありません。Anthropicの最初期ハーネスは、単一エージェント実行(20分・9ドル)に対して6時間・200ドルというコスト差を報告しています。モデル世代が進んだ Opus 4.6 でも、DAWアプリのフル構築で約3時間50分・124ドルという数字が出ています。20倍近いコスト増を許容できるかどうかは、タスクの性格次第です。
筆者のざっくりした判断基準は次の通りです。
- 単一エージェントで十分:単発のリファクタ、定型的なファイル編集、調査だけのタスク
- 3エージェントが必要:本番に載せる機能追加、設計意図を外せない新規実装、複数ファイルをまたぐ横断的な変更
- 3エージェント + 並列化:半日以上走らせる長時間タスク、複数機能を並行で実装したい場合
ポイントは「完成後に人間が手戻りする時間」を含めて考えることです。単一エージェントで速く終わらせても、後でバグを潰す時間が長ければトータルで損をします。3エージェント化のコスト増は、基本的には人間のレビュー時間を買い戻していると見るのが自然です。
まとめ
3エージェントパターンの本質は「関心の分離」です。計画・生成・評価という異なる認知タスクを別々のコンテキストに分けることで、それぞれの品質を独立して最適化でき、同時にメインスレッドのコンテキスト汚染も防げます。
導入のステップとしては、まずEvaluator(レビューエージェント)を1つ作ることをおすすめします。既存のワークフローにレビューステップを追加するだけなので導入コストが低く、効果をすぐ実感できます。そこからPlanner、Generatorと段階的に分離していくのが現実的な進め方です。
エージェントに任せる範囲が広がるほど、ハーネス(エージェントを動かす枠組み)の設計が重要になります。Anthropicの3エージェント設計とMartin FowlerのGuides/Sensorsフレームワークは、そのハーネスを体系的に考えるための有用な道具です。筆者自身、単一エージェントで詰まっていた「長時間タスクの品質問題」が、この設計に寄せてからかなり安定するようになりました。手元で小さく試せる構成なので、まずはEvaluator 1体から導入してみてください。
参考資料
- Harness design for long-running application development - Anthropic Engineering
- Effective harnesses for long-running agents - Anthropic Engineering
- Create custom subagents - Claude Code Docs
- Harness engineering for coding agent users - Martin Fowler
- Building agents with the Claude Agent SDK - Anthropic Engineering