◉ANTIGRAVITY LABEN
記事一覧/Agents & Manager
◈ Agents & Manager/2026-04-17上級

Antigravity マルチエージェント設計の実践パターン — 複雑なワークフローを壊れにくく作る

Antigravity でマルチエージェントワークフローを設計する際の実践パターンを解説。オーケストレーター構成・状態管理・エラー回復・デバッグ手法まで、壊れにくいシステムの作り方を具体的に紹介します。

マルチエージェント41Antigravity386ワークフロー設計3エラーハンドリング3状態管理アーキテクチャ9

Antigravity でシングルエージェントのワークフローを動かし始めると、ある段階で「これ以上は無理だ」と感じる瞬間があります。タスクが複雑になり、コンテキストが膨らみ、エージェントが出力する内容の一貫性が下がってくる。そのとき、マルチエージェント構成に移行するかどうかを判断しなければなりません。

ただし、何でもマルチエージェントにすればよいわけではありません。エージェントを増やすと調整コストが増え、デバッグが難しくなり、壊れ方が複雑になります。マルチエージェント構成に移行すべきタイミングと、移行した後に壊れにくいシステムを作るための設計パターンを順番にご紹介します。


シングルエージェントの限界を認識する

マルチエージェントに移行する前に、本当にシングルエージェントでは限界かを確認してください。多くの場合、適切なプロンプト設計と段階的な処理で解決できます。

移行を検討すべきサインは3つあります。

コンテキストウィンドウの圧迫: 処理する情報量が多く、エージェントの出力品質が中盤から下がり始める。長い処理を途中でリセットしても同じ問題が起きる場合は、そもそも1つのエージェントが処理すべき量を超えています。

責任の混在: 「データ取得→分析→フォーマット→通知」のような異なる性質のタスクを1つのエージェントが担うと、プロンプトが複雑になりすぎて制御しにくくなります。責任を分離すると、それぞれのエージェントの動作が予測しやすくなります。

並列化の必要性: 独立したサブタスクを順番に処理するより、並列実行したほうが明らかに速い。かつ、待ち時間がユーザー体験に影響している場合。

逆に言えば、これらに当てはまらないなら、まずシングルエージェントを磨くべきです。


オーケストレーター・ワーカーパターン

最も基本的なマルチエージェント構成です。1つの「オーケストレーター」が全体の計画を立て、「ワーカー」エージェントに具体的なタスクを委任します。

// オーケストレーターの擬似コード(Antigravity ワークフロー)
const orchestrator = {
  name: "research_orchestrator",
  prompt: `
    あなたはリサーチプロジェクトのオーケストレーターです。
    ユーザーのリクエストを受け取り、以下のワーカーに適切なタスクを割り当ててください。
    
    利用可能なワーカー:
    - web_researcher: ウェブ検索と情報収集
    - data_analyzer: 収集データの分析と構造化
    - report_writer: 最終レポートの作成
    
    タスクの割り当ては JSON で返してください:
    {
      "tasks": [
        { "worker": "web_researcher", "task": "...", "priority": 1 },
        { "worker": "data_analyzer", "task": "...", "priority": 2 }
      ]
    }
  `
};

このパターンの重要なポイントは、オーケストレーターが具体的な処理を一切行わないことです。オーケストレーターは「何を誰に頼むか」だけを決める。実際の処理はすべてワーカーが担います。

オーケストレーターに実処理を混ぜると、責任が曖昧になり、デバッグが難しくなります。


状態管理: マルチエージェントの最大の落とし穴

マルチエージェントシステムで一番問題になるのは状態管理です。エージェントAが生成した中間結果をエージェントBが使い、その結果をエージェントCが参照する — このチェーンのどこかで状態が壊れると、最終出力が静かに間違います。

Antigravity でワークフローを設計する際に、私が使っているパターンを紹介します。

イミュータブルな中間状態

各エージェントの出力は上書きせず、ステップごとに保存します。

// NG: 状態を上書きする
workflow.state.data = await researcher.run(query);
workflow.state.data = await analyzer.run(workflow.state.data); // 元データが消える
 
// OK: ステップごとに保存
workflow.state.research_results = await researcher.run(query);
workflow.state.analysis_results = await analyzer.run(workflow.state.research_results);

この設計だと、後から「どのエージェントが何を入力として受け取り、何を出力したか」が追跡できます。バグが発生したときの診断が格段に楽になります。

バリデーション層の挿入

エージェント間のデータ受け渡しには、必ずバリデーションを入れます。

const researchOutput = await researcher.run(query);
 
// バリデーション
if (\!researchOutput.sources || researchOutput.sources.length === 0) {
  throw new WorkflowError(
    "researcher_output_invalid",
    "sources が空です。クエリを調整して再試行してください",
    { query, output: researchOutput }
  );
}
 
const analysisInput = {
  sources: researchOutput.sources,
  context: researchOutput.summary,
};

バリデーションなしでデータを流すと、エラーが何ステップも後になって発生し、根本原因の特定が難しくなります。


エラー回復設計

マルチエージェントシステムでは、「どのエージェントがどんな理由で失敗したか」によって回復戦略が変わります。一律に「リトライ」するのではなく、失敗の性質に応じた戦略を持つ点が肝心です。

