チュートリアル
AI Agent はどうやって別の Agent を見つけるか:Agent Registry、A2A Agent Card、JSON Capability Discovery
発見が失敗したら、先にどのホップかを問え。カタログ検索か、名刺の取得か、ドメインは握っているのに GET の経路が違うのか。
前回の Agent Card フィールド解説 は 1.0 の必須表を開いた。今日はフィールドを埋め直さない。Registry がカタログである理由 も繰り返さない。オーケストレータの次の問いは、「返品を分類できる同僚が要る」から呼び出し可能な Card まで、どう進むか。公式の答えは A2A Agent Discovery:戦略は三つ、Card は一つ。仕様はキュレーションカタログの問い合わせ API を定めない。同ページの Considerations を見よ。Google Cloud のカタログは実装の一つ。形は Registry JSON schemas と照合する。本稿はホップを辿る。横への委譲と下へのツール呼び出しの層分けは A2A vs MCP。今日は繰り返さない。
発見はプロトコルではない。見つかるのは Card
A2A が標準化するのは自己記述であり、電話帳ではない。遠隔の Agent は能力を JSON の名刺に書く。クライアントはそのカードで向き不向き、つなぎ方、送る Task を決める。方法は環境で変わる。公開網、企業カタログ、開発機への直書き。三つとも同じ Card に着ける。「発見」を別の会話プロトコルと呼ぶと、レビューは先に逸れる。プロトコルは依然 A2A。変わるのは well-known やカタログへ入る扉だ。
公式の発見ページの「Role of the Agent Card」は、まだ 0.3 の口調でトップレベル url に触れる。新しいカードは 1.0:エンドポイントは supportedInterfaces。変更点は v1.0 の変更。発見ホップが古いフィールドを読んでも、それを 1.0 の主契約にするな。フィールドの書き方は前回書いた。今日問うのは、このカードがどのホップで手元に来たか、来たあと先にどのキーを確かめるか、だけだ。
発見の成功は tools/call の許可ではない。向こうは不透明な Agent のまま。skill を選び、インタフェースを選び、送るのは Task。検索の命中を関数表だと思うと、複数回の確認で arguments が壊れる。MCP のホップで引数をどう確かめるかは、サイト内の Schema 稿。今日は「誰を見つけたか、なぜその仕事を任せられると判断したか」で止まる。
| 戦略 | すでに知っていること | 次のホップ |
|---|---|---|
| Well-known URI | ドメインまたはホスト | GET /.well-known/agent-card.json |
| キュレーションカタログ | スキルのキーワード / タグ | カタログを問い合わせ、Card か参照を取る |
| 直接設定 | URL かカード一式 | 検索を飛ばし、カードを読む |
公式の三戦略:道を選んでから歩く
Well-known は公開 Agent、あるいはホスト名を支配できる発見に向く。経路は RFC 8615:https://{agent-server-domain}/.well-known/agent-card.json。クライアントはドメインを知っているか、導き出せる。HTTP GET を出し、JSON を受ける。実装は単純で、自動化しやすい。名刺に機微なスキルや社内 URL があるなら、その GET 自体に認証が要る。社内エンドポイントを公開網に裸で掲げてはいけない。
キュレーションカタログは企業や市場向き。中間サービスが Card を集め、クライアントは skills、tags、provider、capabilities で問い合わせ、カタログは一致するカードか参照を返す。得られるのは統治と、能力での検索。代価はカタログを養うこと。A2A はカタログ API を定めない。Google Agent Registry、コミュニティの registry、自前のカタログは、問い合わせの形を各自が書く。「汎用 discover JSON」一枚で三社を検証するな。
直接設定は密結合、私有 Agent、開発機向き。カード URL は環境変数、設定ファイル、独自 API に置く。関係が静的なら一番安い。Card が動けば、クライアントも追随しなければならない。本番で「開発機への直書き」を唯一の発見面にするのは、2025 年の住所録だ。三路は共存できる。カタログは誰かを探し、well-known はカタログが落ちても名刺を読み、設定は起動時の種ホストを持つ。
ホスト名がある:GET well-known
いちばんきれいなホップは三手。(1) ドメインを得る。例は returns.agents.example.com。(2) GET https://returns.agents.example.com/.well-known/agent-card.json。(3) 応答は 1.0 Schema を通る Card。経路を誤り、HTTP を内部エイリアスに替え、証明書のホスト名が合わないと、障害票は「発見失敗」と書く。Card は健全でも、GET が届いていない。
仕様は Card のエンドポイントにキャッシュヘッダを勧める。Cache-Control: max-age=… で中間層とクライアントは全文を毎回取らない。ETag は version でも内容ハッシュでもよい。期限後は条件付き要求(If-None-Match)。無条件の全文取得を毎回するな。サーバがヘッダを出さなくても、クライアントは短い既定を置いてよい。skills が変わりうるカードを永久にキャッシュしてはいけない。
公開カードはオーケストレータが選べる分量で足りる。機微なスキルと社内の第二エンドポイントは、認証後の拡張カードへ。capabilities.extendedAgentCard が真のときだけ、二枚目を取る。発見ホップは未認証の段階で拡張カードがあると仮定するな。カタログが身元に応じて別の Card を返すことと、well-known の一枚が全員に同じであることとは、開示の型が違う。レビューでは文を分けて書け。
カタログがある:tags を探し、Card を取る
ホスト名がなく、「返品を分類できる同僚を探せ」という一文だけのときは、キュレーションカタログを歩く。問い合わせが食べるのは Card 上の skills[].tags とスキル名であり、スライドのトポロジではない。Google プロジェクト内のオーケストレータ、Gemini Enterprise、Agent Gateway はスキルのキーワードで登録項を探す。それは製品の振る舞いであり、A2A の標準 RPC ではない。コミュニティや他クラウドは各自の search を持つ。検査データが断言すべきは「問い合わせ → 命中一覧 → 各行に cardUrl か埋め込み Card」。一社の経路を仕様にするな。
カタログが参照を返すなら、次のホップは依然 well-known、またはカタログが出した Card URL。埋め込み Card を返すなら、それでも 1.0 Schema で確かめる。登録の成功はフィールドの適法ではない。ホストだけで skills のない NO_SPEC 項目は、検索面が空だ——#5 で書いた。今日の注意は一つ。空の索引へキーワードホップを打っても、プロトコルは壊れていない。
カタログが落ちても、発見が自動で終わらない。ホスト名をすでに握っているなら、クライアントは well-known を GET すべきだ。カタログを唯一の真実にすると、発見面が単一点になる。種設定に安定ホストを一つか二つ残し、カタログが戻ってからキーワード検索を再開する。「カタログ 500 で止まる」より、仕様の三路共存に近い。
命中のあと:skills を合わせ、インタフェースを選び、Task を送る
検索の命中は「彼かもしれない」だけを意味する。オーケストレータはなお skills[] を見る。id は委譲したい仕事か、tags は問い合わせ語に本当に当たるか、description の境界は受け入れるか。MCP の inputSchema で skill を包むな。1.0 の手がかりは examples と MIME。skill を誤って Task を送れば、失敗は委譲であり発見ではない。ただし検査データは「命中 ≠ 選定」を二段で書け。
選定のあと supportedInterfaces を読む。先頭が優先。クライアントは話せるバインディングを選ぶ。JSONRPC、GRPC、HTTP+JSON。共通のバインディングがなければ、発見は成功し通話は失敗する。0.3 のトップレベル url を 1.0 の主エンドポイントにするな。能力フラグも見る。streaming が偽なのにストリームを購読すれば、仕様は能力エラーを求める。黙って unary へ落とすな。
下は走査用のデータであり、どのカタログの公式 API でもない。問い合わせ、命中、優先インタフェースを一つの JSON に畳む。倉庫の Card と並べて diff しやすい。次の動詞は message/send。検証の点検表と署名は、後の稿へ残す。
{
"kind": "discovery-trace",
"note": "CI/review fixture — not an official A2A or Google Registry API",
"query": {
"tags": ["returns", "classify"]
},
"strategy": "curated-registry",
"hits": [
{
"name": "Returns Specialist",
"cardUrl": "https://returns.agents.example.com/.well-known/agent-card.json",
"matchedTags": ["returns", "classify"],
"skillId": "classify-return"
}
],
"selected": {
"skillId": "classify-return",
"preferredInterface": {
"url": "https://agents.example.com/returns/a2a",
"protocolBinding": "JSONRPC",
"protocolVersion": "1.0"
},
"next": "message/send"
}
}
| このホップ | 入力 | 断言すべきこと |
|---|---|---|
| カタログを探す | tags またはスキル名 | 命中一覧が空でなく、参照を持つ |
| well-known を取る | ホスト名または cardUrl | JSON が parse でき、1.0 Schema を通る |
| 選定 / インタフェースを選ぶ | 完全な 1.0 Card | skill id が合い、クライアントがそのインタフェースを話せる |
キャッシュ、古い索引、検査用データ
Card は頻繁には動かない。スキルを足す、認証を変える、そのとき動く。発見面はそれでも古くなる。カタログの索引が遅れ、well-known は新しい version を出し、検索は古い tags を指す。検査データは少なくとも二組。カタログ命中のスナップショットと、いま GET した Card。キーワードが外れたら、先に tags と索引の遅れを見る。1.0 クライアントが 0.3 のカードを読んだ疑いはその次だ。
{
"hop": "well-known",
"method": "GET",
"url": "https://returns.agents.example.com/.well-known/agent-card.json",
"requestHeaders": {
"If-None-Match": "1.0.3"
},
"response": {
"status": 304,
"etag": "1.0.3",
"cacheControl": "max-age=3600"
}
}
仕様ははっきり書く。機微なデータには認証が要る。帯域外の動的な資格情報を勧め、静的な秘密を Card に書くな。発見用データに token や社内パスワードがあれば、レビューはその場で戻す。公開カードは取られる前提で書け。拡張カードのキャッシュはセッションに従う。公開カードの max-age と同じ桶に流し込むな。
Plugin の SKILL.md や MCP の tools/list を発見源にするな。同じ倉庫の Coding Agent がスキルを伸ばすのは箱の話。別チームの返品 Agent が見つかるのは Card の話。一つの capability.json に押し込めば、三つの失敗したホップが同じ票の一行に落ちる。
ブラウザで足りる:JSON 整形で走査データと Card が parse できるか見る。JSON Schema 検証で命中後の 1.0 Card を確かめる。JSON Diffでカタログのスナップショットと今取った Card を比べ、tags / インタフェースのずれを拾う。データは手元を出ない。続きは Agent Card フィールド解説、Registry の概観。署名と検証の点検表は次の実戦稿。
関連:A2A Agent Card JSON Schema、Google Agent Registry、A2A vs MCP。
よくある質問
カタログがあれば、well-known は GET しなくてよいか
否。カタログは Card を消費する。Card を置き換えない。仕様は公開発見の標準経路として well-known を書く。カタログが落ちても、ホスト名を握るクライアントは名刺を読むべきだ。
A2A に「Agent を探す」標準 RPC はあるか
ない。発見ページは明示する。現行仕様はキュレーションカタログの API を定めない。問い合わせは各カタログが自分で定義する。標準なのは Card の形と well-known の経路だ。
見つけたら tools/call してよいか
いけない。命中は発見の結果。向こうは不透明な Agent。送るのは Task。確定的な引数は MCP ツールに残す。発見ホップに書くな。
キャッシュはどれくらいが妥当か
先にサーバの Cache-Control と ETag に従う。ヘッダがなければ短い既定と、期限後の条件付き要求。スキルや認証が変われば version も動く。クライアントは古い tags で本番を回してはいけない。
まとめと次の一手
2026 年の「別の Agent を自動で見つける」は三ホップに畳める。戦略を選び、Card を得て、skills とインタフェースで委譲するかを決める。カタログはその扉の一つであり、プロトコルそのものではない。
出荷の順。公開 Agent は先に well-known を正しく掲げる。キーワードで探すなら、一社のカタログを繋ぎ、問い合わせ用データを自前で持つ。命中したら 1.0 Card を確かめてから Task を送る。フィールドの書き方は前回。カタログが何かは #5。検証と署名は後の稿。走査 JSON と倉庫の Card は JSONVue で対照せよ。