マルチエージェント協調
設計パターンから本番運用まで(2026)

六大パターン · LangGraph/CrewAI/AutoGen · MCP+A2A · 可観測性と落とし穴対策

マルチエージェント協調アーキテクチャ実践:設計パターンから本番運用まで(2026年完全ガイド)
検索・コーディング・レビューを単一 LLM Agent に詰め込むと、スケール時にコンテキスト溢れ、直列遅延、単一障害点に必ずぶつかります。本稿は AI エンジニアとアーキテクト向けに、① 単一 Agent の四つのボトルネックと MAS の三制御モード、② LangGraph / CrewAI / AutoGen の選定マトリクス、③ 六大オーケストレーションパターンと MCP+A2A 二層プロトコルの実装例、④ PostgresSaver・サーキットブレーカー・Token 予算などの本番エンジニアリング、⑤ MAST 故障分布データと五大落とし穴、六ステップ本番 Runbookまでを整理します。
01

なぜ単一 Agent では足りないのか:MAS の核心概念

2024〜2025 年に Agent は実験室から本番へ移行しましたが、多くのチームが同じ壁に当たります。すべてのタスクを一つの LLM Agent に任せると、スケール時にシステムが破綻するのです。Google 社内の Agent Bake-Off 実験では、分散型マルチエージェント構成に切り替えた際、処理時間が 1 時間から 10 分へ短縮されました(約 6 倍)。AdaptOrch(2026)も示していますが、オーケストレーションのトポロジ選択は、基盤モデル選択よりも性能への影響が大きい場合があり、SWE-bench などのベンチマークで 12〜23% の改善が報告されています。

01

コンテキストウィンドウの壁:複雑タスクの中間結果がコンテキストを埋め尽くし、後段の推論品質が急落します。

02

専門性の希薄化:検索・コーディング・レビューを一人で担うと、どれも中途半端になります(jack-of-all-trades 問題)。

03

直列実行の非効率:サブタスクを順番に処理すると、総時間は各ステップの合計になり、並列化できません。

04

単一障害点(SPOF):その Agent が停止すると、ワークフロー全体が止まります。

05

結論:マルチエージェント協調アーキテクチャ(MAS)はこれらを解くために設計されています。トポロジ > モデル選択、という原則を覚えておいてください。

MAS の定義:Multi-Agent System(MAS)は、複数の独立した AI Agent が通信プロトコルとオーケストレーション機構を通じて協調し、単一 Agent では効率的に処理できない複雑タスクを完了するシステムです。

特徴説明
役割の専門化検索・推論・生成・検証など、明確に定義された一つのサブタスクのみを担当します
ツールアクセス自身のタスクに必要なツールセットだけを持ちます
状態の分離独自のコンテキストとメモリを保持し、他 Agent を汚染しません
交換可能性独立してアップグレード・差し替えでき、全体への影響を最小化できます

三つの制御モード:

モード構造利点欠点
集中型(Centralized)Orchestrator が A/B/C を一元制御監査しやすく、制御しやすいボトルネックになりやすい
分散型(Decentralized)Agent 同士が P2P で通信高い弾力性と低遅延デバッグが難しく、非決定性が高い
階層型(Hierarchical)上位 Orchestrator → Team Lead → Worker制御性と拡張性のバランスが良い設計の複雑さは中程度
02

LangGraph vs CrewAI vs AutoGen:フレームワーク比較と選定指針

フレームワークを正しく選べば、自前のオーケストレーションと状態管理コードを大幅に削減できます。下表はアーキテクチャパラダイム、言語サポート、学習曲線、状態管理、HITL、可観測性、本番準備度、プロトタイプ速度、Azure 連携、典型シナリオをカバーしています。

観点LangGraphCrewAIAutoGen(Microsoft)
アーキテクチャステートマシングラフ役割制チーム対話型マルチ Agent
言語Python / JS/TSPythonPython / .NET
学習曲線やや急緩やか中程度
状態管理ネイティブ対応自前実装が必要限定的
Human-in-the-Loopネイティブ interrupt()自前実装が必要対応
可観測性LangSmith(商用)限定的Azure Monitor
本番準備度⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
迅速なプロトタイプ⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Azure 連携⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
向いている場面複雑なステートフルワークフロー役割制コンテンツパイプライン対話型協調と議論