async function runWithRecovery(agent, input, options = {}) {
  const {
    maxRetries = 3,
    retryDelay = 1000,
    fallbackAgent = null,
    onFailure = null,
  } = options;
 
  let lastError;
  
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await agent.run(input);
    } catch (error) {
      lastError = error;
      
      // リトライ不要なエラー(入力が間違っている場合など)
      if (error.type === "invalid_input") {
        break;
      }
      
      // レート制限は待機してリトライ
      if (error.type === "rate_limit") {
        await sleep(retryDelay * attempt * 2);
        continue;
      }
      
      // それ以外は通常のリトライ
      if (attempt < maxRetries) {
        await sleep(retryDelay * attempt);
      }
    }
  }
  
  // フォールバックエージェントが設定されていれば試みる
  if (fallbackAgent) {
    try {
      return await fallbackAgent.run(input);
    } catch (fallbackError) {
      // フォールバックも失敗
    }
  }
  
  // カスタム失敗ハンドラー
  if (onFailure) {
    return onFailure(lastError, input);
  }
  
  throw lastError;
}

フォールバックエージェントの設計は特に有効です。例えば、高精度だが遅いエージェントと、精度は低いが速いエージェントのペアを用意しておき、タイムアウト時に後者に切り替えるパターンは実際のプロダクションで効果的でした。


並列実行と同期

独立したサブタスクを並列実行する場合、結果の統合方法を事前に決めておく必要があります。

// 並列実行の基本パターン
async function runParallelResearch(topics) {
  const tasks = topics.map(topic => ({
    id: topic.id,
    promise: runWithRecovery(
      researchAgent,
      { topic: topic.query },
      { maxRetries: 2, fallbackAgent: lightResearchAgent }
    )
  }));
 
  // allSettled で部分的な失敗を許容する
  const results = await Promise.allSettled(
    tasks.map(t => t.promise)
  );
 
  const successful = [];
  const failed = [];
 
  results.forEach((result, index) => {
    if (result.status === "fulfilled") {
      successful.push({ id: tasks[index].id, data: result.value });
    } else {
      failed.push({ id: tasks[index].id, error: result.reason });
    }
  });
 
  // 最低限の成功数を確認
  if (successful.length < Math.ceil(topics.length * 0.7)) {
    throw new WorkflowError(
      "insufficient_results",
      `並列処理で十分な結果が得られませんでした(成功: ${successful.length}/${topics.length})`
    );
  }
 
  return { successful, failed };
}

Promise.all ではなく Promise.allSettled を使う理由は、1つの失敗で全体を止めないためです。実際の並列リサーチワークフローでは、10トピック中1〜2トピックが失敗しても残りを使って続行できる方が、全件成功を要求するより実用的です。


デバッグ: マルチエージェント特有の問題

マルチエージェントシステムのバグには特有のパターンがあります。

「静かな劣化」問題: 出力が完全に壊れているわけではなく、じわじわと品質が下がる。特定のエージェントがコンテキストを誤解していても、後段のエージェントがある程度補正するため気づきにくい。

診断方法: 各エージェントの入出力を個別にログに記録し、期待する出力形式との差異を計測します。品質メトリクスを1〜2個設定して追跡すると、どのエージェントで劣化が始まるかが特定できます。

「非決定的な失敗」問題: 同じ入力でも5回中1回失敗します。並列実行やタイムアウト絡みの問題によく見られます。

診断方法: 同じ入力で10〜20回実行し、失敗率とタイミングを記録します。特定の条件(負荷が高いとき、特定の入力パターンなど)で失敗率が上がるなら、その条件を絞り込みます。

「コンテキスト汚染」問題: 前のワークフロー実行の状態が次の実行に影響します。特にステートフルなエージェントを使っているときに起きます。

診断方法: ワークフロー開始時に状態を完全にリセットしているか確認します。テストでは、意図的に「汚染された状態」から始めて、期待通りにリセットされるかを検証します。


設計のまとめ

Antigravity でマルチエージェントシステムを作るときに、私が戻ってくる原則が3つあります。

  1. 責任の境界を明確に: オーケストレーターは計画のみ、ワーカーは実行のみ。混ぜありません。

  2. 状態は追跡可能に: 中間状態を上書きしありません。バリデーションをエージェント間の境界に入れる。

  3. 失敗を前提に設計する: リトライ・フォールバック・部分的な成功の許容を最初から組み込む。後から追加するのは難しい。

複雑なワークフローを壊れにくく保つことが、マルチエージェント設計の核心です。エージェントの数を増やすより、それぞれのエージェントの責任を明確にする方が、長期的に管理しやすいシステムになります。

さらに踏み込んだ内容 — 動的なエージェント生成、ワークフローの自己修復、プロダクション監視の設計 — は Antigravity Lab のメンバーシップ記事で扱っています。興味があればぜひご覧ください。

シェア

お読みいただきありがとうございます

Antigravity Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

◈ Agents & Manager2026-04-27
AgentKit 2.0 で作ったAIエージェントを売る5つの収益化パス — 個人開発者が選ぶべき販売チャネルの判断軸
Antigravity で作ったAIエージェントを個人開発者がどう売るか。マーケットプレイス、自社サイト、SaaS 組み込み、受託からの商品化、サブスクの5チャネルを、手取り・顧客との距離・立ち上がりの速さで比べ、Stripe の課金コードと利用上限の設計まで書き残します。
◈ Agents & Manager2026-04-14
Antigravity × AgentKit 2.0 × Stripe でつくるAIエージェント SaaS — 個人開発者が本番運用まで到達する実装ガイド
AgentKit 2.0 と Stripe を組み合わせ、サブスクリプション収益を得られる AI エージェント SaaS を Antigravity で構築する手順をまとめました。アーキテクチャ設計から課金・Webhook の冪等性、同時実行スロットが漏れる Redis 実装の穴まで、個人開発で実際につまずいた箇所を中心に整理しています。
◈ Agents & Manager2026-04-07
複数の専門エージェントを一人で束ねる — Antigravity マルチエージェント・オーケストレーションの実務設計
Antigravityの高度なマルチエージェント開発を体系的に習得。Manager Surface・Sub-agents・タスク分割からパイプライン設計、本番環境のチェックリストまで、実践的なアーキテクチャを網羅的に解説。