GEMINI LABEN
NANOLITE — Nano Banana 2 Liteが登場しました。Googleで最も速く、最もコスト効率の高いGemini Imageモデルで、軽量な画像生成を安く回したい用途に向いていますOMNIFLASH — Gemini Omni Flashがpublic previewになりました。ネイティブにマルチモーダルなモデルで、企業や開発者が独自の動的な動画ワークフローを構築できますAGENTS — Managed Agentsが拡張されました。background: trueでサーバー側の非同期実行とポーリング、リモートMCPサーバー連携、対話をまたぐ認証情報のリフレッシュに対応しますMEMORY — Memory BankのIngestEvents APIが一般提供になりました。イベントの取り込みとメモリ生成を分離し、コンテンツを継続的にストリームできますTHROUGHPUT — Provisioned Throughputで、同一モデル・同一リージョンに対して最大7件の保留オーダーを提出できるようになりましたDEPRECATE — 画像生成モデルは8月17日に、Gemini Enterprise Agent PlatformのGrok 4.1系は8月20日に停止される予定ですNANOLITE — Nano Banana 2 Liteが登場しました。Googleで最も速く、最もコスト効率の高いGemini Imageモデルで、軽量な画像生成を安く回したい用途に向いていますOMNIFLASH — Gemini Omni Flashがpublic previewになりました。ネイティブにマルチモーダルなモデルで、企業や開発者が独自の動的な動画ワークフローを構築できますAGENTS — Managed Agentsが拡張されました。background: trueでサーバー側の非同期実行とポーリング、リモートMCPサーバー連携、対話をまたぐ認証情報のリフレッシュに対応しますMEMORY — Memory BankのIngestEvents APIが一般提供になりました。イベントの取り込みとメモリ生成を分離し、コンテンツを継続的にストリームできますTHROUGHPUT — Provisioned Throughputで、同一モデル・同一リージョンに対して最大7件の保留オーダーを提出できるようになりましたDEPRECATE — 画像生成モデルは8月17日に、Gemini Enterprise Agent PlatformのGrok 4.1系は8月20日に停止される予定です
記事一覧/高度な活用
高度な活用/2026-04-11上級

Google A2A プロトコル × Gemini API でエージェントを相互接続する — 設計から Cloud Run 運用まで

Agent2Agent (A2A) プロトコルと Gemini API を組み合わせ、フレームワークをまたぐエージェント協調を実装します。エージェントカード設計・3つの協調パターンの実測比較・Cloud Run 運用の勘所まで動くコード付きで扱います。

a2a2agent2agentgemini-api279multi-agentadk2マルチエージェント2プロトコル

プレミアム記事

夜間に走らせている記事生成の処理を、あるときエージェント3本に分けました。トピック選定、本文執筆、品質チェック。役割を分ければ見通しが良くなるはずでした。

分けた翌週、私は自分の書いたグルーコードの前で手が止まりました。個人開発では繋ぎ目もすべて自分の担当で、誰かに引き渡す先はありません。3本はそれぞれ別のライブラリで書かれていて、繋ぎ目ごとに JSON の形を合わせ、タイムアウトを決め、失敗時の再送を書いている。エージェント本体より、繋ぎ目のほうが長くなっていたのです。

Google が公開した Agent2Agent (A2A) プロトコル は、この繋ぎ目そのものを標準化する試みです。異なるフレームワーク、異なるプロバイダーで作られたエージェントが、統一された HTTP ベースの仕様で会話する。相手の内部実装を知らないまま協調できる。

ここでは A2A の仕様を押さえたうえで、Gemini API・ADK と組み合わせた実装を FastAPI で組み立て、Cloud Run に載せるところまでを追います。後半には、実際に回して初めて見えてきた運用の勘所を置きました。

想定する読者:

  • Gemini API を使ったエージェント開発の経験がある方
  • 複数エージェントの協調システムを構築したい方
  • A2A プロトコルを本番環境に適用したい方

事前知識として、Gemini API Function Calling:ツール統合と実践的な活用法ADKに頼らない Gemini API カスタムエージェントループ設計ガイド に目を通しておくと、この記事の設計判断が追いやすくなります。


A2A プロトコルの仕様と核心概念

プロトコルの基本構造

A2A プロトコルは、HTTP/JSON-RPC 2.0 をベースにした軽量な仕様です。各エージェントは「A2A サーバー」として動作し、標準化されたエンドポイントを公開します。

A2A の主要コンポーネントは以下の 4 つです。