選定の目安:

LG

LangGraph を選ぶ:金融・医療・コンプライアンスなど本番信頼性が必要な場合、複雑な状態永続化、精密な HITL 制御、条件分岐とループの厳密な表現が求められるときです。

CR

CrewAI を選ぶ:1〜2 日でアイデア検証したい、チームが「役割」で直感的に Agent を理解できる、コンテンツ生成や調査レポートなど役割制シナリオのときです。

AG

AutoGen を選ぶ:Microsoft / Azure スタック、Agent 同士の多輪議論と反復推論、研究や対話パターンの実験が中心のときです。

オーケストレーションのトポロジ選択は、基盤モデル選択よりも性能への影響が大きい——まずパターンとフレームワークを決め、次にモデルを選びます。

03

六大オーケストレーションパターンと MCP+A2A 二層通信

以下の六パターンで、本番マルチエージェントの 95% 以上をカバーできます。パターン一は順次パイプラインです。Agent A の出力を B の入力に渡し、厳密に直列実行します。記事作成やコードレビューなど、固定フローに適しています。

python
from langgraph.graph import StateGraph, START, END
from typing import TypedDict

class PipelineState(TypedDict):
    query: str
    retrieved_docs: str
    analysis: str
    final_report: str

def retrieval_agent(state: PipelineState):
    docs = search_knowledge_base(state["query"])
    return {"retrieved_docs": docs}

def analysis_agent(state: PipelineState):
    result = llm.invoke(f"Analyze the following: {state['retrieved_docs']}")
    return {"analysis": result.content}

def writer_agent(state: PipelineState):
    report = llm.invoke(f"Write a report based on: {state['analysis']}")
    return {"final_report": report.content}

builder = StateGraph(PipelineState)
builder.add_node("retriever", retrieval_agent)
builder.add_node("analyzer", analysis_agent)
builder.add_node("writer", writer_agent)
builder.add_edge(START, "retriever")
builder.add_edge("retriever", "analyzer")
builder.add_edge("analyzer", "writer")
builder.add_edge("writer", END)
pipeline = builder.compile()

パターン二は並列ファンアウト/ファンインです。複数 Agent が独立サブタスクを同時処理し、総時間は max(T1…Tn) になります。LangGraph の Send APIAnnotated[list, operator.add] Reducer で並列結果を自動集約できます。

python
from langgraph.types import Send
from langgraph.graph import StateGraph, START, END
from typing import TypedDict, Annotated
import operator

class ResearchState(TypedDict):
    query: str
    research_results: Annotated[list, operator.add]
    final_synthesis: str

def supervisor(state: ResearchState):
    subtasks = [
        {"query": state["query"], "source": "academic"},
        {"query": state["query"], "source": "industry"},
        {"query": state["query"], "source": "news"},
    ]
    return [Send("research_worker", task) for task in subtasks]

def research_worker(state: dict):
    result = search_by_source(state["query"], state["source"])
    return {"research_results": [result]}

def synthesizer(state: ResearchState):
    combined = "\n".join(state["research_results"])
    synthesis = llm.invoke(f"Synthesize the following research: {combined}")
    return {"final_synthesis": synthesis.content}

builder = StateGraph(ResearchState)
builder.add_node("research_worker", research_worker)
builder.add_node("synthesizer", synthesizer)
builder.add_conditional_edges(START, supervisor, ["research_worker"])
builder.add_edge("research_worker", "synthesizer")
builder.add_edge("synthesizer", END)
graph = builder.compile()

パターン三は階層型 Supervisor-Workerです。Supervisor が意図認識とルーティングを担い、Worker が専門サブタスクを実行します。キーワード高速経路 + LLM 精密ルーティングの二層最適化を推奨します。

python
KEYWORD_ROUTING = {
    "code": "code_agent",
    "search": "search_agent",
    "query": "search_agent",
    "data": "data_agent",
}

