単一エージェントアーキテクチャは天井にぶつかります。コーディングエージェントはコードを書けますが——自分の出力をレビューすることはできません。請求エージェントは問い合わせを解決できますが——出荷部門と話すことはできません。同じ視点、同じ盲点です。
ツールを追加すればするほど、レイテンシーは膨張し、context windowは溢れます。その天井は構造的なものであり、プロンプトを深くすれば突破できるものではありません。
解決策は専門化エージェントです——専門範囲を絞り、並列実行し、プロトコルを定義します。
この記事を読み終えると、3つのオーケストレーションパターン(Supervisor-Worker、Peer-to-Peer、Hierarchical)のPythonコード、コストを50〜70%削減する役割とモデルのマッピング、平坦なspanリストをシステムマップに変えるtraceトポロジーが手に入ります。
単一エージェントはいつ破綻するか?
複雑性の天井
単一エージェントは、4つのシナリオで予測可能な形で失敗します。
複数ドメインの専門知識。 1つのエージェントが、コーディングの専門家、法律レビュアー、財務アナリストを同時に兼ねることを求められます。プロンプト肥大化——3つのドメインをすべて収容するためにsystem promptが膨れ上がります。役割混乱——モデルがトーンと優先順位を混ぜてしまいます。カジュアルなエンジニア用語で書かれた法律レビュー。「コーディング専門家」ペルソナが支配してコンプライアンスチェックを飛ばす財務分析。こうした問題が起こります。
並列実行。 同時に実行できる3つの独立したサブタスク——競合の価格調査、ユーザーレビュー分析、製品仕様の要約——を、単一エージェントが直列に処理します。合計レイテンシーは3つの合計になります。3つの専門エージェントを並列実行すれば、レイテンシーは3つのうち最大値になります。
自己批判。 単一エージェントが出力を生成し、自分の出力を評価します。答えを生み出したのと同じ認知プロセスに、その欠陥を見つけるよう求めても、見つけられません。ピアレビュー——異なるプロンプト、異なるモデル、異なる視点を持つ別のエージェント——が、生成エージェントには見えないエラーを検出します。
ツール数の爆発。 15個のツールなら問題ありません。25個になると、モデルのツール選択精度は測定可能なほど低下します——間違ったツールを選ぶことが増え、正しいツールを見逃し、または間違った順序でツールを呼びます。それぞれ5〜8個のツールを持つ専門エージェントは、25個のツールを持つ1つの汎用エージェントより優れています。
マルチエージェントが常に答えとは限らない
マルチエージェントシステムには実際のオーバーヘッドが伴います。エージェント間通信のレイテンシー、エージェント間メッセージのトークンコスト、2つのエージェントが矛盾する回答を生成したときの整合性リスク、そして5エージェントチェーンのどのエージェントが誤った出力を生成したかを特定できないデバッグの複雑さです。タスクが、よくプロンプトされた1つのエージェントと、適切にスコープされた5〜10個のツールで処理できるなら、マルチエージェントの複雑さを持ち込まないでください。まず単一から始めます。単一が明確に失敗するとき——ツール混乱、役割の不整合、並列実行で解消される直列レイテンシー——だけマルチに移行します。
単一エージェントアーキテクチャガイドでは基礎を解説しています。この記事は、単一エージェント設計を限界まで押し上げ、今まさに天井にぶつかっている読者を想定しています。
3つのオーケストレーションパターン
パターン1:Supervisor-Worker
1つのsupervisorエージェントがオーケストレーションします。タスクを分解し、サブタスクをworkerに割り当て、結果を集約し、出力を返す前に品質ゲートを実行します。workerは専門化されており——それぞれが独自のsystem prompt、ツールセット、モデルを持ちます。worker同士は会話しません。supervisorとのみ通信します。
class SupervisorAgent:
def __init__(self, model: str, workers: list[WorkerAgent]):
self.model = model
self.workers = {w.name: w for w in workers}
async def execute(self, task: str) -> dict:
plan = await self._decompose(task)
results = {}
for subtask in plan["subtasks"]:
worker = self.workers[subtask["assigned_to"]]
results[subtask["id"]] = await worker.execute(subtask)
synthesis = await self._synthesize(task, results)
quality = await self._quality_gate(synthesis)
if quality["passed"]:
return synthesis
else:
return await self._retry_or_escalate(task, quality["issues"])
最適な用途: 独立したサブタスクにきれいに分解でき、中央での品質管理が必要で、比較的固定されたチーム構造を持つタスク。トレードオフ: supervisorがボトルネックになり、単一障害点になります。worker同士が動的に交渉する必要がある場合は不向きです。
パターン2:Peer-to-Peer
階層はありません。すべてのエージェントがピアです。どのエージェントも、共有メッセージバスを通じて他のエージェントと通信を開始できます。エージェントは互いの能力を発見し、タスクの引き継ぎを動的に交渉します。
class PeerAgent:
def __init__(self, name: str, role: str, model: str, message_bus: MessageBus):
self.name = name
self.role = role
self.model = model
self.bus = message_bus
self.bus.subscribe(self.name, self._handle_message)
async def _handle_message(self, msg: Message):
if msg.type == "request":
result = await self._execute_task(msg.content)
await self.bus.send(Message(
to=msg.from_agent,
type="response",
content=result,
correlation_id=msg.correlation_id
))
最適な用途: 動的な交渉——コードレビューエージェントがバグを発見し、修正内容をコーディングエージェントに直接メッセージで送る。supervisorはループ内にいません。ボトルネックなし。柔軟なワークフロー。トレードオフ: デバッグが難しくなります——会話グラフが複雑になり得、ピア間の無限メッセージループや矛盾する出力に対処するためには、明示的なループ検出と競合解決メカニズムが必要です。
パターン3:Hierarchical
多段階エスカレーションです。フロントラインエージェントが定型的なケースを処理します。複雑または異常なケースは上級エージェントにエスカレーションされます。最も難しいケースはプリンシパルエージェントまたは人間に到達します。モデルの品質とコストはtierに比例します——Tier 1は安価なモデル、Tier 2はミッドティア、Tier 3はフロンティアモデルを使用します。
class TieredAgentSystem:
def __init__(self, tiers: list[AgentTier]):
self.tiers = sorted(tiers, key=lambda t: t.level)
async def execute(self, task: str) -> dict:
for tier in self.tiers:
result = await tier.agent.execute(task)
if result["confidence"] >= tier.confidence_threshold:
return result
return await self._escalate_to_human(task)
最適な用途: 自然な複雑性の段階があるサポートワークフロー、自動フィルター——上級レビュー——人間へのエスカレーションという流れのコンテンツモデレーション、そして大半のリクエストが単純で、少数が深い専門知識を要するあらゆるドメイン。トレードオフ: エスカレーションロジックは本番データによる調整が必要です——tierごとのconfidence thresholdを調整するフィードバックループが必要です。
エージェント通信プロトコル
エージェント間プロトコルとしてのFunction Calling
最もシンプルなアプローチ:Agent Aがsend_message_to_agent_bツールを呼びます。このツールはAgent Aのfunction callingスキーマで定義されます。既存のインフラと互換性があります。新しいプロトコルを学ぶ必要はゼロ。制限:同期ブロッキングです。各メッセージは完全なツール呼び出しのラウンドトリップになります。マルチターンのエージェント会話では、レイテンシーが線形に蓄積します。ツール定義自体が、スキーマの不一致な複数のプロバイダーにまたがる必要がある場合、function callingとツール使用ガイドが、エージェント間のツール呼び出しをモデル間で移植可能にする正規化レイヤーを解説しています。
エージェント通信のためのMCP
各エージェントは自身の能力をMCPサーバーとして公開します。MCPクライアントとして動作する他のエージェントが、その能力を発見・起動します。MCPガイドではプロトコルの基礎を解説しています。マルチエージェントシステムでは、MCPが標準化された能力発見を提供します——エージェントは他のエージェントが何ができるかを事前に知る必要がありません。MCPエコシステムに問い合わせて、能力を動的に発見します。
Google A2A
エージェント間通信のために設計された専用プロトコルです(A2A仕様)。能力発見にはAgent Cardsを使用します。構造化されたTaskライフサイクル:submitted——working——completedまたはfailed。タスク実行中のストリーミング更新。マルチモーダルなコンテンツ交換。クロスフレームワーク——異なるフレームワークで構築されたエージェントも、A2Aを話せば相互運用できます。異なるチームが異なるスタックを使用するヘテロジニアスなマルチエージェントシステムに最適です。
カスタムメッセージバス
構造化メッセージスキーマを持つRedis Pub/SubまたはNATS。ルーティング、永続化、リトライ、可観測性に対する最大の制御。実装コストは最大。スキーマ:{agent_id, correlation_id, message_type, payload, timestamp}。エージェント間の通信パターンが、標準プロトコルが適合しないほど独自である場合——または高レベルプロトコルが提供しない保証(exactly-once配信、順序付き配信)が必要な場合に選択します。
役割とモデルのマッピング
マルチエージェントシステムの最大のコストの罠:すべてのエージェントにフロンティアモデルを割り当ててしまうことです。「請求」と「テクニカルサポート」を振り分けるclassifierエージェントに、入力トークン$15/MのClaude Opusは必要ありません。$0.15のGPT-4o Miniで十分です——分類精度は同一です。
| エージェントの役割 | 推奨モデル | Cost/1M Input | 根拠 |
|---|---|---|---|
| Classifier/Router | DeepSeek V3.2 / GPT-4o Mini | $0.14-0.15 | 単純な分類。安価なモデルでもフロンティアモデルと同等の性能を発揮します。 |
| Basic Q&A / FAQ | GPT-4o Mini / Claude Haiku | $0.15-0.25 | Retrieval 拡張による事実ベースの応答。中位の能力、最低価格です。 |
| Content Generation | GPT-4o / Claude Sonnet 4 | $2.50-3.00 | トーン、構成、創造性が重要です。中位層の割増料金に見合う価値があります。 |
| Code Generation | Claude Sonnet 4 / DeepSeek V4 Pro | $0.42-3.00 | SWE-bench のデータがこの選択を後押しします。1ドル当たりの DeepSeek のコーディング性能は傑出しています。 |
| Code Review / Quality Gate | Claude Opus 4 / GPT-5.5 | $10-15.00 | バグの発見にはフロンティアレベルの推論が必要です。バグを1つ見逃すコストは、モデルの割増料金を上回ります。 |
| Final Synthesis | Claude Opus 4 | $15.00 | ユーザーが目にする出力です。トーン、正確性、指示の追従性のために割増料金を払う価値があります。 |
エージェントごとのコスト追跡——すべてのLLM spanにagent_idをspan属性として付け、gen_ai.cost.totalを記録する——で、エージェントごとのコストレポートが得られます。マルチエージェント予算の40%を消費しているエージェントをすぐに見つけられるでしょう。OpusからSonnetにダウングレードし、出力品質が実際に変わるか確認します。多くの場合、変わりません。エージェントごとのモデル選択に加えて、12通りのLLM APIコスト最適化ガイドでは、エージェントフリート全体で相乗効果を発揮するプロンプトキャッシング、バッチ処理、セマンティックキャッシングのパターンを解説しています。
マルチエージェントシステムのデバッグと監視
Traceトポロジーの問題
1つのユーザーリクエストがトリガーするもの:Agent A(分類)——Agent B(調査)+Agent C(コード)の並列実行——Agent A(合成)——6回のLLM呼び出し、10回のツール呼び出し、3つのエージェント間メッセージ。19エントリの平坦なspanリストではデバッグ不可能です。実行グラフが見えません。
解決策:階層モデリングを備えたOpenInference AGENT span kindです。ルートspan:ユーザーセッション。レベル1:オーケストレーターの決定。レベル2:エージェントごとの実行。レベル3:エージェントごとのツール呼び出し。traceビューアは、平坦なリストではなく実行グラフを描画します。Agent Cのツール呼び出しが失敗すると、コンテキスト内で見えます——どのエージェント、どのステップ、その前後で何が起きたか。
完全なOpenTelemetryセットアップは可観測性ガイドをご覧ください。
一般的なマルチエージェント障害モード
無限メッセージループ。 Agent A——Agent B——Agent A——Agent B。防止策:メッセージバスレベルでの会話深度制限とループ検出。APIレイヤーでは、エージェントごとのレート制限が予算の上限を追加します——エージェントがリクエストクォータを超えると、メッセージバスのロジックが何を許可していようと、ループは停止します。
矛盾する出力。 Agent Aは返金すべきと言い、Agent Bは返金すべきでないと言います。解決メカニズムがありません。防止策:明示的な競合解決を持つsupervisorパターン、またはエージェント間の投票メカニズム。
ツール権限の漏洩。 設定ミスのあるツールレジストリを通じて、コーディングエージェントが誤って請求エージェントの返金ツールにアクセスしてしまいます。防止策:エージェントごとのツール許可リスト。すべてのツール監査証跡へのエージェントIDの記録。
サイレントエージェント障害。 あるエージェントが未処理のエラーを投げます。オーケストレーターは気づきません。ユーザーは重要な情報が欠けた部分的な応答を受け取ります。防止策:エージェント間プロトコルでの構造化エラー報告。合成前のオーケストレーターレベルのヘルスチェック。
FAQ
いつマルチエージェントアーキテクチャを使うべきでないか?
適切にプロンプトされた、10個以下の明確に定義されたツールを持つ単一エージェントがタスクを処理できるなら、マルチエージェントの複雑さを持ち込まないでください。通信オーバーヘッド、デバッグの難しさ、エージェント間メッセージのコストが、利点を上回ります。まず単一エージェント。マルチエージェントは、単一エージェントが明確に失敗するとき——ツール混乱、役割の不整合、並列実行で解決される直列レイテンシー——だけです。
システムは何体のエージェントから始めるべきか?
2〜3体で、明確に異なる役割をカバーします。6体から始めないでください。調整の複雑さは非線形にスケールします——6エージェントシステムは2エージェントシステムの3倍難しいのではありません。9倍に近いです。既存のエージェントが、明確な専門知識を要する特定のサブタスクで一貫して失敗するようになったときだけ、エージェントを追加します。
どのオーケストレーションパターンから始めるべきか?
Supervisor-Workerです。中央集権的な制御、明確な状態管理、最もシンプルなデバッグ。worker同士が本当に動的な交渉を必要とする場合だけ、Peer-to-Peerにアップグレードします。測定可能なconfidence thresholdを持つ明確な複雑性の段階がある場合だけ、Hierarchicalにアップグレードします。シンプルに始めます。データが必要性を証明したときだけ、複雑さを追加します。
一貫してミスをするエージェントをどう扱うか?
プロンプトの微調整から始めないでください。最初に:trace分析。失敗パターンを見つけます——どの入力がエラーをトリガーするか?実行のどのステップが失敗するか?次に:エージェントのスコープを狭めます。処理しているタスクタイプが多すぎるかもしれません。3番目に:品質ゲートエージェントを追加します——出力がユーザーに届く前にチェックするレビュアーです。4番目に:エージェントにドメイン知識が欠けている場合は、RAGを追加します——fine-tuningではなく、プロンプトの追加でもありません。
3つのモデルtierで稼働する5エージェントシステムの実際の運用コストは?
運用コストの本質はトークンではありません——断片化です。各エージェントtierが別々のプロバイダーに接する可能性があります。つまり、別々のAPIキー、別々のレート制限追跡、別々のコストダッシュボードが必要です。classifierエージェント($0.14/MのDeepSeek Flash)とコードレビュアー($15/MのClaude Opus)が異なるプロバイダーを経由するとき、エージェントの動作を最適化するよりも、資格情報の管理に時間を費やしてしまいます。修正はアーキテクチャ的なものです:モデルに関係なくすべてのエージェントに単一のエンドポイント。エージェントごとのコスト帰属が、プロバイダー横断のスプレッドシート作業ではなく、span属性になります。この単一エンドポイントアプローチを本番対応にする可観測性とレイテンシーチューニングについては、TokSpanの本番最適化ガイドが、エージェントフリート全体でのコネクションプーリング、リクエストキューイング、モデルごとのタイムアウト設定を解説しています。
マルチエージェントアーキテクチャはより洗練されているのではありません——特定の障害モードへの対応なのです。単一エージェントがドメイン横断でツールを混同するとき、直列実行でレイテンシーが許容不能になるとき、自己レビューが自分のエラーを検出できないとき——それがシグナルです。それ以前ではありません。
Supervisor-Workerから始めます。役割とモデルのマッピングを容赦なく行います——classifierにOpusは不要です。すべてのエージェントのspanにagent_idを計装します。エージェントごとのコストレポートを1週間観察します。少なくとも1体はモデル過剰で、品質に影響なくtierを下げられるエージェントが見つかるでしょう。
オーケストレーションパターンよりも重要なのは、いつ別のエージェントを追加すべきでないかを知る規律です。
エージェントフリートのコストレポートを、4つの異なるプロバイダーダッシュボードのCSVエクスポートを寄せ集めて作るべきではありません。TokSpanでエージェントをデプロイしましょう——エージェントごとのコスト帰属、集中管理されたレート制限、エージェントが必要とするすべてのモデルを1つのエンドポイントの背後に。