跳到主要内容

01 · 发现与 Agent Card

本章讲一切的起点:远程 agent 怎么描述自己(Agent Card),客户端怎么找到这张名片,以及怎么用密码学签名确认名片没被篡改。

1. 为什么需要“名片”

要把任务托付给一个黑盒 agent,你至少得先知道三件事:它在哪(端点 URL)、它会什么(技能)、怎么安全地连它(鉴权要求)。A2A 把这三类信息打包成一份 JSON 文档,叫 Agent Card(名片)——agent 的“数字名片”。

客户端拿到名片后,据此判断“这个 agent 适不适合干我这活、请求该怎么组、用什么凭证连”。

2. 名片里有什么

Agent Card 的结构由 proto 的 message AgentCard(specification/a2a.proto:361)定义。挑关键字段:

字段含义必填?
name / description身份:人读的名字与用途
supported_interfaces怎么连:一组 AgentInterface,各含 url + 传输绑定 + 协议版本;第一项是首选
provider服务提供方(组织名 + URL)
versionagent 自身版本(如 "1.0.0")
capabilities可选能力开关:streaming / push_notifications / extended_agent_card / 扩展列表
security_schemes / security_requirements鉴权方案与要求否 / 否
default_input_modes / default_output_modes默认收发的媒体类型(MIME)
skills会什么:一组 AgentSkill
signatures名片的 JWS 签名(见 §5)

“技能(skill)”是描述性的,不是 RPC。 AgentSkill(specification/a2a.proto:435)用 id / name / description / tags / examples 描述“这个 agent 大概擅长干哪类事”,还可按技能覆盖输入/输出模式。它帮客户端匹配与挑选,而不是一个可直接调用的函数签名——这再次体现“对等 agent,不是工具”的取向。

AgentInterface 是 v1.0 的关键升级:同一 agent 可以用多种传输暴露同一套能力。 每个接口声明自己的 urlprotocol_binding(JSONRPC / GRPC / HTTP+JSON,开放字符串)、和各自的 protocol_version(specification/a2a.proto:336-355)。客户端按顺序读 supported_interfaces,选第一个自己支持的传输——所以服务端应按偏好排序。

3. 客户端怎么找到名片:三种发现策略

名片“长什么样”是标准化的,但“去哪拿”依环境而定。规范列了三种(docs/topics/agent-discovery.md:18-71):

策略机制适合
Well-Known URIGET https://{域名}/.well-known/agent-card.json(遵循 RFC 8615)公开 / 域内广泛发现
Curated Registry(注册表)中心服务收录名片,客户端按 skill/tag 等查询企业内 / 公开市场
Direct Config(直配)硬编码、配置文件、环境变量、私有 API紧耦合 / 私有 / 开发期

注意:注册表的查询 API 目前未被规范标准化(docs/topics/agent-discovery.md:59)——这是协议刻意留白的边界。

最常见的 well-known 流程(三步):

Client 已知/推断出域名 smart-thermostat.example.com

▼ GET https://smart-thermostat.example.com/.well-known/agent-card.json
Server 返回 JSON 名片

▼ Client 解析 supported_interfaces → 选首选传输 → 据 capabilities/skills 决定怎么用

4. 公开名片 vs 受保护名片(Extended Agent Card)

名片本身可能含敏感信息(内部 URL、敏感技能描述)。A2A 的应对是分层:

  • 公开名片:放在 well-known URI 上,只放可公开的基本信息;敏感字段不放。
  • Extended(扩展)名片:鉴权后才给的、更详细的版本。客户端先走 OAuth 等拿到凭证,再调 GetExtendedAgentCard(specification/a2a.proto:122)取扩展名片。

要用扩展名片,agent 须在 capabilities.extended_agent_card 声明支持;否则调用要返回 UnsupportedOperationError,声明了但没配置则返回 ExtendedAgentCardNotConfiguredError(docs/specification.md:575)。

规范还建议名片端点用标准 HTTP 缓存(Cache-Control + ETag,ETag 可由 version 派生),客户端用 If-None-Match 做条件请求(docs/topics/agent-discovery.md:96-106)。

5. 让名片可验真:JWS 签名 + RFC 8785 规范化

要解决的问题。 你从某个 URL 拿到一张名片,怎么确认它确实来自声称的提供方、且没被中间人改过?A2A 的答案是给名片加 JWS(JSON Web Signature,RFC 7515) 签名,放进 signatures 字段(AgentCardSignature,specification/a2a.proto:456)。

最巧妙的一步:签名前必须“规范化(canonicalize)”。 同一份 JSON,不同库序列化出来的字节可能不同(键顺序、空格、默认值要不要写)。要让“签名时算的字节”和“验签时重建的字节”一字不差,必须先做 JSON Canonicalization Scheme(JCS,RFC 8785):键按字典序、统一数字/字符串表示、去掉无意义空白(docs/specification.md:2018-2021)。

更微妙的是默认值的取舍——这里 proto 的字段存在性语义直接决定规范化结果(docs/specification.md:2012-2016):

  • 标了 optional显式设过的字段(哪怕值等于默认)→ 保留;
  • 标了 optional没设的 → 删除;
  • 标了 REQUIRED 的 → 始终保留(即使是默认值);
  • 其余带默认值的字段 → 删除(除非 REQUIRED 或 optional)。

规范给的例子(docs/specification.md:2025-2056):一个含 streaming:falseextensions:[] 的片段,因为 streaming 是显式设的 optional 要留、extensions 是空的非必填 repeated 要删,最终规范化成:

{"capabilities":{"pushNotifications":false,"streaming":false},"description":"","name":"Example Agent","skills":[]}

签名/验签流程(简化):

签名方 验签方
────── ──────
1. 删默认值字段 + 删 signatures 1. 取 signatures[i]
2. RFC 8785 规范化 → payload 2. 据 kid/jku 取公钥
3. 造 protected 头(alg/typ/kid) 3. 删默认值字段 + 删 signatures
4. 签名 base64url(头)+"."+payload 4. RFC 8785 规范化
5. 装进 AgentCardSignature 5. 验签

关键点(docs/specification.md:2023:2117-2134):signatures 字段本身必须排除在被签内容之外(否则循环依赖);客户端应至少验一个签名再信任名片;支持多签名以便密钥轮换。

6. 边界与坑

  • 注册表 API 没标准化——跨注册表互通仍需各自约定。
  • 名片是“声明”,不是“保证”:agent 声称支持某技能,不等于一定成功。规范明确技能“largely descriptive”(specification/a2a.proto:391-393)。
  • 规范化极易踩坑:默认值删错一个、键序错一处,验签就失败。务必严格按 §5.7 的存在性规则。

7. 代码地图

主题文件符号 / 锚点
名片结构specification/a2a.protomessage AgentCard(:361)
多传输接口声明specification/a2a.protomessage AgentInterface(:336)
技能描述specification/a2a.protomessage AgentSkill(:435)
能力开关specification/a2a.protomessage AgentCapabilities(:411)
签名对象specification/a2a.protomessage AgentCardSignature(:456)
发现策略docs/topics/agent-discovery.md“Discovery Strategies”
签名规则docs/specification.md§8.4(:2002)
扩展名片 RPCspecification/a2a.protorpc GetExtendedAgentCard(:122)