def supervisor_with_fast_path(state):
    query = state["query"].lower()
    for keyword, agent_name in KEYWORD_ROUTING.items():
        if keyword in query:
            return {"next": agent_name}
    routing_prompt = f"""
    User request: {state['query']}
    Available agents: code_agent, search_agent, data_agent
    Return only the most suitable agent name.
    """
    decision = llm.invoke(routing_prompt)
    return {"next": decision.content.strip()}

パターン四は群集協調(Swarm)です。Agent が P2P でタスクを受け渡し、中央調整者はいません。終了ルールで停止します。本番では慎重に使い、ハードなラウンド上限を必ず設定してください。AutoGen の GroupChat + max_round の例です。

python
import autogen

reviewer_1 = autogen.AssistantAgent(
    name="SecurityReviewer",
    system_message="You are a security expert focused on vulnerabilities in code."
)
reviewer_2 = autogen.AssistantAgent(
    name="PerformanceReviewer",
    system_message="You are a performance expert focused on efficiency and resource usage."
)
human_proxy = autogen.UserProxyAgent(
    name="CodeAuthor",
    human_input_mode="NEVER",
    max_consecutive_auto_reply=2,
    is_termination_msg=lambda x: "APPROVED" in x.get("content", "")
)
groupchat = autogen.GroupChat(
    agents=[human_proxy, reviewer_1, reviewer_2],
    messages=[],
    max_round=6
)
manager = autogen.GroupChatManager(groupchat=groupchat)

パターン五はブラックボードアーキテクチャです。全 Agent が構造化ワークスペースを共有し、前提条件を満たしたときに読み書きします。時間単位の非同期タスクや異種サービス連携に向きます。パターン六はハイブリッドです。Intent ルーター + Supervisor + 並列ファンアウト + 品質保証パイプラインを組み合わせ、企業向けコンテンツ生成の典型構成となります。

MCP + A2A 二層プロトコル(Linux Foundation Agentic AI Foundation 管轄):MCP は垂直層で Agent ↔ ツール/DB/API を統一し、A2A は水平層で Agent ↔ Agent のタスク委譲と能力発見を標準化します。

python
from mcp.server import Server
from mcp.types import Tool, TextContent

app = Server("data-agent-mcp")

@app.list_tools()
async def list_tools():
    return [
        Tool(
            name="query_customer_db",
            description="Query customer database by id, name, or email",
            inputSchema={
                "type": "object",
                "properties": {
                    "field": {"type": "string", "enum": ["id", "name", "email"]},
                    "value": {"type": "string"}
                },
                "required": ["field", "value"]
            }
        )
    ]

@app.call_tool()
async def call_tool(name: str, arguments: dict):
    if name == "query_customer_db":
        result = db.query(arguments["field"], arguments["value"])
        return [TextContent(type="text", text=str(result))]

A2A の Agent Card(/.well-known/agent.json)で能力を宣言し、Orchestrator が JSON-RPC 2.0 でタスクを委譲します。

python
import httpx

async def discover_and_delegate(agent_url: str, task: str):
    card_response = await httpx.get(f"{agent_url}/.well-known/agent.json")
    agent_card = card_response.json()
    available_skills = [s["id"] for s in agent_card["skills"]]
    if "web_research" not in available_skills:
        raise ValueError(f"Agent {agent_card['name']} does not support web_research")
    payload = {
        "jsonrpc": "2.0",
        "method": "message/send",
        "id": "task-001",
        "params": {
            "message": {
                "role": "user",
                "parts": [{"type": "text", "text": task}]
            }
        }
    }
    response = await httpx.post(agent_card["url"], json=payload)
    return response.json()

関連記事:ツール接続の詳細はゼロから MCP Server を開発する、プロトコル戦略の全体像はMCP が AI 時代の HTTP となる理由を併読してください。

04

本番級マルチエージェントシステム:六ステップ Runbook

01

選定とトポロジ設計:意思決定ツリーでオーケストレーションパターン(パイプライン/ファンアウト/階層/ブラックボード/ハイブリッド)を確定します。Agent 数は 3〜8 個に抑え、過剰設計を避けます。

02

状態永続化:PostgresSaver でチェックポイントを保存し、プロセス跨ぎの復旧と中断再開を可能にします。各セッションに thread_id を紐づけます。

03

Human-in-the-Loop:高リスク操作は interrupt() で一時停止し、人手確認を待ちます。コンプライアンス業界では必須です。

04

サーキットブレーカーとリトライ:外部 Agent 呼び出しを CircuitBreaker で包み、失敗閾値で OPEN 状態に遷移させ、連鎖障害を防ぎます。

05

Token 予算:TokenBudgetManager を導入し、各 Agent 呼び出し前に残予算を検証して、コスト暴走を防ぎます。

06

可観測性の接続:OpenTelemetry の traced_agent_call に correlation_id を付与し、MONITORING_METRICS を追跡します。LLM-as-Judge で出力品質をサンプリング評価します。

python
from langgraph.checkpoint.postgres import PostgresSaver
from langgraph.types import interrupt

with PostgresSaver.from_conn_string("postgresql://user:pass@localhost/agentdb") as checkpointer:
    graph = builder.compile(checkpointer=checkpointer)
    config = {"configurable": {"thread_id": "user-session-12345"}}
    result = graph.invoke({"query": "Analyze Q2 earnings"}, config)

def high_risk_action_agent(state):
    proposed_action = plan_action(state)
    human_decision = interrupt({
        "proposed_action": proposed_action,
        "risk_level": "HIGH",
        "message": "This operation will modify the production database. Please confirm."
    })
    if human_decision["approved"]:
        return execute_action(proposed_action)
    return {"status": "cancelled", "reason": human_decision.get("reason")}
python
import time
from functools import wraps

class CircuitBreaker:
    def __init__(self, failure_threshold=5, recovery_timeout=60):
        self.failure_count = 0
        self.failure_threshold = failure_threshold
        self.recovery_timeout = recovery_timeout
        self.state = "CLOSED"
        self.last_failure_time = None

    def __call__(self, func):
        @wraps(func)
        async def wrapper(*args, **kwargs):
            if self.state == "OPEN":
                if time.time() - self.last_failure_time > self.recovery_timeout:
                    self.state = "HALF_OPEN"
                else:
                    raise Exception("Circuit breaker OPEN - agent temporarily unavailable")
            try:
                result = await func(*args, **kwargs)
                if self.state == "HALF_OPEN":
                    self.state = "CLOSED"
                    self.failure_count = 0
                return result
            except Exception:
                self.failure_count += 1
                self.last_failure_time = time.time()
                if self.failure_count >= self.failure_threshold:
                    self.state = "OPEN"
                raise
        return wrapper

class TokenBudgetManager:
    def __init__(self, total_budget: int = 100_000):
        self.total_budget = total_budget
        self.used_tokens = 0
        self.agent_usage = {}

    def check_budget(self, agent_name: str, estimated_tokens: int) -> bool:
        remaining = self.total_budget - self.used_tokens
        if estimated_tokens > remaining:
            raise BudgetExceededException(
                f"Agent {agent_name} requested {estimated_tokens} tokens, "
                f"but only {remaining} tokens remain"
            )
        return True

    def record_usage(self, agent_name: str, actual_tokens: int):
        self.used_tokens += actual_tokens
        self.agent_usage[agent_name] = self.agent_usage.get(agent_name, 0) + actual_tokens
05

可観測性の実データ、五大落とし穴と 2026 年の動向

MAST 研究チームが 1,642 件のマルチエージェント実行トレースを分析した結果、故障分布は次のとおりです。

故障タイプ割合内容
システム設計の問題41.77%ステップ重複、ツール選択ミス、コンテキスト溢れ、終了条件の欠如
Agent 間の不整合36.94%引き継ぎ時のコンテキスト喪失、幻覚が次 Agent の「事実」になる
タスク検証の失敗21.30%早期終了、不完全な検証
A

57% vs 8%:組織の 57% が本番で Agent を稼働させていますが、LLM 可観測性を実装完了したのは 8% のみです。HTTP 200 でエラーが返り、ダッシュボードは緑でも出力は誤っている、という状態が散見されます。

B