① エージェントカード(Agent Card): エージェントの能力・エンドポイント・認証方式を記述した JSON メタデータです。/.well-known/agent.json で公開され、クライアントはここを起点にエージェントを「発見」します。

② タスク(Task): クライアントがエージェントに依頼する作業単位です。一意の ID を持ち、submitted → working → completed / failed というライフサイクルを管理します。

③ アーティファクト(Artifact): タスクの成果物です。テキスト・JSON・ファイルなど複数の MIME タイプをサポートし、ストリーミング中は逐次追記される形式をとります。

④ メッセージ(Message): タスク実行中のやり取りです。ユーザーとエージェント間のマルチターン対話や、エージェント間の中間連絡に使われます。

通信フロー

クライアント                    A2A サーバー(エージェント)
    |                                      |
    |--- GET /.well-known/agent.json ----> |  ① エージェントカード取得
    |<-- {"name": "...", "skills": [...]} -|
    |                                      |
    |--- POST /tasks/send ---------------> |  ② タスク送信
    |    {"id": "task-123",                |
    |     "message": {"role": "user", ...}}|
    |<-- {"status": {"state": "submitted"}}|
    |                                      |
    |--- GET /tasks/get?id=task-123 -----> |  ③ ステータス確認(ポーリング)
    |<-- {"status": {"state": "completed"},|
    |     "artifacts": [...]}              |
    |                                      |
    |  または SSE でリアルタイム受信       |
    |--- POST /tasks/sendSubscribe ------> |
    |<== data: {"type": "artifact", ...}  --|(ストリーミング)
    |<== data: {"type": "status", ...} ---|

エージェントカードの設計

エージェントカードは、エージェントを発見するための「名刺」であり、他エージェントが何を依頼できるかを判断する根拠になります。設計の質が協調システム全体の使いやすさを左右します。

{
  "name": "データ分析エージェント",
  "description": "CSV・JSON データを統計分析し、ビジネス洞察と可視化を提供します",
  "url": "https://data-agent.example.run.app",
  "version": "1.2.0",
  "capabilities": {
    "streaming": true,
    "pushNotifications": false
  },
  "authentication": {
    "schemes": ["Bearer"]
  },
  "skills": [
    {
      "id": "analyze-csv",
      "name": "CSV 統計分析",
      "description": "CSV ファイルを受け取り、平均・分散・相関係数などの統計量と主要な洞察を返します",
      "inputModes": ["text", "file"],
      "outputModes": ["text", "data"]
    },
    {
      "id": "generate-chart",
      "name": "データビジュアライゼーション",
      "description": "数値データから最適なグラフ(棒・折れ線・散布図)を自動選択し生成します",
      "inputModes": ["data"],
      "outputModes": ["file"]
    }
  ]
}

設計のポイント:

  • description はエージェントの専門性を 1 文で明確に述べる
  • skills[].description は何を入力すると何が返ってくるかを具体的に書く
  • inputModes / outputModes は対応形式を正確に列挙する

環境準備と A2A サーバーの基本実装

必要なパッケージ

# Google ADK(A2A サーバー機能を含む)
pip install google-adk
 
# Gemini API クライアント
pip install google-generativeai
 
# Web サーバーフレームワーク
pip install fastapi uvicorn httpx pyjwt

最小構成の A2A サーバー

# a2a_server.py
import uuid
import asyncio
from datetime import datetime
from typing import Optional
from fastapi import FastAPI, HTTPException, BackgroundTasks
from pydantic import BaseModel
import google.generativeai as genai
 
# Gemini API 初期化
# ⚠️ API キーは必ず環境変数から取得すること
import os
genai.configure(api_key=os.environ["GEMINI_API_KEY"])
model = genai.GenerativeModel("gemini-2.5-pro")
 
app = FastAPI(title="Gemini A2A Agent", version="1.0.0")
 
# タスクストア(本番では Redis または Firestore を推奨)
tasks: dict[str, dict] = {}
 
# =====================
# エージェントカード
# =====================
AGENT_CARD = {
    "name": "Gemini 汎用分析エージェント",
    "description": "Gemini 2.5 Pro を活用したテキスト分析・要約・構造化データ抽出エージェント",
    "url": "https://your-agent.run.app",
    "version": "1.0.0",
    "capabilities": {
        "streaming": True,
        "pushNotifications": False
    },
    "authentication": {"schemes": ["Bearer"]},
    "skills": [
        {
            "id": "analyze-text",
            "name": "テキスト分析",
            "description": "テキストを分析し、要約・洞察・構造化 JSON を返します",
            "inputModes": ["text"],
            "outputModes": ["text", "data"]
        }
    ]
}
 
