エージェントカード
エージェントのサービス プロファイル
小さな公開文書には、発信者にエージェントの名前、エンドポイント、スキル、プロトコルのバージョン、セキュリティ要件、ストリーミングまたは通知をサポートするかどうかが記載されています。
A2A は、他のエージェントが別の AI サービスで実行されている場合、異なるプログラミング言語やエージェント フレームワークを使用している場合、または別のクラウドにデプロイされている場合でも、AI エージェントに、別のエージェントに自己紹介し、ジョブやタスクを受け入れ、進捗状況を報告し、詳細情報を要求し、有用な結果を返すための標準的な方法を提供します。どちらのエージェントも、相手のエージェントがどのように構築されているかを理解する必要はありません。これらは、A2A 標準を使用して通信し、連携します。
ADK-Rust A2A リファレンス アーキテクチャ
The network contract stays separate from the agent's model, tools, memory, and internal orchestration.
01
別のエージェントに作業を依頼するエージェントまたはアプリケーション。
どのリモート スペシャリストがタスクを受け取るかを決定します。
カードを検出し、ストリーミングを選択し、プロトコル メッセージを送信します。
02
互換性のあるすべてのクライアントが理解できる公的契約。
名前、スキル、エンドポイント、プロトコルのバージョン、セキュリティ、宣言された機能。
バージョン、コンテンツ タイプ、ID、メッセージ部分、メタデータ、ID、および制限。
1 つの共有実装を通じて JSON-RPC または REST 操作をディスパッチします。
03
フレームワークはタスクを実行し、入力された進行状況を生成します。
呼び出しコンテキストを作成し、エージェント イベントをストリーミングします。
LLM、ワークフロー、グラフ、カスタム、またはマルチエージェント ロジック。
Rust ツールと MCP
セッションと記憶
04
検証済みのステート マシンにより、長時間実行される作業を検査可能になります。
ステータス、コンテキスト、履歴、アーティファクト、メタデータ、およびプッシュ構成。
有効な遷移のみが受け入れられます。ターミナルタスクはターミナルのままです。
05
呼び出し側は、お釣りの受け取り方法を選択します。
完全なタスクとそのアーティファクトを返します。
最初にタスク、次にステータスとアーティファクトの更新。
06
長いタスクは、1 つの接続を開いたままにすることなく、後でレポートできます。
クライアントは既存のタスクの更新をリッスンします。
再試行と SSRF チェックによる認証済み配信。
アイデアから始める
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、メッセージを追加し、同じジョブを続行します。現実世界のロジックフロー
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 コントラクトによって定義されたメッセージ、タスク状態、およびアーティファクトのみを共有します。
サポート コーディネーターは、フルフィルメント エージェントのカードを読み取り、注文調査を処理し、進捗状況をストリーミングしていることを確認します。
注文番号、顧客のリクエスト、一意の messageId、および新しい会話コンテキストを送信します。
リモートの ADK-Rust エージェントは、呼び出し元に内部情報を公開することなく、注文ツール、在庫、配送履歴、会社ポリシーをチェックします。
損傷の証拠が必要な場合、タスクは推測または黙って失敗するのではなく、INPUT_REQUIRED になります。
コーディネーターは、同じ contextId を使用して承認された証拠を提供します。履歴とタスクのアイデンティティはそのまま残ります。
タスクはステータス履歴と、交換の決定と次のステップを含むアーティファクトで完了します。
Sequence diagram
Read from top to bottom. The A2A service owns the network contract and task record. The fulfilment agent owns its reasoning and private tools.
Calling agent
Protocol boundary
ADK-Rust Runner
Orders · inventory · policy
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
コードとワイヤーによる応答
これらの例では、ADK-Rust 実装と同じ v1 操作名、メッセージ フィールド、タスク状態、および SSE 応答形状を使用します。 ID と注文の詳細は固定されているため、会話全体を簡単に理解できます。
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?;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()?;{
"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."
}]
}
}
}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"}
}}
}{
"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."
}]
}
}
}
}{
"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"
}]
}
}
}{
"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 を登録し、リモート エージェントが後で変更を配信できるようにすることができます。
メッセージを送信し、完了したタスクまたはライブ ストリームを受け取ります。
SendMessageSendStreamingMessage現在の作業を読み取り、一致するタスクをリストし、状態が許可している場合はタスクをキャンセルします。
GetTaskListTasksCancelTaskすでに存在するタスクからの更新のために SSE サブスクリプションを開きます。
SubscribeToTaskタスクの認証済み Webhook 宛先を作成、読み取り、一覧表示、および削除します。
CreatePushConfigGetPushConfigListPushConfigsDeletePushConfigエージェントの公開サービス プロファイルの拡張バージョンをリクエストします。
GetExtendedAgentCardJSON-RPC および REST ルートは同じ RequestHandler にディスパッチされるため、タスクの動作がトランスポート間で変動することはありません。
受信 A2A メッセージは ADK-Rust コンテンツになります。 Runner は、選択したエージェントを実行し、そのイベントをタスク ステータスとアーティファクトに変換します。
messageId を繰り返すと、同じ作業を 2 回実行するのではなく、既存のタスクが返されます。実稼働環境では、再起動後もこのマッピングが維持される必要があります。
最初の SSE イベントは完全なタスクです。後のイベントではステータスとアーティファクトの更新が行われるため、クライアントはストリームが何に属しているかを常に把握できます。
RemoteA2aAgent は、ADK-Rust エージェント特性を実装します。コーディネーターは、エージェント階層にネットワーク サービスを含めて、通常のフレームワーク イベントを受信できます。
バージョン ネゴシエーション、メッセージ検証、ベアラー認証、レート制限、監査インターセプター、Webhook 認証、SSRF チェックによってサービスを保護できます。
適切な境界を選択してください
A2A では、ネットワーク、パブリック コントラクト、認証、障害処理、およびリモート タスクの状態が導入されています。それらのコストは、真の独立性を生み出すときに価値があります。すべてのエージェントがすでに同じプロセス内に存在する場合、これらは不要です。
現地代理店
リモート A2A エージェント
Rust エージェントからネットワーク サービスへ
コンビニエンス サーバーは、エージェント カード、セッション、A2A ルート、およびストリーミングを有効にした Axum アプリケーションを作成します。リモート アダプターはそのサービスを検出し、そのタスクの更新を ADK-Rust イベントに変換して戻します。
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?;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()?;RequestHandler::with_runner パスを使用して、タスク ストア、プッシュ送信者、エージェント カード、Runner サービス、JSON-RPC ルート、REST ルーター、およびバージョン ネゴシエーション ミドルウェアを明示的に選択します。生産前
ADK-Rust は、v1 タイプ、ハンドラー、ライフサイクル、クライアント、検証、配信プリミティブ、および Runner との統合を提供します。実稼働の準備が整っているかどうかは、サービス用に選択されたストレージ、ID、ネットワーク、可観測性、および運用ポリシーに依存します。
導入で実際にサポートされるスキル、バインディング、ストリーミング、プッシュ配信、およびセキュリティ スキームのみをアドバタイズします。
含まれている InMemoryTaskStore とメモリ内の冪等マップは開発に役立ちます。長時間にわたる実稼働作業には、プロセスの再起動にも耐えられるストレージが必要です。
着信通話を認証し、発信プッシュ配信を保護します。 HTTP プッシュ センダーは、ベアラー資格情報、通知トークン、再試行、およびプライベート アドレスの拒否をサポートします。
リモートワークは要求を超えて続く可能性があります。クライアントのタイムアウト、キャンセル ポリシー、再試行動作、およびいずれかのサービスが利用できなくなった場合の動作を定義します。
エージェントシステムを接続する
1 枚の正直なエージェント カードと 1 つの有用なタスクから始めます。作業が長くなり、サービスの重要性が高まるにつれて、ストリーミング、マルチターン入力、タスク永続性、サブスクリプション、認証済みプッシュ、境界制御を追加します。