チュートリアル

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/AgentCard0.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 の inputSchemaJSON を直す / 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 で対照せよ。