コンテンツにスキップ
LinkedInX

マルチエージェント設計パターン

約10分

対象読者: 複数のAIエージェントを組み合わせたシステムを設計する開発者・アーキテクト

マルチエージェントシステムとは、複数のAIエージェントが協調して単一のエージェントでは解決が難しいタスクを処理するアーキテクチャです。このページでは、Claude Agent SDKで実装できる4つの代表的な設計パターンと、それぞれの選定基準を解説します。

マルチエージェントシステムとは

Section titled “マルチエージェントシステムとは”

単一のAIエージェントには、構造的な限界が3つあります。第一にコンテキスト長の上限です。大規模なコードベース全体のレビューや、数百ページにわたるドキュメント群の分析は、1回のコンテキストウィンドウに収まりません。第二に専門性の限界です。法律・医療・ファイナンスといった専門領域では、汎用エージェントよりも特定ドメインに特化したエージェントの方が正確さと一貫性が高くなります。第三に並列性の欠如です。単一エージェントはタスクを直列で処理するため、独立した複数のサブタスクがある場合でも同時実行できません。

マルチエージェントシステムはこれら3つの問題を解決します。タスクを分割してコンテキスト長の制約を回避し、専門化されたエージェントを役割ごとに配置し、独立したサブタスクを並列実行することで全体のスループットを向上させます。

graph TD
  SINGLE[単一エージェント] --> LIMIT1[コンテキスト長の上限]
  SINGLE --> LIMIT2[専門性の限界]
  SINGLE --> LIMIT3[並列性の欠如]

  MULTI[マルチエージェント] --> SOL1[タスク分割でコンテキスト制約を回避]
  MULTI --> SOL2[専門化エージェントによる精度向上]
  MULTI --> SOL3[並列実行によるスループット向上]

パターン1: Orchestrator-Worker(オーケストレーター・ワーカー)

Section titled “パターン1: Orchestrator-Worker(オーケストレーター・ワーカー)”

Orchestrator-Worker パターンとは、1つのオーケストレーターエージェントが複数のワーカーエージェントを管理・指揮する構造です。オーケストレーターはタスク全体の計画立案・分割・ワーカーへの指示・結果の統合を担います。ワーカーは各自の専門的なサブタスクを実行し、結果をオーケストレーターに返します。

sequenceDiagram
  participant User as ユーザー
  participant Orch as オーケストレーター
  participant W1 as ワーカーA
  participant W2 as ワーカーB
  participant W3 as ワーカーC

  User->>Orch: タスク依頼(例:競合調査レポート)
  Orch->>W1: サブタスクA(競合A の製品分析)
  Orch->>W2: サブタスクB(競合B の価格調査)
  Orch->>W3: サブタスクC(市場トレンド収集)
  W1-->>Orch: 結果A
  W2-->>Orch: 結果B
  W3-->>Orch: 結果C
  Orch->>User: 統合レポート

適したユースケース:

  • 複雑なコーディングタスク(機能実装・テスト作成・ドキュメント生成を並列で実施)
  • 競合調査・市場分析レポートの作成(複数情報源から同時に収集・分析)
  • 大規模なデータ処理パイプライン(複数データセットの並列集計・統合)

Claude Agent SDK での実装例(Python 擬似コード):

from anthropic import Anthropic

client = Anthropic()

def orchestrator_agent(task: str) -> str:
    """オーケストレーター: タスクを分解してワーカーに委譲"""
    # オーケストレーターがサブタスクを計画する
    plan_response = client.messages.create(
        model="claude-opus-4-5",
        max_tokens=1024,
        system="あなたはタスク分解の専門家です。入力タスクをサブタスクに分解してください。",
        messages=[{"role": "user", "content": f"次のタスクを並列実行できるサブタスクに分解: {task}"}]
    )
    subtasks = parse_subtasks(plan_response.content[0].text)

    # 各サブタスクをワーカーに委譲(並列実行)
    results = []
    for subtask in subtasks:
        result = worker_agent(subtask)
        results.append(result)

    # 結果を統合
    return synthesize_results(results)

