A2A エージェントディスカバリー
このデプロイメントはエージェントを公開できるため、別のデプロイメントや任意のHTTPクライアントがエージェントを見つけて呼び出せます。A2Aは、あるエージェントが別のエージェントに到達するためのプロトコルであり、人がチャットアプリを通じてボットに到達するのと同じ仕組みです。このページでは、入力すべき内容と返される内容を正確に示します。
このページのすべての応答は、実行中のデーモンからの実際の出力です。ここにあるものは何も例示ではありません。
認証
2 つの検出用 GET は認証不要です。カタログカードとエイリアスごとのエージェントカードはトークンなしで読み取れるため、ピアはペアリング前に公開済みのサーフェスを検出できます。message/send POST はこれとは異なります。ツールが有効な完全なエージェントターンを実行するため、他のすべての書き込みサーフェスと同様にゲートウェイのペアリング認証の背後に置かれます。[gateway] require_pairing が有効な場合(デフォルト)、タスク POST でペアリング由来のベアラートークンを渡してください:
curl -X POST http://localhost:42617/a2a/agent_alpha \
-H "Authorization: Bearer $ZEROCLAW_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"message/send","params":{...}}'
未認証の task POST は 401 を返し、エージェントターンにはなりません。以下の discovery GET にはヘッダーは不要です。トークンの取得方法については gateway pairing のドキュメントを参照してください。
全体を2つのリクエストで
エージェントを検出するには、2つのGETリクエストだけで済みます。
まず、デプロイメントが公開しているエージェントを問い合わせます:
curl http://localhost:42617/.well-known/agents-card.json次に、それらのエージェントの1つに何ができるかを尋ねます。
curl http://localhost:42617/a2a/agent_alpha/.well-known/agent-card.json
最初のリクエストでは、エージェントの URL のリストが返されます。2 番目のリクエストでは、1 つのエージェントのスキルと、作業を送信する URL が返されます。これがディスカバリの対象範囲のすべてです。このページの残りの部分は、これら 2 つのレスポンスを注意深く読むだけです。
リクエスト1: エージェントの一覧を表示
curl http://localhost:42617/.well-known/agents-card.json応答:
{
"name": ZeroClaw エージェント,
"description": この ZeroClaw インストール上で公開されている A2A エージェントを列挙するディスカバリーカタログ。実行可能なエージェントではありません。以下の各エントリはそれぞれ独自の A2A カードとエンドポイントを提供します。スキルは公開されたエージェントから集約され、それぞれ所有エイリアスでタグ付けされています。,
supportedInterfaces: [
{
「url」: http://localhost:42617/.well-known/agents-card.json,
protocolBinding: カタログ,
protocolVersion: 1.0
},
{
「url」: http://localhost:42617/a2a/agent_beta,
protocolBinding: JSONRPC,
protocolVersion: 1.0
},
{
「url」: http://localhost:42617/a2a/agent_alpha,
protocolBinding: JSONRPC,
protocolVersion: 1.0
}
],
version: "0.8.5",
機能: {
ストリーミング: false,
pushNotifications: false,
extendedAgentCard: false
},
defaultInputModes: ["text"],
defaultOutputModes: ["text"],
スキル: [
{
"id": agent_beta/github-issue-triage,
"name": github-issue-triage,
"description": ZeroClaw 向けのイシュートリアージおよびライフサイクル管理エージェント。,
タグ: [github, 課題, トリアージ, agent_beta]
},
{
"id": agent_beta/github-pr-review-session,
"name": github-pr-review-session,
"description": ZeroClaw の PR レビュー向けヒューマンレビュアー・コパイロット。,
タグ: [github, pull-requests, レビュー, agent_beta]
},
{
"id": agent_alpha/zeroclaw,
"name": zeroclaw,
"description": ユーザーが自分の ZeroClaw エージェントインスタンスを操作し、対話できるように支援します。,
タグ: [操作, cli, ゲートウェイ, agent_alpha]
},
{
"id": agent_alpha/skill-creator,
"name": skill-creator,
"description": 新しいスキルを作成し、既存のスキルを変更・改善し、スキルのパフォーマンスを測定する。,
タグ: [スキル, オーサリング, 評価, agent_alpha]
},
{
"id": agent_alpha/changelog-generation,
"name": changelog-generation,
"description": ZeroClaw リリース向けの変更履歴生成スキル。,
タグ: [変更履歴, release, 自動化, agent_alpha]
}
]
}
こう読みます。supportedInterfaces はURLの一覧です。catalog とタグ付けされたものはこの一覧自体なので、無視してください。JSONRPC とタグ付けされた2つがエージェントの agent_alpha と agent_beta です。これらのURLが作業の送信先になります。skills は公開されている全エージェントのスキルを集約したもので、各 id には所有エイリアスがプレフィックスとして付き、tags にもそのエイリアスがタグ付けされます。これにより、一度読むだけでインストール全体の機能範囲と、各要素の所有者を把握できます。
リクエスト2: 1つのエージェントを検査する
リストからURLを取得し、カードパスを追加します:
curl http://localhost:42617/a2a/agent_alpha/.well-known/agent-card.json
応答:
{
"name": agent_alpha,
"description": ZeroClaw エージェント 'agent_alpha'.,
supportedInterfaces: [
{
「url」: http://localhost:42617/a2a/agent_alpha,
protocolBinding: JSONRPC,
protocolVersion: 1.0
}
],
version: "0.8.5",
機能: {
ストリーミング: false,
pushNotifications: false,
extendedAgentCard: false
},
defaultInputModes: ["text"],
defaultOutputModes: ["text"],
スキル: [
{
"id": zeroclaw,
"name": zeroclaw,
"description": ユーザーが自分の ZeroClaw エージェントインスタンスを操作し、対話できるように支援します。,
タグ: [操作, cli, ゲートウェイ]
},
{
"id": skill-creator,
"name": skill-creator,
"description": 新しいスキルを作成し、既存のスキルを変更・改善し、スキルのパフォーマンスを測定する。,
タグ: [スキル, オーサリング, 評価]
},
{
"id": changelog-generation,
"name": changelog-generation,
"description": ZeroClaw リリース向けの変更履歴生成スキル。,
タグ: [変更履歴, release, 自動化]
}
]
}
これで3つのことが分かりました。エージェントの名前は agent_alpha です。3つのスキル、zeroclaw、skill-creator、および changelog-generation を持ち、それぞれが何をするかの平易な説明があります。そして、単一の JSONRPC インターフェース URL、http://localhost:42617/a2a/agent_alpha が、タスクを POST するアドレスです。
カード description は、エイリアスのアイデンティティドキュメントが設定されている場合、そこから取得されます。AIEOS アイデンティティの bio がこの行を提供し、設定されていない場合はそのアイデンティティの名前にフォールバックします。アイデンティティが設定されていない場合、カードは上記に示した中立的なデフォルト ZeroClaw agent '<alias>'. を使用します。
エージェントが何を表示するかを選択します
エージェントは、持っているすべてのスキルを公開する必要はありません。同じデプロイメント内の agent_beta エージェントは、独自に選択したセットを公開します:
curl http://localhost:42617/a2a/agent_beta/.well-known/agent-card.json
{
"name": agent_beta,
"description": ZeroClaw エージェント 'agent_beta'。,
supportedInterfaces: [
{
「url」: http://localhost:42617/a2a/agent_beta,
protocolBinding: JSONRPC,
protocolVersion: 1.0
}
],
version: "0.8.5",
機能: {
ストリーミング: false,
pushNotifications: false,
extendedAgentCard: false
},
defaultInputModes: ["text"],
defaultOutputModes: ["text"],
スキル: [
{
"id": github-issue-triage,
"name": github-issue-triage,
"description": ZeroClaw 向けのイシュートリアージおよびライフサイクル管理エージェント。
},
{
"id": github-pr-review-session,
"name": github-pr-review-session,
"description": ZeroClaw の PR レビュー向けヒューマンレビュアー・コパイロット。
}
]
}
デプロイでは、どのエージェントを公開するか、そして各エージェントがどのスキルを公開するかを選択しました。これこそが公開の目的です。エージェントごとに、外部の世界がどのスキルを見られるかを決定します。
タスクを送信する
エージェントのインターフェース URL とスキルを用意したら、その URL に JSON-RPC の message/send POST として作業を送信します:
curl -X POST http://localhost:42617/a2a/agent_alpha \
-H "Authorization: Bearer $ZEROCLAW_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "message/send",
"params": {
"message": {
"role": "user",
"parts": [{ "kind": "text", "text": "Reply with PONG" }]
}
}
}'
エージェントはターンを実行し、完了したタスクで応答します。応答はタスクのアーティファクト内のテキスト部分です:
{
"id": 1,
"jsonrpc": "2.0",
"result": {
"artifacts": [
{
"artifactId": "5346ae32-1b63-40c0-9aaa-345d815c792e",
"parts": [
{
"kind": "text",
"text": "PONG"
}
]
}
],
"contextId": "a2a_agent_alpha_06cb22f5-12bf-4b26-9ebc-9c063ab520a4",
"id": "0ef19fcb-b5e4-4c26-afce-d80451c8861e",
"kind": "task",
"status": {
"state": "completed"
}
}
}
インターフェイスの URL は、ディスカバリーとタスクで同じであり、変化するのはリクエストのみです。エンドポイントは message/send のみを受け付けます。それ以外の method は JSON-RPC の -32601 を返し、空のメッセージは -32602 を返し、JSON-RPC ではないボディは HTTP 400 を返します。
露出と一つの鋭いエッジ
タスクエンドポイントは、カードの有効化ゲートおよび公開ゲートを共有します。すなわち、[a2a.server] enabled が設定されており、かつエイリアスが有効化かつ公開されている場合にのみ応答します。未公開または不明なエイリアスへのタスク POST は、そのカードと同様に 404 を返します。ただし、カードの認証姿勢は共有しません。ディスカバリーカードは公開されたままですが、タスクの呼び出しにはゲートウェイのベアラートークンが必要であり、それがない場合は 401 を返します。
注意すべき点の1つ: インターフェースURLは、単なるGETに対してエージェントではなくWebダッシュボードで応答します。ゲートウェイが認識しないパスに対してダッシュボードの配信にフォールバックするためです:
curl -i http://localhost:42617/a2a/translator
HTTP/1.1 200 OK
content-type: text/html
ディスカバリー(.well-known パス)と message/send の POST がサポートされているサーフェスです。インターフェース URL への単なる GET はプロトコルの一部ではありません。代わりに .well-known パスのカードを読んでください。
エージェントが提供される場所
カードは Web ゲートウェイによって、他のすべてと同じアドレスおよびポートで提供されます。ゲートウェイが localhost:42617 にある場合、そこにカタログとすべてのエージェントカードが存在します。2 つ目のサーバーを実行することも、2 つ目のポートを開くこともありません。
このデプロイメントをリバースプロキシまたはパブリックホスト名の背後に置く場合、カード内のURLはクライアントが実際に到達するアドレスと一致している必要があります。公開URLは次の順序で解決されます。設定した場合は明示的なパブリックベースURL、次に設定した場合はA2A固有のホストとポートのオーバーライド、その後ゲートウェイ自身のアドレスです。オーバーライドはプロキシのケース用に存在します。プロキシの背後にいない場合は触れる必要はなく、カードはゲートウェイのアドレスを直接アドバタイズします。
有効にする
Discovery はオンにするまでオフであり、誤って何も漏洩しないように 3 つの独立した方法でオフになっています:
- A2A サーバーはデフォルトでデプロイメント全体に対して無効になっています。
- 各エージェントは、サーバーがオンであっても、デフォルトで非公開です。
- 公開されたエージェントは、指定したスキルのみを公開し、それ以外は何も公開しません。
サーバーを一度有効化し、到達可能にしたい特定のエージェントを published としてマークし、それぞれが公開するスキルを列挙します。無効化されている、または published になっていないエージェントはカタログに表示されず、そのカードパスは 404 を返します。不明なエージェント名も同様に 404 を返します。
名前付きスキルは、エージェントが実際に保持している本物のスキルに解決される場合にのみカードに表示されます。エージェントのスキルバンドルのいずれかに存在し、その SKILL.md に有効な YAML フロントマターがなければなりません。解決されない名前、またはエージェントが宣言していないバンドル内のスキルは、広告されるのではなく、黙ってドロップされます。
空の skills: [] 配列の最も一般的な原因は、skill_bundles を宣言していないエージェントに a2a.exposed_skills を設定することです。exposed_skills はエージェントの解決済みスキルセットを絞り込むだけであり、それ自体でスキルを読み込むことはありません。バンドルが宣言されていない場合、フィルターが保持するものが何もないため、すべての名前が除外され、カードには何も公開されません。所有するバンドルを agents.<alias>.skill_bundles に追加してください。設定の検証では、このケースが起動時の警告(a2a_exposed_skills_without_bundles)として表示されます。
公開が実際に露出するもの
公開する前にこれをお読みください。サーバーが有効になり、エイリアスが公開されると、POST /a2a/{alias} はそのエイリアスに対してエージェントのターンを完全に実行します。これは、チャットサーフェスが使用するのと同じパスを通じてエージェントを呼び出し、そのエージェントに設定されたツールセット全体(シェル、ファイル、ブラウザ、およびそのエイリアスが持つその他すべて)を使用します。
そのタスクエンドポイントは、他のすべての書き込み面と同様に、ゲートウェイのベアラー/ペアリング認証の背後にあります。呼び出し元が公開エージェントを起動するには、ペアリング由来のベアラートークンが必要です。認証されていないリクエストは 401 を返し、エージェントのターンには決して至りません。
ディスカバリーカードはその認証の背後にはありません。カタログとエイリアスごとのカードはトークンなしで読み取れるため、公開されたサーフェスは、リスナーに到達できるすべての呼び出し元に対してエージェント名と公開スキルを通知します。これがディスカバリーの目的です。ピアはペアリングする前にカードを読み取ります。これはまた、エージェントの呼び出しには依然としてトークンが必要であるにもかかわらず、公開によってそのメタデータがゲートウェイに到達できる誰にでも露出することを意味します。
公開はどちらの軸においても露出に関する決定です。カードのメタデータは公開され、有効なトークンを保持する者は誰でも公開されたエイリアスをそのフルツールセットで呼び出せます。スイッチを切り替える前に:
- バインドの構成範囲を限定してください。信頼できないネットワークにリスナーを直接公開するのではなく、ゲートウェイをプライベートインターフェイスにバインドするか、リバースプロキシの背後に配置してください。これにより、認証なしで公開されるカードを読み取れる対象も制限されます。
- すべてのトークン保持者による呼び出しを許容できるツールセットを持ち、その名前とスキルを認証なしで公開しても構わないエイリアスのみを公開してください。相互運用に必要な最小限まで
exposed_skillsを絞り込んでください。 - エイリアスがどのツールやスキルバンドルを持つかを判断する際は、公開されたエイリアスをリモートで呼び出し可能な実行面として扱ってください。
- クロスデプロイメントの相互運用は、呼び出し元のピアとトークンを共有します。そのクレデンシャルは他のものと同様にスコープし、ローテーションしてください。
複数のデプロイメントの接続方法
Discovery は任意の数のデプロイメントにまたがって構成されます。各デプロイメントは自身のアドレスで独自のカタログを公開します。複数のデプロイメントアドレスを知っているクライアントは、各カタログを取得し、エージェントを読み取り、それらすべてにわたる到達可能なすべてのエージェントの結合マップを保持します。レジストリも中央サーバーもありません。クライアントだけがアドレスを知る必要があり、各デプロイメントに直接通信します。
具体的な図。あなたは個人のデプロイメントを実行します。チームは共有のものを実行します。データチームは3つ目を実行します。クライアントは3つのカタログすべてを取得します:
curl http://personal.example:42617/.well-known/agents-card.json
curl http://team.example:42617/.well-known/agents-card.json
curl http://data.example:42617/.well-known/agents-card.json
それぞれが独自のエージェントリストを返します。クライアントは、たとえば personal の notes エージェント、team の deploy エージェント、data の query エージェントを認識します。それらを使用するには、そのエージェントのカードを取得し、上記とまったく同じようにそのエージェントの URL にタスクを送信します。デプロイごとに変わるものはありません。異なるホストを指すだけで、同じ 2 回の読み取りと 1 回の POST です。
ユースケース
デプロイメントを互いに接続するいくつかの具体的な理由。
研究用デプロイメントは文献検索を専門のデータデプロイメントに委ねます。研究エージェントはデータデプロイメントの search エージェントを発見し、クエリをタスクとして送信し、結果を自身の作業に取り込みます。研究側はデータ側の認証情報やインデックスを保持せず、エージェントの URL のみを知っています。
オンコールのデプロイメントは、インシデントをチーム所有のデプロイメントにファンアウトします。各チームのデプロイメントで triage エージェントを検出し、それぞれに同じインシデントをタスクとして送信し、回答を収集します。各チームは自身の triage エージェントが公開するものを制御します。オンコール側はカードを読み取り、タスクを送信するだけです。
個人のデプロイメントは、ログインを共有せずに企業のデプロイメントの審査済みエージェントを呼び出します。企業の invoice エージェントを発見し、下書きリクエストを送信して結果を受け取ります。企業はどのエージェントとスキルを公開するかを決定します。あなたは企業のデプロイメント内のシートを得ることはなく、エージェントエンドポイントのみを取得します。
A2A は MCP ではありません
これらは異なる問題を解決するものであり、互いに組み合わせて使えます。MCP は 1 つのエージェントをそのツールやコンテキストに接続します。つまり、単一のエージェントが何を呼び出せるかに答えるものです。A2A はエージェントを対等な存在として他のエージェントに接続します。つまり、他のどのエージェントに作業を引き渡せるかに答えるものです。A2A を介して到達するエージェントは、その仕事を行うために内部的に MCP ツールを使用しているかもしれませんが、あなたはそれを見ることもなければ気にする必要もありません。カードにはスキルが表示され、その背後にあるツールは表示されません。エージェントに能力を与えるには MCP を使い、エージェント同士が互いに委任し合えるようにするには A2A を使いましょう。