チュートリアル
A2A 1.0 Agent Card JSON 実戦:能力の名乗り、Skills の形、エージェント間の通信データをどう検証するか
検証が失敗したら、先にどの層が緑だったかを問え。parse できたのか、生成 Schema を通ったのか、仕様の必須表に合ったのか。
前回の 発見の走査 は well-known、カタログ、それから Card まで歩いた。フィールドの書き方は先の Agent Card フィールド解説。今日はフィールドを埋め直さない。ホップも辿り直さない。手元にはもう一枚ある。または今 GET した。問いは、それを適法だとどう断言するか、送る Task がゴミ扱いされないか。原文は A2A 1.0 仕様 の §4.4 と §3.3.4。サイトの a2a.json は自ら書く。proto から抜いた非規範の JSON Schema 束だ。0.3 から 1.0 への移動は v1.0 の変更。
緑は合格ではない
生成束を Ajv に投げ、根を指し、緑を見る——レビューでいちばん多い偽の合格だ。根は Card ではない。AgentCard、AgentSkill、Task、Message は $defs の下にある。束の根を検証しても、何も検証していない。正しいポインタは #/$defs/AgentCard。通信は #/$defs/Task か #/$defs/Message。Task を Card の Schema で包むな。
ポインタが正しくても、生成束はしばしば required を欠く。2026 年 9 月のサイト上の AgentCard と AgentSkill は additionalProperties: false を置くが、仕様表の必須を required に並べない。空の name、tags のない skill でも緑になりうる。必須の源は仕様表だ。name、description、version、supportedInterfaces、capabilities、defaultInputModes、defaultOutputModes、skills。各 skill にはなお id / name / description / tags が要る。
だから少なくとも二度見る。一度目:parse でき、生成の AgentCard が extra key で爆発しない。二度目:仕様表が非空を断言する。一度目だけなら、0.3 の名残のトップレベル url は additionalProperties: false で掴める。tags のない skill は逃げる。二度目だけ、生成束なしでは、紛れ込んだ inputSchema を逃がす。両方要る。
| この層 | 掴めるもの | 掴めないもの |
|---|---|---|
| JSON.parse | 壊れた文法、切り詰め、末尾のカンマ | 形が正しいか |
生成の #/$defs/AgentCard | 0.3 のトップレベル url、skill 上の inputSchema | 仕様の必須が書かれたか |
| 仕様 §4.4 の必須表 | 空の name、欠けた tags、空の skills | 旗がこれから送る操作と合うか |
四層。一層は一種類の誤りだけを掴む
第三層は能力の旗。仕様 §3.3.4 ははっきり書く。streaming が偽なのに購読すれば、エージェントは UnsupportedOperationError を返さねばならない。pushNotifications が偽なのに webhook を置けば PushNotificationNotSupportedError。extendedAgentCard が偽なのに拡張カードを取れば、同じ不支持。Schema は緑、必須も揃い、次のホップはそれでも跳ねる。検査データは「Card は適法」と「この操作は旗に許される」を二段で書け。
第四層は通信。送るのは Task か Message。Card を再度 POST しない。InvalidAgentResponseError は応答の形であり、名刺ではない。MIME は defaultInputModes か skill の inputModes に合わせる。外れは ContentTypeNotSupportedError。A2A の skill を MCP の inputSchema で見るな。1.0 の手がかりは examples と MIME。
生成束には snake_case の patternProperties もある(supported_interfaces、default_input_modes)。仕様の JSON は camelCase。新しいカードは仕様表に従う。CI が両方の鍵名を受けると、Diff が先に汚れる。互換層を明示して養うのでなければ、proto のフィールド名を公開名刺に写すな。検査データにそう書け。
Card:根ではなく AgentCard を指せ
倉庫に a2a.json を釘付けし、公開束の版と揃える。CI は漂う latest URL を叩くな。Ajv(または任意の 2020-12 実装)の schema ポインタは #/$defs/AgentCard。instance は今 GET したカード、または倉庫の agent-card.json。path と keyword を出せ。path が検査データと合わなければ、カードを疑う前にポインタを疑え。
一度目でいちばん価値がある拒否は extra key。1.0 のエンドポイントは supportedInterfaces。トップレベルに残った url、protocolVersion、supportsAuthenticatedExtendedCard は additionalProperties: false で赤になる。0.3 の残りであり、「多いほど安全」ではない。フィールド解説は移動を書いた。今日求めるのは一つ。検証器はそれらの鍵を誤りとして印せ。無視するな。
インタフェース項は三つ見る。本番の url は絶対 HTTPS(gRPC は host:port)、protocolBinding はクライアントが話せるバインディング、protocolVersion は 1.0 のようなプロトコル版であり、エージェント自身の version ではない。どちらも version と呼ばれる。検査データは分けて断言せよ。先頭が優先。共通のバインディングがなければ通話はない。
skills:仕様は必須、Schema はしばしば問わない
生成の AgentSkill も required を欠くことが多い。tags のない skill は Ajv で緑でも、検索面は空だ——発見の稿で書いた。今日の断言:各 skill は空でない id、name、description と、少なくとも一つの tag を持つ。空の skills 配列は仕様表を通らない。ホストだけの NO_SPEC 項目は、登録の前に赤になるべきだ。キーワードホップが空を打ったあとではない。
skill に inputSchema を載せるな。additionalProperties: false は extra key と見る。それは MCP ツールの話。サイト内の Schema 稿を見よ。1.0 の skill が見せるのは examples と MIME。関数の引数表を名刺に流し込めば、一度目で失敗すべきだ。検証での失敗は、Task を送ったあとの確認より安い。
下のカードは一度目か二度目で赤になるためのものだ。「もう少しで使える」草稿ではない。0.3 のトップレベル url、tags のない skill、MCP 風の inputSchema が混ざる。倉庫の Returns Specialist と並べて diff せよ。三つの赤は三つの path に落ちるべきだ。
{
"name": "Returns Specialist",
"description": "Classifies return requests.",
"version": "1.0.3",
"url": "https://agents.example.com/returns/a2a",
"protocolVersion": "1.0",
"supportedInterfaces": [
{
"url": "https://agents.example.com/returns/a2a",
"protocolBinding": "JSONRPC",
"protocolVersion": "1.0"
}
],
"capabilities": {
"streaming": true
},
"defaultInputModes": ["text/plain"],
"defaultOutputModes": ["text/plain"],
"skills": [
{
"id": "classify-return",
"name": "Classify a return",
"description": "Decide the request type.",
"inputSchema": {
"type": "object",
"required": ["orderId"],
"properties": {
"orderId": { "type": "string" }
}
}
}
]
}
| 検査 | 失敗の形 | 次のホップ |
|---|---|---|
| parse + AgentCard ポインタ | 末尾カンマ;トップレベル url;skill の inputSchema | JSON を直す / 0.3 の鍵を捨てる |
| 仕様の必須 / 非空 | 空の name;tags のない skill;空の skills | §4.4 からフィールドを埋める |
| 旗 vs 操作 | streaming が偽なのに購読;未宣言の拡張カードを取る | クライアントを変えるか、Card の旗を変える |
通信データ:Task は名刺ではない
Card が通ってから message/send。本体はバインディングに従う。JSON-RPC、gRPC、HTTP+JSON。中の業務オブジェクトは Message か Task であり、AgentCard ではない。要求を Card 定義で見れば必ず赤になり、学びもない。生成束には別の Task、Message、Part、Artifact がある。通信用データはポインタを切り替えよ。Card の一行を使い回すな。
応答も見よ。仕様は約定に合わないエージェントの返信を InvalidAgentResponseError に畳む。状態機械は submitted / working / completed / failed / canceled / rejected、それに中断の input-required と auth-required。completed だけを成功と見ると、「もう一文足せ」が障害票になる。それらの鍵は名刺にない。発見は成功し通話は失敗した——票は層を書け。
下の JSON は検証報告用のデータであり、どのカタログや A2A の公式 RPC でもない。四層を一つのオブジェクトに畳む。倉庫の Card と一回の message/send と並べて diff しやすい。署名の検査は形だけを断言する。signatures[] の各項に protected と signature(RFC 7515 JWS)。本物の鍵と本物の検証はセキュリティレビューへ。秘密鍵を検査データに入れるな。
{
"kind": "card-validation-report",
"note": "CI/review fixture — not an official A2A RPC",
"target": "agent-card.json",
"schema": {
"bundle": "https://a2a-protocol.org/latest/spec/a2a.json",
"pointer": "#/$defs/AgentCard",
"normative": false
},
"parse": true,
"schemaPass": false,
"schemaErrors": [
{ "path": "/url", "keyword": "additionalProperties" },
{ "path": "/skills/0/inputSchema", "keyword": "additionalProperties" }
],
"specChecks": [
{ "id": "required-name", "pass": true },
{ "id": "skills-tags-nonempty", "pass": false },
{ "id": "no-top-level-url", "pass": false }
],
"capability": {
"streaming": true,
"clientWillStream": true,
"ok": true
},
"next": "fix-card"
}
署名、検査データ、手元の対照
仕様は signatures を RFC 7515 の形で許す。配列があるなら、先に二つの必須文字列が空でないことを断言し、それから検証するかを決める。配列がないことはカードを違法にしない。フィールドは任意だ。公開カードは取られる前提で書け。静的な秘密や社内パスワードを Card に書くな。拡張カードはセッションに従う。公開カードと「検証済み」キャッシュを共有するな。
Plugin の SKILL.md や MCP の tools/list を同じ Card 検査に流し込むな。箱の中のスキルはこの倉庫の Coding Agent 向け。別チームの自己記述は Card。一つの capability.json に押し込めば、三層の失敗が同じ票の一行に落ちる。
ブラウザで足りる:JSON 整形でカードと報告が parse できるか見る。JSON Schema 検証で公式束を AgentCard に向け、ポインタを切り替えて Task を見る。JSON Diffで適法なカードと赤いカードを比べ、extra key と欠けた tags を拾う。データは手元を出ない。続きは Agent Card フィールド解説、発見の走査。カタログが何かは Registry の概観。
関連:A2A Agent Card JSON Schema、Agent が別の Agent を見つける、Google Agent Registry。
よくある質問
Ajv が a2a.json で緑なら、二度目は不要か
要る。サイトの束は自ら非規範と書き、生成定義はしばしば required を欠く。必須の源は仕様表。緑は extra key と型を踏まなかったことだけを意味する。
一つの Schema で Card と Task の両方を見られるか
見られない。ポインタを切り替えよ。AgentCard と Task は二つの $defs。要求を Card で包めば、失敗メッセージは次のホップを誤らせる。
skill に JSON Schema を入参として掛けてよいか
1.0 の skill は inputSchema を受けない。それは MCP ツール。生成束は extra key と見る。確定的な引数はツールのホップに残せ。名刺に書くな。
signatures がなければ違法か
違法ではない。仕様では signatures は任意。配列があるなら JWS の二つの必須文字列を断言する。なければ、なお §4.4 の必須と旗を見る。
まとめと次の一手
2026 年の「Agent Card を検証する」は四層に畳める。parse、生成束のポインタ、仕様の必須表、それから旗と通信。カタログと発見は入口。検証は委譲してよいかの門番だ。
出荷の順。a2a.json を釘付けし、ポインタは AgentCard。仕様表の非空断言を走らせ、Task を送る前に旗と MIME を見る。通信用データは Task / Message に切り替え。フィールドの書き方はフィールド解説。カードの見つけ方は発見の稿。適法なカード、赤いカード、報告は JSONVue で対照せよ。