def worker_agent(subtask: str) -> str:
    """ワーカー: 割り当てられたサブタスクを実行"""
    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=512,
        system="あなたは指定されたサブタスクを正確に実行する専門エージェントです。",
        messages=[{"role": "user", "content": subtask}]
    )
    return response.content[0].text

パターン2: Pipeline(パイプライン)

Section titled “パターン2: Pipeline(パイプライン)”

Pipeline パターンとは、各エージェントが出力を次のエージェントの入力として渡す直列構造です。前段エージェントの結果が次段エージェントの入力となり、処理が段階的に洗練されます。各ステージは明確に定義された変換処理を担います。

graph LR
  INPUT[入力] --> A1[エージェント1\n 下書き作成]
  A1 --> A2[エージェント2\n 事実確認・校正]
  A2 --> A3[エージェント3\n スタイル統一]
  A3 --> A4[エージェント4\n 翻訳]
  A4 --> OUTPUT[最終出力]

適したユースケース:

  • コンテンツ制作パイプライン(下書き作成 → 事実確認 → 校正 → スタイル統一 → 翻訳)
  • データ変換・ETL処理(抽出 → クレンジング → 変換 → 検証 → ロード)
  • コードレビューパイプライン(生成 → 静的解析 → テスト作成 → ドキュメント生成)

各ステージのエージェント役割定義の考え方:

各ステージのエージェントには、単一責任の原則(Single Responsibility Principle)を適用します。1つのエージェントが担う変換処理は1種類に限定し、入力フォーマットと出力フォーマットを明確に定義します。これにより、各ステージの品質評価と置き換えが独立して行えます。また、各ステージのシステムプロンプトには「前段の出力を受け取り、次の処理を実施して出力する」という流れを明示し、コンテキストの連続性を保ちます。

def run_pipeline(input_text: str) -> str:
    """パイプラインの各ステージを順番に実行"""
    stages = [
        ("下書き作成エージェント", "与えられたトピックについて下書きを作成してください。"),
        ("校正エージェント", "以下の文章を校正し、事実の誤りを修正してください。"),
        ("翻訳エージェント", "以下の日本語テキストを英語に翻訳してください。"),
    ]

    current_content = input_text
    for stage_name, system_prompt in stages:
        response = client.messages.create(
            model="claude-sonnet-4-5",
            max_tokens=1024,
            system=system_prompt,
            messages=[{"role": "user", "content": current_content}]
        )
        current_content = response.content[0].text

    return current_content

パターン3: Specialist Pool(スペシャリストプール)

Section titled “パターン3: Specialist Pool(スペシャリストプール)”

Specialist Pool パターンとは、ルーターエージェントが入力の内容を判断し、最も適した専門化エージェントに処理を振り分ける構造です。各専門エージェントは特定のドメインや処理種別に最適化されており、汎用エージェントよりも高い精度を発揮します。

graph TD
  INPUT[入力] --> ROUTER[ルーターエージェント]
  ROUTER --> |技術的質問| SPEC_TECH[技術サポートエージェント]
  ROUTER --> |請求・支払い| SPEC_BILL[課金サポートエージェント]
  ROUTER --> |英語| SPEC_EN[英語対応エージェント]
  ROUTER --> |フランス語| SPEC_FR[フランス語対応エージェント]
  ROUTER --> |その他| SPEC_GEN[汎用エージェント]
  SPEC_TECH --> OUTPUT[回答]
  SPEC_BILL --> OUTPUT
  SPEC_EN --> OUTPUT
  SPEC_FR --> OUTPUT
  SPEC_GEN --> OUTPUT

適したユースケース:

  • カスタマーサポートシステム(技術的質問・課金・クレーム・一般問い合わせを専門エージェントで処理)
  • 多言語処理(言語を判定して母語の専門エージェントに振り分け)
  • 法的・医療・財務文書の分析(文書種別ごとに専門知識を持つエージェントを配置)

ルーティングロジックの設計パターン:

ルーターエージェントの設計には3つのアプローチがあります。第一はルールベースルーティングで、キーワードや正規表現に基づいて機械的に振り分けます。高速で予測可能ですが、複雑な入力には対応が難しくなります。第二はLLMベースルーティングで、ルーターエージェント自体がLLMを使って入力の意図を理解し、振り分け先を判断します。柔軟性が高く複雑な入力にも対応できますが、レイテンシとコストが増加します。第三はハイブリッドルーティングで、まずルールベースで高速に判定し、不明な場合のみLLMに委ねます。多くのプロダクション環境ではこのアプローチが有効です。

def router_agent(user_input: str) -> str:
    """ルーター: 入力を分析して適切な専門エージェントに振り分け"""
    routing_response = client.messages.create(
        model="claude-haiku-4-5",
        max_tokens=128,
        system="""入力を分析し、適切なカテゴリを1つ返してください。
        カテゴリ: [technical, billing, general, language_en, language_fr]
        JSONフォーマットで返してください: {"category": "..."}""",
        messages=[{"role": "user", "content": user_input}]
    )
    category = parse_category(routing_response.content[0].text)

    # カテゴリに応じた専門エージェントを呼び出し
    specialist_map = {
        "technical": technical_specialist,
        "billing": billing_specialist,
        "general": general_specialist,
    }
    specialist = specialist_map.get(category, general_specialist)
    return specialist(user_input)

Swarm パターンとは、中央集権的なオーケストレーターを持たず、複数の自律的なエージェントが相互に協調しながら問題を解決する構造です。各エージェントは状態を共有し、必要に応じて他のエージェントに処理を委譲(ハンドオフ)できます。群(スウォーム)全体として適応的な問題解決を実現します。

graph TD
  SHARED[共有状態\n(コンテキスト・進捗・成果物)]

  A1[エージェント1\n コード分析] <-->|ハンドオフ| A2[エージェント2\n テスト生成]
  A2 <-->|ハンドオフ| A3[エージェント3\n ドキュメント生成]
  A1 <-->|ハンドオフ| A3
  A1 --> SHARED
  A2 --> SHARED
  A3 --> SHARED
  SHARED --> A1
  SHARED --> A2
  SHARED --> A3

適したユースケース:

  • 大規模コードリファクタリング(各エージェントがモジュールを独立して解析・改善し、共有状態に結果を書き込む)
  • 並列リサーチ(複数エージェントが異なる情報源を同時に調査し、発見を共有状態に集約)
  • 自律的なソフトウェアテスト(テスト生成・実行・デバッグを複数エージェントが協調して処理)

Claude Code Level 10 との接続:

Claude Code のLevel 10(高度なエージェント自律性レベル)では、このSwarmパターンが基盤として使われています。Claude Code が複数のサブエージェントを生成し、大規模なリポジトリのリファクタリングやマイグレーションを並列で実行する際、各サブエージェントは独立したコンテキストを持ちつつ、共有のファイルシステムや状態ストアを通じて協調します。Swarmパターンを理解することで、Claude Code の高度な自律動作の仕組みを把握できます。

class SwarmAgent:
    """スウォームエージェント: 共有状態を通じて他エージェントと協調"""

    def __init__(self, name: str, specialization: str, shared_state: dict):
        self.name = name
        self.specialization = specialization
        self.shared_state = shared_state

    def process(self, task: str) -> str:
        # 共有状態から現在の進捗を取得
        context = self.shared_state.get("context", "")

        response = client.messages.create(
            model="claude-sonnet-4-5",
            max_tokens=1024,
            system=f"あなたは{self.specialization}の専門エージェントです。共有状態を参照して作業してください。",
            messages=[{
                "role": "user",
                "content": f"共有状態: {context}\n\nタスク: {task}"
            }]
        )

        result = response.content[0].text
        # 共有状態を更新
        self.shared_state[f"{self.name}_result"] = result
        return result

適切なパターンを選ぶには、タスクの性質・依存関係・並列性・専門性の4軸で評価します。

graph TD
  START[タスクを受け取る] --> Q1{タスクを\nサブタスクに\n分解できるか?}

  Q1 -->|No| SINGLE[単一エージェントで処理]
  Q1 -->|Yes| Q2{サブタスク間に\n依存関係があるか?}

  Q2 -->|Yes, 直列依存| PIPELINE[Pipeline パターン]
  Q2 -->|No, 独立| Q3{中央集権的な\n管理が必要か?}

  Q3 -->|Yes| Q4{専門化された\nルーティングが必要か?}
  Q3 -->|No| SWARM[Swarm パターン]

  Q4 -->|Yes, 振り分け型| SPECIALIST[Specialist Pool パターン]
  Q4 -->|No, 統合型| ORCHESTRATOR[Orchestrator-Worker パターン]

パターン選定基準表:

評価軸Orchestrator-WorkerPipelineSpecialist PoolSwarm
タスクの性質分割・統合が必要段階的変換種別ルーティング大規模・複雑
サブタスク依存関係並列・独立直列・順序依存独立(種別依存)動的・適応的
並列性高(ワーカー並列)低(直列処理)中(種別ごと)高(全エージェント並列)
専門性中(汎用ワーカー可)中(各ステージ専門化)高(ドメイン特化)中〜高(適応的)
実装複雑度低〜中
推奨モデル規模Opus(Orch)+ Sonnet(Worker)Sonnet全段Haiku(Router)+ 専門モデルSonnet全エージェント

エージェント間のコンテキスト受け渡しは、マルチエージェントシステムの品質に直接影響します。各エージェントに渡すコンテキストは「最小限かつ必要十分」にする必要があります。全コンテキストをそのまま渡すとトークン消費が増大し、関係のない情報によって判断精度が低下します。各エージェントの役割に応じて、前段の結果から必要な情報のみを抽出・要約してから渡すサマリーパターンが有効です。また、エージェント間でスキーマ化された構造化データ(JSON)を受け渡すことで、解析エラーを防ぎ信頼性を高めます。

エラーハンドリングと部分失敗の対処

Section titled “エラーハンドリングと部分失敗の対処”

マルチエージェントシステムでは、個々のエージェントが失敗する可能性を前提に設計します。Pipeline パターンでは前段エージェントの失敗が後段全体に波及するため、各ステージでのエラー検出と fallback 処理が不可欠です。Orchestrator-Worker パターンでは、ワーカーの部分失敗を許容し、成功したワーカーの結果だけで最終出力を生成するグレースフルデグレードが重要です。具体的には、リトライロジック(指数バックオフ付き)、タイムアウト設定、失敗ワーカーの結果を「未取得」として扱う処理を実装します。

コスト・レイテンシのトレードオフ

Section titled “コスト・レイテンシのトレードオフ”

マルチエージェントシステムはAPI呼び出しが増加するため、コストとレイテンシの管理が重要になります。ルーターエージェントには高速・低コストの Claude Haiku を使い、複雑なタスクを担うエージェントには Claude Opus を使うなど、役割に応じたモデルの使い分けがコスト最適化の基本です。また、結果のキャッシュ(同一入力に対する再計算防止)と、並列実行による全体レイテンシの削減を組み合わせることで、コストとスピードのバランスを取ります。プロダクション環境では、各エージェントの実行時間・コスト・精度をモニタリングし、継続的に最適化します。


マルチエージェントシステムの4パターンを整理します。

  • Orchestrator-Worker: 複雑なタスクを分割・並列実行し、中央のオーケストレーターが統合する。調査レポート作成や複雑なコーディングタスクに適する。
  • Pipeline: 各エージェントが直列で処理を引き継ぎ、段階的に出力を洗練する。コンテンツ制作やデータ変換フローに適する。
  • Specialist Pool: ルーターが入力種別に応じて専門化エージェントに振り分ける。カスタマーサポートや多言語処理に適する。
  • Swarm: 中央管理なしに自律エージェントが協調する。大規模リファクタリングや並列リサーチに適する。

パターン選定では「タスクを分解できるか」「依存関係の方向」「中央集権管理の必要性」「専門化の要否」の4つの問いに順番に答えることで、最適なパターンに到達できます。


このページの外部仕様・背景情報は、参考文献を参照してください。[1][2]

  1. Anthropic, Claude Code documentation
  2. Anthropic, Claude API documentation
クイズ