ストーリー
A2Aプロトコルとは
概要
A2A(Agent-to-Agent)プロトコルは、Googleが2025年に発表したエージェント間通信の標準規格です。異なるフレームワーク、異なるベンダーのエージェントが相互運用できることを目指しています。
A2Aの基本構造:
[クライアントエージェント] ←→ [リモートエージェント]
│ │
│ 1. Agent Card を取得 │
│ ←────────────────────── │
│ │
│ 2. Task を送信 │
│ ──────────────────────→ │
│ │
│ 3. 結果を受信 │
│ ←────────────────────── │
A2Aの主要コンポーネント
| コンポーネント | 役割 | 例 |
|---|---|---|
| Agent Card | エージェントの能力・スキルを宣言するメタデータ | 「注文管理ができます」 |
| Task | エージェントに処理を依頼するリクエスト | 「注文ORD-12345を検索して」 |
| Message | タスク内のメッセージのやり取り | テキスト、ファイル、構造化データ |
| Artifact | タスクの成果物 | 検索結果、レポート、生成ファイル |
Agent Card
Agent Cardの構造
Agent Cardは、エージェントの「名刺」のようなものです。JSONフォーマットで定義されます。
{
"name": "NetShop Order Agent",
"description": "NetShop社の注文管理を行うエージェント。注文の検索、詳細確認、キャンセル、ステータス更新が可能です。",
"url": "https://agents.netshop.co.jp/order-agent",
"version": "1.0.0",
"capabilities": {
"streaming": true,
"pushNotifications": false
},
"skills": [
{
"id": "search_orders",
"name": "注文検索",
"description": "顧客ID、日付範囲、ステータスで注文を検索します",
"inputModes": ["text"],
"outputModes": ["text", "data"]
},
{
"id": "get_order_details",
"name": "注文詳細取得",
"description": "注文番号を指定して詳細情報を取得します",
"inputModes": ["text"],
"outputModes": ["text", "data"]
},
{
"id": "cancel_order",
"name": "注文キャンセル",
"description": "注文のキャンセル処理を行います。pending/confirmedの注文のみ対象。",
"inputModes": ["text"],
"outputModes": ["text"]
}
],
"authentication": {
"type": "bearer",
"tokenUrl": "https://auth.netshop.co.jp/token"
}
}
Agent Cardの取得
標準的なエンドポイント /.well-known/agent.json から取得します。
// Agent Cardの取得
async function discoverAgent(baseUrl: string): Promise<AgentCard> {
const response = await fetch(`${baseUrl}/.well-known/agent.json`);
return await response.json();
}
// 使用例
const orderAgent = await discoverAgent("https://agents.netshop.co.jp/order-agent");
console.log(orderAgent.skills); // 利用可能なスキル一覧
タスクの管理
タスクのライフサイクル
タスクの状態遷移:
submitted → working → completed
↓ ↓
input_required failed
↓
working → completed
| 状態 | 説明 |
|---|---|
| submitted | タスクが送信された |
| working | エージェントが処理中 |
| input_required | 追加情報がクライアントに必要 |
| completed | タスク完了 |
| failed | タスク失敗 |
タスクの送信と応答
// タスクの送信
interface A2ATask {
id: string;
skill: string;
message: {
role: "user";
parts: Array<{
type: "text";
text: string;
}>;
};
}
// タスクを送信
async function sendTask(agentUrl: string, task: A2ATask): Promise<TaskResult> {
const response = await fetch(`${agentUrl}/tasks`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer <token>"
},
body: JSON.stringify(task)
});
return await response.json();
}
// 使用例
const result = await sendTask(
"https://agents.netshop.co.jp/order-agent",
{
id: "task-001",
skill: "search_orders",
message: {
role: "user",
parts: [{ type: "text", text: "顧客CUST-001の直近の注文を検索してください" }]
}
}
);
A2AとMCPの違い
A2Aと似た概念にMCP(Model Context Protocol)があります。
| 観点 | A2A | MCP |
|---|---|---|
| 目的 | エージェント間の通信 | LLMとツール/データソースの接続 |
| 通信相手 | エージェント ↔ エージェント | LLM ↔ 外部ツール |
| 粒度 | タスクレベル(高レベル) | ツール呼び出しレベル(低レベル) |
| 自律性 | 相手エージェントが自律的に処理 | ツールは指示通りに実行 |
| 状態管理 | タスクのライフサイクルを管理 | ステートレスなツール呼び出し |
関係性:
[エージェントA] ──A2A──→ [エージェントB]
│ │
MCP MCP
│ │
[ツール群] [ツール群]
A2A: エージェント間の高レベルなタスク委任
MCP: エージェント内のツール接続
NetShop社でのA2A活用例
┌─────────────────┐ A2A ┌─────────────────┐
│ カスタマーサポート │ ──────────→ │ 注文管理 │
│ エージェント │ │ エージェント │
│ │ ←────────── │ │
│ Skills: │ │ Skills: │
│ - 問い合わせ対応 │ │ - 注文検索 │
│ - FAQ検索 │ A2A │ - 注文キャンセル │
│ │ ──────────→ │ │
└─────────────────┘ └─────────────────┘
│ │
│ A2A │ A2A
↓ ↓
┌─────────────────┐ ┌─────────────────┐
│ 配送管理 │ │ 決済管理 │
│ エージェント │ │ エージェント │
│ Skills: │ │ Skills: │
│ - 配送追跡 │ │ - 返金処理 │
│ - 再配達手配 │ │ - 決済状況確認 │
└─────────────────┘ └─────────────────┘
まとめ
| ポイント | 内容 |
|---|---|
| A2Aの目的 | 異なるエージェント間の標準的な通信プロトコル |
| Agent Card | エージェントの能力を宣言するメタデータ |
| Task | エージェントへの処理依頼とライフサイクル管理 |
| A2A vs MCP | A2Aはエージェント間通信、MCPはツール接続 |
チェックリスト
- A2Aプロトコルの目的と基本構造を理解した
- Agent Cardの役割と構造を説明できる
- タスクのライフサイクル(submitted → working → completed)を理解した
- A2AとMCPの違いを説明できる
次のステップへ
次は「エージェント間通信」を学びます。メッセージパッシング、共有状態、イベントドリブンの3つの通信パターンを理解しましょう。
推定読了時間: 30分