教程

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/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。不要用 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 对合法卡、红卡和报告。