Google Bake-Off 6 倍:分散マルチエージェント構成で処理時間が 1 時間から 10 分へ短縮され、子 Agent を独立アップグレードできます。

C

AdaptOrch 12〜23%:適切なオーケストレーショントポロジは SWE-bench などで 12〜23% の性能向上をもたらし、モデル差し替え単独より効果が大きい場合があります。

python
from opentelemetry import trace
import uuid

tracer = trace.get_tracer("multi-agent-system")

def traced_agent_call(agent_name: str, task: dict, correlation_id: str = None):
    if not correlation_id:
        correlation_id = str(uuid.uuid4())
    with tracer.start_as_current_span(f"agent.{agent_name}") as span:
        span.set_attribute("agent.name", agent_name)
        span.set_attribute("correlation.id", correlation_id)
        span.set_attribute("task.type", task.get("type", "unknown"))
        try:
            result = agent_registry[agent_name].run(task)
            span.set_attribute("agent.tokens_used", result.get("tokens", 0))
            span.set_attribute("agent.status", "success")
            return result
        except Exception as e:
            span.set_attribute("agent.status", "error")
            span.set_attribute("error.message", str(e))
            raise

MONITORING_METRICS = {
    "task_success_rate": "End-to-end task completion rate (target: >85%)",
    "e2e_latency_p95": "P95 end-to-end latency (target: <30s)",
    "total_cost_per_task": "Average token cost per task",
    "agent_error_rate": "Per-agent error rate (target: <5%)",
    "agent_retry_count": "Retry count (high retries = investigate)",
    "tool_call_budget_usage": "Tool call count vs budget ratio",
    "output_quality_score": "Output quality score",
    "goal_alignment_score": "Goal alignment score",
    "hallucination_rate": "Hallucination detection rate",
}

def evaluate_agent_output(original_task: str, agent_output: str) -> dict:
    evaluation_prompt = f"""
    Original task: {original_task}
    Agent output: {agent_output}
    Score completeness, accuracy, relevance, and hallucination (1-5).
    Return JSON: {{"completeness": x, "accuracy": x, "relevance": x,
    "hallucination_detected": true/false, "comments": "..."}}
    """
    evaluation = llm.invoke(evaluation_prompt)
    return json.loads(evaluation.content)

五大落とし穴と対策:

1

コンテキスト汚染:Agent A の幻覚が B/C に伝播し、誤った前提でワークフロー全体が進みます。対策:各引き継ぎ点で validate_agent_output により Schema と信頼度を検証します。

2

無限ループ:リトライやツール呼び出しが制御不能になり、Token コストが急増します。対策:MAX_ITERATIONSMAX_TOOL_CALLS_PER_AGENTMAX_TOTAL_TOKENS のハード上限を設定します。

3

過剰設計:二段の処理を八つの Agent に分割してしまいます。対策:まず順次パイプラインから始め、本番の最適数は 3〜8 個です。

4

デモと本番の断絶:社内デモは綺麗でも、エッジ入力で頻繁に失敗します。対策:ProductionGuardrails で入力長、インジェクション検知、PII フィルタを実装します。

5

並列同期の欠如:Send API でファンアウト後、遅い分岐が完了する前に Supervisor が再実行されます。対策:LangGraph の defer=True で明示的な同期バリアを作ります。

python
def validate_agent_output(output: dict, schema: dict) -> bool:
    jsonschema.validate(output, schema)
    if output.get("confidence_score", 1.0) < 0.7:
        raise LowConfidenceError(f"Agent output confidence too low: {output['confidence_score']}")
    required_fields = schema.get("required", [])
    missing = [f for f in required_fields if not output.get(f)]
    if missing:
        raise MissingFieldsError(f"Missing required fields: {missing}")
    return True

MAX_ITERATIONS = 10
MAX_TOOL_CALLS_PER_AGENT = 20
MAX_TOTAL_TOKENS = 50_000