# =====================
# エンドポイント定義
# =====================
 
@app.get("/.well-known/agent.json")
async def get_agent_card():
    """エージェントカードを公開する(A2A 必須エンドポイント)"""
    return AGENT_CARD
 
class TaskRequest(BaseModel):
    id: str
    message: dict
    sessionId: Optional[str] = None
 
@app.post("/tasks/send")
async def send_task(req: TaskRequest, background_tasks: BackgroundTasks):
    """タスクを非同期で受け付け、処理を開始する"""
    task_id = req.id
 
    tasks[task_id] = {
        "id": task_id,
        "status": {"state": "submitted", "timestamp": datetime.utcnow().isoformat()},
        "artifacts": [],
        "history": [req.message]
    }
 
    background_tasks.add_task(process_with_gemini, task_id, req.message)
    return tasks[task_id]
 
@app.get("/tasks/get")
async def get_task(id: str):
    """タスクの現在状態を取得する"""
    if id not in tasks:
        raise HTTPException(status_code=404, detail="Task not found")
    return tasks[id]
 
async def process_with_gemini(task_id: str, message: dict):
    """Gemini API でタスクを処理する内部関数"""
    try:
        tasks[task_id]["status"]["state"] = "working"
 
        # メッセージからテキスト部分を結合
        user_text = " ".join(
            part.get("text", "")
            for part in message.get("parts", [])
            if part.get("type") == "text"
        )
 
        # Gemini API 呼び出し(ブロッキングなので asyncio.to_thread で実行)
        response = await asyncio.to_thread(model.generate_content, user_text)
 
        tasks[task_id]["status"] = {
            "state": "completed",
            "timestamp": datetime.utcnow().isoformat()
        }
        tasks[task_id]["artifacts"] = [{
            "name": "analysis_result",
            "parts": [{"type": "text", "text": response.text}]
        }]
 
    except Exception as e:
        tasks[task_id]["status"] = {
            "state": "failed",
            "message": {"code": -1, "message": str(e)},
            "timestamp": datetime.utcnow().isoformat()
        }
        print(f"❌ タスク {task_id} 失敗: {e}")

期待する動作確認:

# サーバー起動
uvicorn a2a_server:app --reload
 
# エージェントカード確認
curl http://localhost:8000/.well-known/agent.json
 
# タスク送信
curl -X POST http://localhost:8000/tasks/send \
  -H "Content-Type: application/json" \
  -d '{"id":"task-001","message":{"role":"user","parts":[{"type":"text","text":"AI エージェントとは何かを 3 行で説明してください"}]}}'
 
# 結果取得
curl "http://localhost:8000/tasks/get?id=task-001"
# → {"status":{"state":"completed"},"artifacts":[{"parts":[{"type":"text","text":"..."}]}]}

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

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
エージェントカード・タスクライフサイクル・アーティファクトという A2A の骨格を、FastAPI の動くコードとして最後まで組み立てられます
パイプライン・ファンアウト・動的ルーティングの3パターンを同一タスクで実測し、レイテンシとコストから選び分ける基準を示します
エージェントカードのキャッシュ不整合、タスク再送のべき等性、Managed Agents との使い分けなど、公式ドキュメントに載らない運用の勘所をまとめました
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

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

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

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

関連記事

高度な活用2026-04-26
ADKに頼らない Gemini API カスタムエージェントループ設計ガイド — ツール呼び出し・メモリ・並列実行の本番実装
Google ADKを使わずにGemini APIでカスタムエージェントループを実装する完全ガイド。ツール呼び出し・会話メモリ・並列実行・エラー回復まで、本番環境で稼働する自律AIエージェントの設計パターンを詳解します。
高度な活用2026-07-16
システム指示を何語で書くか — 現地語のプロンプトが多数になったアプリで3方式を測り直す
システム指示を英語で固定するか、ユーザーの言語に訳して渡すか。countTokens で言語別の入力トークンを実測し、出力言語の一致率とスキーマ遵守率を並べて、9トークンで足りる場所と訳すべき場所を切り分けます。
高度な活用2026-07-09
無料ユーザー一人あたりのトークン予算を決める — AdMob 収益と AI 機能のコストを釣り合わせる設計
レート制限は秒あたりを守りますが、月末の請求は守ってくれません。広告収益から一人あたりのトークン予算を逆算し、呼び出しラッパー一か所で台帳を作り、ソフトキャップで段階的に降格させ、上位1%の消費比率で濫用を検知するまでを、動くコードとともにまとめます。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →