Agent2Agent プロトコル · A2A v1.0

エージェントを独立して配置できるようにする 一緒に働きます。

A2A は、他のエージェントが別の AI サービスで実行されている場合、異なるプログラミング言語やエージェント フレームワークを使用している場合、または別のクラウドにデプロイされている場合でも、AI エージェントに、別のエージェントに自己紹介し、ジョブやタスクを受け入れ、進捗状況を報告し、詳細情報を要求し、有用な結果を返すための標準的な方法を提供します。どちらのエージェントも、相手のエージェントがどのように構築されているかを理解する必要はありません。これらは、A2A 標準を使用して通信し、連携します。

11 v1 オペレーションエージェントカードJSON-RPC + RESTSSE ストリーミングマルチターンタスク認証されたプッシュRemoteA2aAgent

ADK-Rust A2A リファレンス アーキテクチャ

A2A リモート エージェントのアーキテクチャ

The network contract stays separate from the agent's model, tools, memory, and internal orchestration.

01

通話システム

別のエージェントに作業を依頼するエージェントまたはアプリケーション。

コーディネーターエージェント

どのリモート スペシャリストがタスクを受け取るかを決定します。

A2Aクライアント

カードを検出し、ストリーミングを選択し、プロトコル メッセージを送信します。

HTTPS

02

A2A サービス境界

互換性のあるすべてのクライアントが理解できる公的契約。

エージェントカード

名前、スキル、エンドポイント、プロトコルのバージョン、セキュリティ、宣言された機能。

リクエストチェック

バージョン、コンテンツ タイプ、ID、メッセージ部分、メタデータ、ID、および制限。

リクエストハンドラ

1 つの共有実装を通じて JSON-RPC または REST 操作をディスパッチします。

タイプされた呼び出し

03

ADK-Rust ランタイム

フレームワークはタスクを実行し、入力された進行状況を生成します。

Runner

呼び出しコンテキストを作成し、エージェント イベントをストリーミングします。

エージェント制

LLM、ワークフロー、グラフ、カスタム、またはマルチエージェント ロジック。

ツール

Rust ツールと MCP

セッションと記憶

エージェントの動作中にタスクの状態とイベントが記録されます

04

タスクのライフサイクル

検証済みのステート マシンにより、長時間実行される作業を検査可能になります。

タスクストア

ステータス、コンテキスト、履歴、アーティファクト、メタデータ、およびプッシュ構成。

ステートマシン

有効な遷移のみが受け入れられます。ターミナルタスクはターミナルのままです。

05

進捗状況の配信

呼び出し側は、お釣りの受け取り方法を選択します。

ダイレクトレスポンス

完全なタスクとそのアーティファクトを返します。

SSE ストリーム

最初にタスク、次にステータスとアーティファクトの更新。

06

依頼を受けてから作業する

長いタスクは、1 つの接続を開いたままにすることなく、後でレポートできます。

定期購入

クライアントは既存のタスクの更新をリッスンします。

プッシュ Webhook

再試行と SSRF チェックによる認証済み配信。

ADK-Rust は、A2A ワイヤ コントラクト、タスク ライフサイクル、エージェント実行、配信チャネルを個別の部分として保持するため、それぞれを個別に保護、テスト、置き換えることができます。

アイデアから始める

外部でホストされている AI エージェントを使用するにはどうすればよいですか?

1 つの ADK-Rust プロセス内で、エージェントは Rust タイプ、セッション、ツール、および直接の関数呼び出しを共有できます。エージェントが別のサービス、または別の組織に所属すると、それらのプライベート実装の詳細は安全な契約ではなくなります。

A2A は、その境界における共有言語を定義します。呼び出し元は、エンドポイントの背後でどのモデル、フレームワーク、ツールが実行されているかを知る必要がなく、リモート エージェントが提供するものを発見し、構造化メッセージを送信し、既知の状態を通じてタスクを追跡し、成果物を受信します。

ADK-Rust は、adk-server に A2A v1 を実装し、プロトコルを Runner に直接接続します。ローカルでテストする同じエージェントをネットワーク サービスにすることができますが、RemoteA2aAgent を使用すると、別の ADK-Rust システムが通常のエージェント インターフェイスを通じてそのエージェントを使用できるようになります。

エージェントカード

エージェントのサービス プロファイル

小さな公開文書には、発信者にエージェントの名前、エンドポイント、スキル、プロトコルのバージョン、セキュリティ要件、ストリーミングまたは通知をサポートするかどうかが記載されています。

メッセージ

あるエージェントが別のエージェントに言うこと

メッセージには、役割、一意の ID、およびテキストや構造化データなどの 1 つ以上の部分が含まれます。一意の ID により、安全な再試行が可能になります。

タスク

両方のシステムが実行できるジョブ

タスクは、リモート作業に ID、会話コンテキスト、状態、メッセージ履歴、メタデータ、およびその過程で生成された成果物を与えます。

アーティファクト

作業から得られる有用な成果物

アーティファクトは、タスクに添付された名前付きの結果です。つまり、レポート、決定、計画、生成されたファイル、または別のシステムが使用できるその他の構造化された出力です。

1 つの仕事をフォローする

プロトコルには、リクエストと作業の存続期間の両方が含まれます。

呼び出し元は、1 つの応答を待ったり、ライブ イベント ストリームを開いたり、既存のタスクをサブスクライブしたり、後の更新のために Webhook を登録したりできます。タスク ID とコンテキストにより、すべての配信モードが同じ作業に関連付けられます。

タスクステートマシン

リモートの仕事には、あなたが従うことができる生活があります。

A2A はテキストを返すだけではありません。それは作品にアイデンティティ、会話のコンテキスト、現在の状態、歴史、成果物を与えます。 ADK-Rust は、保存する前にすべてのトランジションを検証します。

SUBMITTED

サーバーはタスクを受け入れました。

WORKING

エージェントが実行しています。

INPUT REQUIRED

エージェントはさらに詳しい情報を必要としています。

AUTH REQUIRED

呼び出し元は承認を与える必要があります。

COMPLETED

作品と成果物は準備ができています。

FAILED

実行はエラーで終了しました。

CANCELED

許可されたキャンセルによりタスクが終了しました。

REJECTED

サーバーはタスクを拒否しました。

マルチターン作業: タスクが到達したとき INPUT_REQUIRED、発信者は同じメッセージを含む別のメッセージを送信します。 contextId。 ADK-Rust はタスクを見つけて、それを返します WORKING、メッセージを追加し、同じジョブを続行します。

現実世界のロジックフロー

Case Study: Resolve a customer's damaged order across two distinct agent services.

A customer tells the company's support agent that an order arrived damaged. The support agent remains responsible for the conversation: it understands the request, keeps the customer informed, collects any missing evidence, and presents the final decision. It does not have direct access to warehouse stock, delivery records, or replacement policy.

その運用情報は、個別に展開されたフルフィルメント エージェントに属します。 A2A を通じて、サポート エージェントはフルフィルメント エージェントが何を行っているかを発見し、調査をタスクとして送信し、進行状況を追跡し、詳細情報の要求に答え、最終的な交換の決定を受け取ることができます。各サービスは独自のコード、データ、ツール、モデルプロバイダー、およびセキュリティ制御を保持します。それらは、A2A コントラクトによって定義されたメッセージ、タスク状態、およびアーティファクトのみを共有します。

01

スペシャリストを発見する

サポート コーディネーターは、フルフィルメント エージェントのカードを読み取り、注文調査を処理し、進捗状況をストリーミングしていることを確認します。

02

クリアジョブを 1 つ送信する

注文番号、顧客のリクエスト、一意の messageId、および新しい会話コンテキストを送信します。

03

サービス内のルート

リモートの ADK-Rust エージェントは、呼び出し元に内部情報を公開することなく、注文ツール、在庫、配送履歴、会社ポリシーをチェックします。

04

足りないものを尋ねる

損傷の証拠が必要な場合、タスクは推測または黙って失敗するのではなく、INPUT_REQUIRED になります。

05

同じタスクを再開する

コーディネーターは、同じ contextId を使用して承認された証拠を提供します。履歴とタスクのアイデンティティはそのまま残ります。

06

監査可能な結果を返す

タスクはステータス履歴と、交換の決定と次のステップを含むアーティファクトで完了します。

Sequence diagram

The task pauses and resumes without losing its identity.

Read from top to bottom. The A2A service owns the network contract and task record. The fulfilment agent owns its reasoning and private tools.

Support coordinator

Calling agent

A2A service

Protocol boundary

Fulfilment agent

ADK-Rust Runner

Business systems

Orders · inventory · policy

A2A 経由の通話
Runnerに発送します
承認されたツールを使用する

GET /.well-known/agent-card.json

Discover skills and streaming

Agent Card

Fulfilment capability published

SendStreamingMessage

ORD-1042 · messageId msg-order-1042

Runner invocation

Create task and execute agent

order.lookup + policy.check

Use private business tools

Evidence required

Damage photo is missing

INPUT_REQUIRED

Persist state and context

SSE status update

Ask support for evidence

SendMessage · same contextId

Approved photo reference

Resume task

INPUT_REQUIRED → WORKING

inventory.reserve

Reserve replacement stock

Artifact + COMPLETED

Replacement decision

Final SSE events

Auditable result returned

The support coordinator never receives database credentials or fulfilment code. It receives only the Agent Card, protocol events, task state, and final artifact.

コードとワイヤーによる応答

双方が何を送受信するかを確認します。

これらの例では、ADK-Rust 実装と同じ v1 操作名、メッセージ フィールド、タスク状態、および SSE 応答形状を使用します。 ID と注文の詳細は固定されているため、会話全体を簡単に理解できます。

fulfilment.rsフルフィルメントサービス・RUST
let fulfilment = LlmAgentBuilder::new("fulfilment")
      .description("Investigates orders and delivery")
      .model(model)
      .instruction(
          "Use the approved order, inventory, and policy tools.            Ask for evidence when the replacement policy requires it."
      )
      .build()?;

  A2aServer::builder()
      .agent(Arc::new(fulfilment))
      .agent_card_name("Fulfilment Agent")
      .streaming(true)
      .build()?
      .serve()
      .await?;
support.rsサポートコーディネーター・RUST
let fulfilment = RemoteA2aAgent::builder("fulfilment")
      .description("Investigates orders and delivery")
      .agent_url("https://agents.example.com/fulfilment")
      .streaming(true)
      .build()?;

  let support = LlmAgentBuilder::new("support")
      .model(model)
      .instruction("Own the customer conversation.")
      .sub_agent(Arc::new(fulfilment))
      .build()?;
SendStreamingMessage.json1 · ジョブを送信します
{
    "jsonrpc": "2.0",
    "id": "replace-1",
    "method": "SendStreamingMessage",
    "params": {
      "message": {
        "messageId": "msg-order-1042",
        "role": "ROLE_USER",
        "parts": [{
          "text": "Investigate damaged order ORD-1042 and prepare a replacement decision."
        }]
      }
    }
  }
text/event-stream2 · タスクの進行状況をストリーム配信する
data: {
    "jsonrpc":"2.0", "id":"replace-1",
    "result":{"task":{
      "id":"task-order-1042",
      "contextId":"ctx-order-1042",
      "status":{"state":"TASK_STATE_SUBMITTED"}
    }}
  }

  data: {
    "jsonrpc":"2.0", "id":"replace-1",
    "result":{"statusUpdate":{
      "taskId":"task-order-1042",
      "contextId":"ctx-order-1042",
      "status":{"state":"TASK_STATE_WORKING"}
    }}
  }
input-required.event.json3 · 不足している証拠を要求する
{
    "statusUpdate": {
      "taskId": "task-order-1042",
      "contextId": "ctx-order-1042",
      "status": {
        "state": "TASK_STATE_INPUT_REQUIRED",
        "message": {
          "role": "ROLE_AGENT",
          "parts": [{
            "text": "Please provide a photo showing the damaged item."
          }]
        }
      }
    }
  }
SendMessage.follow-up.json4 · 同じタスクを再開する
{
    "jsonrpc": "2.0",
    "id": "replace-2",
    "method": "SendMessage",
    "params": {
      "message": {
        "messageId": "msg-order-1042-photo",
        "contextId": "ctx-order-1042",
        "role": "ROLE_USER",
        "parts": [{
          "text": "Evidence received and approved: damage-photo-8841.jpg"
        }]
      }
    }
  }
final-events.json5 · アーティファクトを受け取って完成
{
    "artifactUpdate": {
      "taskId": "task-order-1042",
      "contextId": "ctx-order-1042",
      "artifact": {
        "artifactId": "replacement-decision-1042",
        "name": "Replacement decision",
        "parts": [{
          "text": "Approved. Reserve SKU-RED-42 and dispatch with priority shipping."
        }]
      }
    }
  }

  {
    "statusUpdate": {
      "taskId": "task-order-1042",
      "contextId": "ctx-order-1042",
      "status": { "state": "TASK_STATE_COMPLETED" }
    }
  }

A2A v1 API

クライアントがリモート エージェント上で作業を開始、フォロー、終了するために必要なものすべて。

ADK-Rust は、A2A v1 の 11 の操作すべてを実装します。短いジョブの場合は、SendMessage を呼び出し、タスクの結果を待ちます。作業に時間がかかる可能性がある場合は、SendStreamingMessage を使用して最初にタスクを受信し、続いてライブ ステータスとアーティファクト イベントを SSE 経由で受信します。

返されたタスク ID を使用すると、クライアントはジョブを再度送信せずに再接続できます。最新の状態を取得したり、関連タスクをリストしたり、さらなる更新を購読したり、キャンセルをリクエストしたりできます。クライアントが接続を開いたままにできない場合は、認証された Webhook を登録し、リモート エージェントが後で変更を配信できるようにすることができます。

01

仕事を始める

メッセージを送信し、完了したタスクまたはライブ ストリームを受け取ります。

SendMessageSendStreamingMessage
02

検査と管理

現在の作業を読み取り、一致するタスクをリストし、状態が許可している場合はタスクをキャンセルします。

GetTaskListTasksCancelTask
03

進捗状況を追跡する

すでに存在するタスクからの更新のために SSE サブスクリプションを開きます。

SubscribeToTask
04

今後のアップデートを受け取る

タスクの認証済み Webhook 宛先を作成、読み取り、一覧表示、および削除します。

CreatePushConfigGetPushConfigListPushConfigsDeletePushConfig
05

もっと発見する

エージェントの公開サービス プロファイルの拡張バージョンをリクエストします。

GetExtendedAgentCard

2 つのバインディングに対して 1 つのハンドラー

JSON-RPC および REST ルートは同じ RequestHandler にディスパッチされるため、タスクの動作がトランスポート間で変動することはありません。

Runner による実行

受信 A2A メッセージは ADK-Rust コンテンツになります。 Runner は、選択したエージェントを実行し、そのイベントをタスク ステータスとアーティファクトに変換します。

安全な再試行

messageId を繰り返すと、同じ作業を 2 回実行するのではなく、既存のタスクが返されます。実稼働環境では、再起動後もこのマッピングが維持される必要があります。

コンテキストから始まるストリーミング

最初の SSE イベントは完全なタスクです。後のイベントではステータスとアーティファクトの更新が行われるため、クライアントはストリームが何に属しているかを常に把握できます。

リモートエージェントがローカルにいるように感じる

RemoteA2aAgent は、ADK-Rust エージェント特性を実装します。コーディネーターは、エージェント階層にネットワーク サービスを含めて、通常のフレームワーク イベントを受信できます。

境界での保護

バージョン ネゴシエーション、メッセージ検証、ベアラー認証、レート制限、監査インターセプター、Webhook 認証、SSRF チェックによってサービスを保護できます。

適切な境界を選択してください

ローカル サブエージェントとリモート A2A エージェント

A2A では、ネットワーク、パブリック コントラクト、認証、障害処理、およびリモート タスクの状態が導入されています。それらのコストは、真の独立性を生み出すときに価値があります。すべてのエージェントがすでに同じプロセス内に存在する場合、これらは不要です。

現地代理店

リモート A2A エージェント

ベストフィット
1 つのアプリケーションが所有するエージェント
エージェントは個別にデプロイまたは所有される
コミュニケーション
インプロセス エージェントの呼び出しと型指定されたイベント
HTTP、JSON-RPC または REST、および SSE
共有状態
同じセッションとサービスを使用できる
宣言されたメッセージ、タスク、成果物のみを共有します
故障境界
1 つのランタイムとデプロイメント
ネットワーク、タイムアウト、再試行、およびリモートサービスの失敗
相互運用性
ADK-Rust コンポーネント
A2A 互換の言語またはフレームワーク

Rust エージェントからネットワーク サービスへ

エージェントを公開し、エージェントとして使用します。

コンビニエンス サーバーは、エージェント カード、セッション、A2A ルート、およびストリーミングを有効にした Axum アプリケーションを作成します。リモート アダプターはそのサービスを検出し、そのタスクの更新を ADK-Rust イベントに変換して戻します。

serve.rsエージェントを公開する
use adk_server::a2a::convenience::A2aServer;

  let app = A2aServer::quick_start(agent);
  let listener = tokio::net::TcpListener::bind(
      "0.0.0.0:8080"
  ).await?;

  axum::serve(listener, app).await?;
coordinator.rs他のエージェントから電話をかける
use adk_server::a2a::RemoteA2aAgent;

  let fulfilment = RemoteA2aAgent::builder("fulfilment")
      .description("Investigates orders and delivery")
      .agent_url("https://agents.example.com/fulfilment")
      .build()?;

  let coordinator = LlmAgentBuilder::new("support")
      .model(model)
      .sub_agent(Arc::new(fulfilment))
      .build()?;
完全に構成された v1 サービスの場合: 文書化されたものを使用する RequestHandler::with_runner パスを使用して、タスク ストア、プッシュ送信者、エージェント カード、Runner サービス、JSON-RPC ルート、REST ルーター、およびバージョン ネゴシエーション ミドルウェアを明示的に選択します。

生産前

A2A エージェントのデプロイ

ADK-Rust は、v1 タイプ、ハンドラー、ライフサイクル、クライアント、検証、配信プリミティブ、および Runner との統合を提供します。実稼働の準備が整っているかどうかは、サービス用に選択されたストレージ、ID、ネットワーク、可観測性、および運用ポリシーに依存します。

01

正直なカードを発行する

導入で実際にサポートされるスキル、バインディング、ストリーミング、プッシュ配信、およびセキュリティ スキームのみをアドバタイズします。

02

耐久性のある状態を選択する

含まれている InMemoryTaskStore とメモリ内の冪等マップは開発に役立ちます。長時間にわたる実稼働作業には、プロセスの再起動にも耐えられるストレージが必要です。

03

両方向のセキュリティを確保

着信通話を認証し、発信プッシュ配信を保護します。 HTTP プッシュ センダーは、ベアラー資格情報、通知トークン、再試行、およびプライベート アドレスの拒否をサポートします。

04

デザインのキャンセルとタイムアウト

リモートワークは要求を超えて続く可能性があります。クライアントのタイムアウト、キャンセル ポリシー、再試行動作、およびいずれかのサービスが利用できなくなった場合の動作を定義します。

エージェントシステムを接続する

標準の A2A インターフェイスを通じてエージェントを公開します。

1 枚の正直なエージェント カードと 1 つの有用なタスクから始めます。作業が長くなり、サービスの重要性が高まるにつれて、ストリーミング、マルチターン入力、タスク永続性、サブスクリプション、認証済みプッシュ、境界制御を追加します。