智能体发现与 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"}生成签名的步骤:
- 准备载荷:移除带默认值的属性、排除
signatures字段,再按 RFC 8785 规范化; - 构造受保护头并做 base64url 编码,得到
protected; - 计算签名输入
ASCII(BASE64URL(UTF8(受保护头)) || '.' || BASE64URL(载荷)),用alg指定的算法与私钥签名,对结果做 base64url 编码,得到signature; - 组装
AgentCardSignature,可选地附上未受保护头。
签名验证
验证签名的客户端必须依次:
- 从
signatures数组中取出签名; - 用
kid与jku(或受信任的密钥库)取得公钥; - 移除接收到的卡片中带默认值的属性,并排除
signatures字段; - 按 RFC 8785 规范化;
- 对规范化后的载荷验证签名。
安全考虑:客户端应当在信任卡片前至少验证一个签名;公钥应当通过 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。
相关页面
- 核心协议规范
:
GetExtendedAgentCard的行为与能力校验; - 智能体发现 :开放、策展与私有三种发现策略;
- 认证、授权与安全考量 :扩展 Agent Card 的访问控制要求;
- 企业级特性 :认证、授权与安全实践。