智能体发现与 Agent Card

Agent Card 是 A2A 服务端公开的 JSON 元数据文档,描述智能体的身份、能力、技能、服务端点与认证要求。客户端借助它发现合适的智能体并配置交互方式。以下整理自规范第 8 章;字段定义见数据结构 ,发现策略的实践讨论见智能体发现 。

发布要求与发现机制

A2A 服务端必须提供一份 Agent Card。客户端可以通过以下方式找到它:

机制说明
知名 URI(Well-Known URI)访问 https://{server_domain}/.well-known/agent-card.json,也是 Python SDK 公开卡片的默认端点
注册中心/目录查询经过管理的智能体目录
直接配置预先配置 Agent Card 的 URL 或内容

声明协议:supportedInterfaces

Agent Card 必须正确声明所支持的协议:

  • supportedInterfaces 应当按偏好顺序声明所有支持的协议组合,第一项是首选接口;
  • 每个接口必须准确声明传输协议(protocolBinding)、协议版本(protocolVersion)与 URL;多种传输可以复用同一个 URL;
  • 客户端必须这样选择:解析 supportedInterfaces 并选择第一个自己支持的传输;多个选项都支持时,优先靠前的条目;使用所选传输对应的 URL;
  • 客户端必须在每个请求消息的 tenant 字段中,原样填入所选 AgentInterface 声明的 tenant 值;如果该条目没有设置 tenant,则请求中必须省略该字段。多租户的部署方式见多租户 。

一个声明了三种绑定的最小 Agent Card 示例(改编自官方规范):

{
  "name": "Example Agent",
  "description": "An example agent that echoes messages.",
  "supportedInterfaces": [
    {"url": "https://example.com/a2a/v1", "protocolBinding": "JSONRPC", "protocolVersion": "1.0"},
    {"url": "https://example.com/a2a/grpc", "protocolBinding": "GRPC", "protocolVersion": "1.0"},
    {"url": "https://example.com/a2a/json", "protocolBinding": "HTTP+JSON", "protocolVersion": "1.0"}
  ],
  "version": "1.0.0",
  "capabilities": {
    "streaming": true,
    "pushNotifications": false,
    "extendedAgentCard": false
  },
  "defaultInputModes": ["text/plain"],
  "defaultOutputModes": ["text/plain"],
  "skills": [
    {
      "id": "echo",
      "name": "Echo",
      "description": "Echoes the input.",
      "tags": ["echo"]
    }
  ]
}

Agent Card 签名

Agent Card 可以用 JSON Web Signature(JWS,RFC 7515 )进行数字签名,以保证真实性与完整性:客户端据此确认卡片没有被篡改,并确实来自声称的提供方。

规范化

签名之前,卡片内容必须按 JSON Canonicalization Scheme(JCS,RFC 8785 )规范化,以保证不同 JSON 实现生成和验证的一致性。规范化前须遵守 proto 的字段存在性语义:

  • 未显式设置的 optional 字段必须从 JSON 中省略;
  • 显式设置过的 optional 字段(即使值等于默认值)必须保留;
  • 标记为 REQUIRED 的字段必须始终存在;
  • 带默认值的字段必须省略,除非它是 REQUIRED 或带有 optional 关键字;
  • 对象属性按键的字典序排列,数字、字符串等基本值按 RFC 8785 统一表示。

签名格式

签名是 AgentCardSignature 对象,由三个字段表示 JWS 的组成部分:

字段说明
protected必填。base64url 编码的 JWS 受保护头(JSON 对象)
signature必填。base64url 编码的签名值
header可选。未受保护头(JSON 对象,不做 base64url 编码)

受保护头必须包含 alg(签名算法,如 ES256、RS256)、typ(应当为 JOSE)与 kid(密钥 ID),可以包含 jku(指向含公钥的 JWKS 的 URL)。例如:

{"alg":"ES256","typ":"JOSE","kid":"key-1","jku":"https://example.com/agent/jwks.json"}

生成签名的步骤:

  1. 准备载荷:移除带默认值的属性、排除 signatures 字段,再按 RFC 8785 规范化;
  2. 构造受保护头并做 base64url 编码,得到 protected;
  3. 计算签名输入 ASCII(BASE64URL(UTF8(受保护头)) || '.' || BASE64URL(载荷)),用 alg 指定的算法与私钥签名,对结果做 base64url 编码,得到 signature;
  4. 组装 AgentCardSignature,可选地附上未受保护头。

签名验证

验证签名的客户端必须依次:

  1. 从 signatures 数组中取出签名;
  2. 用 kid 与 jku(或受信任的密钥库)取得公钥;
  3. 移除接收到的卡片中带默认值的属性,并排除 signatures 字段;
  4. 按 RFC 8785 规范化;
  5. 对规范化后的载荷验证签名。

安全考虑:客户端应当在信任卡片前至少验证一个签名;公钥应当通过 HTTPS 等安全通道获取;客户端可以为已知的智能体提供方维护受信任的密钥库;已过期或已吊销的密钥不得用于验证;为支持密钥轮换,卡片中可以同时存在多个签名。

缓存

Agent Card 的变化频率远低于被拉取的频率,服务端与客户端应当使用标准 HTTP 缓存机制来减少不必要的网络开销。

服务端:

  • Agent Card 的 HTTP 端点应当返回带有合适 max-age 的 Cache-Control 响应头;
  • 应当返回 ETag,取值来自卡片的 version 字段或卡片内容的哈希;
  • 可以返回 Last-Modified。

客户端:

  • 应当遵守 RFC 9111 定义的 HTTP 缓存语义;
  • 缓存的卡片过期后,应当使用条件请求(If-None-Match 搭配保存的 ETag,或 If-Modified-Since),避免重新下载未变化的卡片;
  • 服务端没有返回缓存头时,可以采用实现自定的默认缓存时长。

扩展 Agent Card 与访问控制

公开卡片可以声明 capabilities.extendedAgentCard: true,让通过认证的客户端用 GetExtendedAgentCard 获取更详细的版本(例如额外的技能)。客户端必须使用公开卡片声明的认证方案,并且应当在认证会话期间用扩展卡片替换缓存的公开卡片。

Agent Card 可能包含敏感信息。实现者可以通过访问控制、要求认证与授权来保护它:例如在组织内部,即使遵循 .well-known 路径的公开发现也可以通过 mTLS 限定给特定客户端;注册中心和私有发现接口应当要求认证,并按身份返回不同内容。切勿在没有认证保护的前提下,把 API 密钥之类的凭据放入 Agent Card。

相关页面

来源:A2A 官方规范 · Agent Discovery: The Agent Card