チュートリアル
A2A Agent Card JSON Schema 完全ガイド:名前・能力・Skills・インタフェース・Endpoint をどう定義するか
Card はオーケストレータ向けの契約であり、自前モデル向けの手引きではない。フィールドを誤ると、先に発見が壊れる。
前回の Agent Registry はカタログとソース JSON を分けた。今日は登録の話でも、発見ホップの話でもない。手元にあるのはコミットすべき agent-card.json。各フィールドは何か、どれが必須か、0.3 のトップレベル url は残してよいか。答えはスライドではなく A2A 仕様 §4.4。0.3 から 1.0 への移動は v1.0 の変更。Google のカタログは両契約を受ける。Registry JSON schemas を見よ。新しいカードは 1.0。検証の実戦は後の稿。今日はフィールドを広げる。
このカードは誰が読むか
Agent Card は A2A サーバが /.well-known/agent-card.json に掲げる公開名刺だ。読むのは自前のモデルではない。別のオーケストレータ、ゲートウェイ、組織内のカタログだ。答える文は三つ。あなたは誰か、どうつながるか、何を引き受けると名乗るか。第一は name / description / version。第二は supportedInterfaces。第三は skills[]。runbook を description に流し込めば 10KB 上限が先に来る。発見面は痩せる。
1.0 は必須を固定した。仕様表では name、description、supportedInterfaces、version、capabilities、defaultInputModes、defaultOutputModes、skills が Yes。一つ欠けると、1.0 クライアントは合法カードとして読んではならない。0.3 はトップレベルの url と protocolVersion で生きられた。1.0 クライアントはそれらを無視し、インタフェース配列だけを読む。二つのフィールド集合を混ぜると、カタログ抽出は黙って痩せる。チケットには「見つからない」とだけ残る。
カードは Plugin Manifest でも MCP の tools/list でもない。一つのコーディングエージェントがスキルをどう増やすかは Plugin の稿。呼び出しホップの引数は MCP と JSON Schema。今日は横の同僚が自分をどう述べるかだけ。署名、拡張カード、GetExtendedAgentCard は認証のあと。公開カードが先にスキルを述べる。
| フィールド | 1.0 で必須 | 何を書くか |
|---|---|---|
name / description / version | はい | 人向けの身元。version はエージェント自身の版 |
supportedInterfaces | はい | 順序付きエンドポイント。先頭が優先 |
capabilities / デフォルト MIME / skills | はい | 能力フラグ、メディア型、名乗ったスキル |
身元:name、description、version、provider
name はカタログを眺める人のためであり、内部サービス名ではない。description は範囲と境界:何をし、何をしないか。返品担当なら「返品申請を分類する。返金の仕訳はしない」。オーケストレータは README ではなく、この段落で Task を送るかを決める。
version はこのエージェントの発行版、例えば 1.0.3。プロトコル版はインタフェースに付き、supportedInterfaces[].protocolVersion に書く。両方に 1.0 と書くと、あとで実装だけ変えたときにどちらが動いたか分からない。provider は任意だが、書くなら対:organization と url。documentationUrl と iconUrl も任意。長い本文はドキュメント URL へ。名刺に積まない。
身元ブロックのあと一度止める。インタフェースがなければ呼べない。skills がなければカタログは見つけない。三文の第一を短く正しくしてから、エンドポイントを埋める。
インタフェース:エンドポイントは supportedInterfaces
1.0 の主エンドポイントはトップレベルにない。supportedInterfaces は順序付き配列で、先頭が優先。各項は url、protocolBinding、protocolVersion が必須。本番の url は絶対 HTTPS。公式の中核値は JSONRPC、GRPC、HTTP+JSON。仕様は拡張のため文字列を開けている。tenant は任意。マルチテナントのときだけ書く。
一つのエージェントが三つのバインディングを三つの URL に置ける。クライアントは配列順で、話せる最初を選ぶ。見た目のために三つとも同じ 404 を指さない。0.3 のトップレベル url と protocolVersion は旧契約。v1.0 変更ページは、それらを主フィールドにしないと書く。1.0 として登録しながら URL をトップに置くと、1.0 検証は落ちるか、主エンドポイントが無視される。
インタフェース配列は話し方を決め、仕事内容は決めない。JSONRPC だけで skills が無い:つながるが探せない。skills だけでインタフェースが無い:探せるが Task を出せない。両方要る。
capabilities とデフォルト MIME
1.0 では capabilities は必須オブジェクト。中の真偽は任意:streaming、pushNotifications、extendedAgentCard、それに extensions 配列。未記入または false なら、対応操作はエラーになるべきで、黙って再試行しない。0.3 の stateTransitionHistory を中核能力として戻さない。4.4.3 の表にもう無い。
defaultInputModes と defaultOutputModes は全 skill に効くメディア型配列。個別 skill は inputModes / outputModes で上書きできる。テキストだけなら text/plain。JSON を出すなら application/json を足す。空配列は未宣言であり、1.0 検証は通らない。ファイル拡張子や内部列挙を書かない。
extendedAgentCard が真なら、認証後に二枚目の厚いカードを取れる。公開カードはそれでも自立する:スキル、インタフェース、デフォルト MIME。重要な skill を拡張カードにだけ隠すと、未認証のカタログは検索面で見逃す。
skills[]:id、tags、examples
各 skill は id、name、description、tags が必須。id は安定した短いプログラム用キー。空白は避ける。name は人向け。description は入出力の境界であり、依然として引数スキーマではない。tags は 1.0 で必須の文字列配列。カタログとオーケストレータのキーワード。Google Registry も tags を索引する。空または省略:parse できても見つからない。
examples は任意。人向けのプロンプトや場面であり、JSON Schema ではない。1.0 は inputSchema を skill 契約にしない。古い実装はまだスキーマをぶら下げる。ヒントならよい。tools/call 契約にしてはいけない。対面は不透明なエージェントで、送るのは Task。サイト内の 0.3 断片が skill に inputSchema を置いているのは旧契約。新しいカードに写さない。
内部関数名で skill を切らない。一つはオーケストレータが委譲する仕事の種類。返品担当なら classify-return と check-window。「表を読む」「ログを書く」「メールを送る」を三つの検索語にしない。下はリポジトリに入れてよい 1.0 カード。まず parse、次に公式スキーマ。
{
"name": "Returns Specialist",
"description": "Classifies return requests and checks the return window. Does not post refunds.",
"version": "1.0.3",
"provider": {
"organization": "Example Commerce",
"url": "https://commerce.example.com"
},
"documentationUrl": "https://docs.example.com/returns-agent",
"supportedInterfaces": [
{
"url": "https://agents.example.com/returns/a2a",
"protocolBinding": "JSONRPC",
"protocolVersion": "1.0"
},
{
"url": "https://agents.example.com/returns/a2a/json",
"protocolBinding": "HTTP+JSON",
"protocolVersion": "1.0"
}
],
"capabilities": {
"streaming": true,
"pushNotifications": false,
"extendedAgentCard": false
},
"defaultInputModes": ["text/plain", "application/json"],
"defaultOutputModes": ["text/plain", "application/json"],
"skills": [
{
"id": "classify-return",
"name": "Classify a return",
"description": "Decide whether a request is a return, exchange, or warranty claim.",
"tags": ["returns", "classify", "commerce"],
"examples": ["This jacket arrived damaged. Is it a return or a warranty claim?"]
},
{
"id": "check-window",
"name": "Check return window",
"description": "Say whether the purchase is still inside the return window.",
"tags": ["returns", "policy", "deadline"],
"examples": ["Order 8841 was delivered on 2026-08-02. Can they still return it?"]
}
]
}
| フィールド | 必須 | よく壊れる点 |
|---|---|---|
id / name / description | はい | id を関数名から写す。description が runbook |
tags | はい | 無い、または空。カタログは探せない |
examples / スキルごとの MIME | いいえ | examples を inputSchema 扱い |
1.0 のカードに書いてはいけないもの
負例を少なくとも一枚残す。トップレベルに url が残り、skill に tags が無く、MCP 形の inputSchema が入っている。1.0 検証は落ちるべき。CI が 0.3 と 1.0 を「汎用エージェント検査」に潰すなら、クライアントより乱れている。Registry は宣言した版で規則を選び、読み込み中にスキーマを取りに行かない。
{
"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,
"stateTransitionHistory": 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" }
}
}
}
]
}
securitySchemes とセキュリティ要求は任意層。公開カードは署名なしで出せる。signatures は JWS。検証の歩き方は実戦の稿。覚えておく:署名は tags の代わりにならない。本物の skill が一つあるカードは、空のスキル配列の美しいカードより正直。skills は必須配列のまま。本当に何も無いとき以外、ゼロ件で出さない。
閉じた Plugin フィールド、SKILL.md のパス、MCP の tools[].name を Card に写さない。三つの JSON はどれも能力と書くが、失敗の扱いが違う。悪い Card は発見の失敗。
ブラウザでできる:JSON 整形でカードが parse するか見る。JSON Schema 検証で 1.0 の supportedInterfaces と skills[].tags を見る。JSON Diffでコミットしたカードと負例の、トップレベル url / tags 漏れを拾う。データは手元を出ない。続きはAgent Registry 概観、A2A vs MCP。発見の歩き方は次稿。
よくある質問
互換のためトップレベル url を残してよいか
1.0 として登録するなら主フィールドにしてはいけない。トップレベル url をまだ読むクライアントは 0.3 契約。新しいカードはエンドポイントを supportedInterfaces だけに置く。両方書くと、二つの契約が半分ずつ読む。
skill は id だけで、tags は後でか
合法な 1.0 にはできない。仕様は tags を Yes としている。カタログ検索は tags を食べる。「後で」は、今は探せないという意味。
description が短い。手引きはどこへ
documentationUrl か、エージェント自身のスキルや文書へ。カードには体積上限がある。手引きを名刺に入れると 10KB に先に当たり、発見面はゼロになる。
skill に inputSchema を付けるべきか
1.0 の契約としては付けない。形のヒントが要るなら examples と MIME。決定的なパラメータは MCP ツールへ。Agent Card には書かない。
まとめと次の一手
2026 年の A2A Agent Card は一枚の必須表に折れる。身元の三段、インタフェース配列、能力オブジェクト、デフォルト MIME、tags 付き skills。オーケストレータが読むのはこれらのフィールドであり、アーキテクチャ図ではない。
出す順:合法な 1.0 カード。インタフェース先頭は本物のエンドポイント。各 skill に空でない tags。JSONVue で parse とスキーマ。カタログがカードをどう受けるかは前回。ホップは次回。署名と検証リストはさらに後。