教程
A2A 1.0 Agent Card JSON 實戰:如何驗證 Agent 能力描述、Skills Schema 與跨 Agent 通信數據?
校驗失敗時,先問綠的是哪一層:能 parse、過了生成 Schema,還是對照規範必填表。
上一篇 發現鏈路 把 well-known、目錄、再對 Card 走完了。字段怎麼寫,見更早的 Agent Card 字段教程。今天不重填字段,也不重走 hop。手裏已經有一張卡,或剛 GET 到一張卡,問的是:怎麼斷言它合法,以及發出去的 Task 會不會被對面當垃圾。規範原文在 A2A 1.0 規範 §4.4 與 §3.3.4。站點上的 a2a.json 自己寫明:這是從 proto 抽出的非規範 JSON Schema 包。1.0 相對 0.3 的搬家見 v1.0 變更。
綠了不等於過了
把生成包丟進 Ajv,指針指到根對象,整包過了——評審裏最常見的假綠。根對象不是一張 Card。$defs 裏纔有 AgentCard、AgentSkill、Task、Message。對整包根做校驗,等於沒校驗。正確指針是 #/$defs/AgentCard。通信數據另指 #/$defs/Task 或 #/$defs/Message,不要拿名片 Schema 去套 Task。
即便指針對了,生成包也常缺 required。2026 年 9 月站點上的 AgentCard 與 AgentSkill 都寫了 additionalProperties: false,卻沒有把規範表裏的必填列進 required。空字符串的 name、缺 tags 的 skill,Ajv 仍可能綠。規範表纔是必填源: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。不要用 MCP inputSchema 去核 A2A skill——1.0 的 skill 提示是 examples 和 MIME。
生成包裏還有 snake_case 的 patternProperties(supported_interfaces、default_input_modes)。規範 JSON 用 camelCase。新卡按規範表寫 camelCase。CI 若同時收兩套鍵名,Diff 會先髒。不要把 proto 字段名抄進公開名片,除非你明確在養兼容層,並且測試夾具裏寫明。
對 Card:指向 AgentCard,不要對整包根
倉庫裏釘一份 a2a.json,版本和站點發布的 bundle 對齊,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 這類協議版本,不是 Agent 自己的 version。兩項都叫 version,夾具要分開斷言。第一項是首選——客戶端挑得到共同綁定,通話纔開始。
對 skills:規範必填,Schema 經常不問
生成包裏的 AgentSkill 同樣常常沒有 required。缺 tags 的 skill,Ajv 可能綠,目錄搜索面卻是空的——發現文寫過。今天的斷言是:每個 skill 必須有非空 id、name、description,以及至少一項 tags。空 skills 數組過不了規範表。NO_SPEC 那種只有主機的條目,校驗應在登記前就紅,而不是等關鍵詞 hop 打空。
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;skill 無 tags;空 skills | 按 §4.4 補字段 |
| 旗標 vs 操作 | 不支持流還訂流;未聲明擴展卡還去拉 | 改客戶端,或改 Card 旗標 |
對通信數據:Task 不是名片
Card 過了,才輪到 message/send。請求體按綁定走 JSON-RPC、gRPC 或 HTTP+JSON,裏面的業務對象是 Message 或 Task,不是 AgentCard。用名片定義去校驗請求,必紅,而且紅得沒意義。生成包裏另有 Task、Message、Part、Artifact。CI 爲通信夾具換指針,不要複用 Card 那一行。
響應也要核。規範把不合約定的 Agent 回包收成 InvalidAgentResponseError。狀態機是 submitted / working / completed / failed / canceled / rejected,以及中斷態 input-required、auth-required。客戶端把 completed 當唯一成功,會把「還要你補一句」寫成故障。這些鍵不在名片上。發現成功、通話失敗,故障單要寫清是哪一層。
下面是一份校驗報告夾具,不是任何一家目錄或 A2A 的官方 RPC。它把四層結果收成 JSON,方便和倉庫 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 的;對面 Agent 的自述是 Card。混進一份 capability.json,三層失敗會算到同一行。
瀏覽器裏即可完成:JSON 格式化看卡和報告能否 parse;JSON Schema 校驗把官方 bundle 指到 AgentCard,再換指針核 Task;JSON Diff對比合法卡與故意紅的卡,抓 extra key 和缺 tags。數據不離開本機。延伸閱讀:Agent Card 字段教程、發現鏈路。目錄是什麼讀 Registry 總覽。
相關文章:A2A Agent Card JSON Schema、Agent 如何發現另一個 Agent、Google Agent Registry。
常見問題 FAQ
Ajv 對 a2a.json 綠了,還要不要第二遍?
要。站點 bundle 寫明非規範,且生成定義常缺 required。規範表纔是必填源。綠了只說明沒踩 extra key 和類型。
能不能用同一份 Schema 校驗 Card 和 Task?
不能。指針必須換。AgentCard 和 Task 是兩個 $defs。拿名片套請求,失敗信息會誤導下一跳。
skill 能不能掛 JSON Schema 當入參?
1.0 的 skill 不收 inputSchema。那是 MCP 工具。生成包會把它當 extra key。確定性參數留給工具 hop,不要寫進名片。
沒有 signatures 算不算非法?
不算。規範裏 signatures 可選。有數組,再核 JWS 兩項必填。沒有數組,仍按 §4.4 核必填和旗標。
總結與下一步
2026 年說「驗證 Agent Card」,可以收成四層:parse、生成包指針、規範必填表、旗標與通信數據。目錄和發現是進門,校驗是能不能委託的門衛。
落地順序:CI 釘住一份 a2a.json,指針寫 AgentCard;再跑規範表非空斷言;發 Task 前核對旗標和 MIME;通信夾具換 Task / Message 指針。字段怎麼寫讀字段教程;怎麼找到這張卡讀發現文。用 JSONVue 對合法卡、紅卡和報告。