class ProductionGuardrails:
    def validate_input(self, user_input: str) -> str:
        if len(user_input) > 10000:
            raise InputTooLongError("Input exceeds 10000 character limit")
        injection_patterns = ["ignore previous instructions", "forget everything"]
        for pattern in injection_patterns:
            if pattern.lower() in user_input.lower():
                raise PromptInjectionError("Potential prompt injection detected")
        return user_input.strip()

    def validate_output(self, output: str) -> str:
        output = self.pii_filter.redact(output)
        if self.content_classifier.is_harmful(output):
            raise HarmfulContentError("Output contains harmful content")
        return output

builder.add_node("supervisor", supervisor_node, defer=True)
text
タスクに明確な直列依存ステップがありますか?
├─ はい → サブタスクは並列実行できますか?
│        ├─ いいえ → 【順次パイプライン】
│        └─ はい → 【並列ファンアウト + 順次パイプラインのハイブリッド】
└─ いいえ → 意思決定権を持つ Agent はいますか?
         ├─ はい → サブチームが必要な規模ですか?
         │        ├─ いいえ → 【Supervisor-Worker 階層パターン】
         │        └─ はい → 【階層型(Supervisors of Supervisors)】
         └─ いいえ → 長時間の非同期タスクですか?
                  ├─ はい → 【ブラックボードアーキテクチャ】
                  └─ いいえ → Agent 数は 5 以下ですか?
                           ├─ はい → 【Swarm(終了条件を必ず設定)】
                           └─ いいえ → 【階層パターンへの再分割を検討】

五つの核心要点:① オーケストレーショントポロジ > モデル選択、② 順次パイプラインから始め、根拠があってから Agent を増やす、③ MCP + A2A は新規プロジェクトの標準プロトコル、④ 可観測性はオプションではない(57% vs 8% のギャップ)、⑤ 本番の最適 Agent 数は 3〜8 個です。

2026 年の動向:連邦型オーケストレーション(複数チームのサブオーケストレーターがルーティング戦略を共有)、マルチモーダルマルチエージェント(視覚・音声とテキストの混合協調)、適応型トポロジ選択(AdaptOrch 方向)、EU AI Act による完全な意思決定監査チェーンの義務化が進んでいます。

注意:ノート PC でマルチエージェントを動かすと、スリープによる切断、メモリ不足、ネットワークジッターに直面します。安価な Linux VPS では Xcode や Apple Silicon 最適化推論をネイティブ実行できません。マルチエージェントアーキテクチャは 2026 年 AI エンジニアリングの中核ですが、本番には安定したホストが必要です。

7×24 のマルチエージェント常駐、PostgresSaver チェックポイント永続化、MCP Server と Cursor / Claude Code の協調が必要な本番環境では、MESHLAUNCH の Mac Mini クラウドレンタルが最適解となることが多いです。専有 Apple Silicon、日/週/月の柔軟契約で、LangGraph ワークフローとローカルベクトル検索の安定ホストとして、オーケストレーション資産をベンダー依存からチーム自有过の移植可能な能力へ移行できます。見積もりは料金ページ、デプロイ支援はヘルプセンターをご覧ください。

よくある質問

複雑な状態管理、HITL、コンプライアンス監査が必要なら LangGraph を選びます。1〜2 日でプロトタイプを作り、役割制コンテンツパイプラインを回すなら CrewAI が向きます。Microsoft / Azure スタックで多輪の議論型協調が必要なら AutoGen を検討してください。マルチエージェントの常駐ホストは料金ページをご覧ください。

MCP は垂直層で、Agent がツール・データベース・API にアクセスする経路を統一します(一度実装すればどこでも使えます)。A2A は水平層で、Agent Card と JSON-RPC 2.0 によりエージェント間のタスク委譲と能力発見を標準化します。両者は Linux Foundation Agentic AI Foundation がガバナンスを担っており、新規プロジェクトでは二層アーキテクチャの採用を推奨します。

最低限、PostgreSQL チェックポイント永続化(PostgresSaver)、OpenTelemetry 分散トレース、Token 予算管理、サーキットブレーカー、そしてスリープしない 7×24 ホストが必要です。Mac Mini 裸機では LangGraph ワークフロー、MCP Server、ローカルベクトル検索を同一ノードで稼働できます。デプロイとネットワークの詳細はヘルプセンターをご覧ください。