能力发现 (Agent Discovery) 是指一个 Agent 如何知道另一个 Agent 是谁、会什么、怎么连、要什么认证。
注意:角色是相对的。Agent A 委派任务给 B 时,A 是 Client、B 是 Server;B 再转包给 C 时,B 又成了 Client。
Agent Card 是一份 JSON 元数据文档,是整个发现机制的核心。A2A Server 把它发布在一个约定俗成的路径上:
https://<agent 域名>/.well-known/agent-card.json
早期版本(v0.2 之前)路径是
/.well-known/agent.json,网上旧教程常见,已废弃。
Client 拿到这份"名片"后,就知道:
┌───────────────────────────────────────────────┐
│ Agent Card(名片) │
├───────────────────────────────────────────────┤
│ 我是谁 name / description / version │
│ 怎么连我 supportedInterfaces(URL + 传输绑定│
│ + 协议版本,如 JSONRPC / GRPC) │
│ 我会什么 skills[](技能列表:id/名称/描述/ │
│ 标签/示例) │
│ 我支持什么 capabilities(streaming 流式? │
│ pushNotifications 推送?) │
│ 格式偏好 defaultInputModes / OutputModes │
│ (MIME 类型,如 text/plain) │
│ 怎么认证 securitySchemes(OAuth2/APIKey 等) │
│ 防伪签名 signatures(可选,JWS 签名) │
└───────────────────────────────────────────────┘
下面是一个Agent Card示例:
{
"name": "Dice Agent",
"description": "一个会掷骰子的极简 A2A Agent,输入如 '2d6' 即掷 2 个 6 面骰。",
"version": "1.0.0",
"supportedInterfaces": [
{
"url": "http://localhost:9999/",
"protocolBinding": "JSONRPC",
"protocolVersion": "1.0"
}
],
"capabilities": { "streaming": true },
"defaultInputModes": ["text/plain"],
"defaultOutputModes": ["text/plain"],
"skills": [
{
"id": "roll_dice",
"name": "掷骰子",
"description": "按 NdM 格式掷 N 个 M 面骰子并返回结果",
"tags": ["dice", "game"],
"examples": ["roll 2d6", "掷 3d20"]
}
]
}
supportedInterfaces:到哪、用什么协议连。一个 Agent 可以同时提供JSON-RPC 和 gRPC 两个接口;Client 按自己支持的绑定挑一个。skills:技能清单。tags 和 examples 很重要——编排型 Agent(或 LLM)靠它们判断"这个任务该派给谁”。capabilities.streaming: true:表示支持 SendStreamingMessage(SSE 流式)。| 方式 | 说明 | 适用场景 |
|---|---|---|
| Well-Known URI | 直接 GET /.well-known/agent-card.json |
最常用,公开/内网服务 |
| 注册中心(Registry/Catalog) | 企业统一的 Agent 目录,按技能检索 | 大型组织治理 |
| 直接配置 | 把 Agent Card 或 URL 写进配置 | 私有/紧耦合系统 |
signatures 字段),Client 可验签防止"名片被伪造”。import httpx
from a2a.client import A2ACardResolver
async with httpx.AsyncClient() as http:
resolver = A2ACardResolver(http, "http://localhost:9999")
card = await resolver.get_agent_card() # GET /.well-known/agent-card.json
print(card.name) # Dice Agent
print(card.capabilities.streaming) # True
print([s.name for s in card.skills]) # ['掷骰子']
对应的时序:
Client Server
│ GET /.well-known/agent-card.json │
│ ───────────────────────────────────>│
│ 200 OK + AgentCard(JSON) │
│ <───────────────────────────────────│
│ │
│ (解析卡片 → 选择接口/绑定 → │
│ 按 securitySchemes 准备认证) │
│ 之后的任务请求发往卡片中的 url │
│ ───────────────────────────────────>│
能力发现之后的第一件事就是发消息、建任务,下一节介绍