Client、Server 与 Agent Card

能力发现 (Agent Discovery) 是指一个 Agent 如何知道另一个 Agent 是谁、会什么、怎么连、要什么认证。

两个角色

  • A2A Client(客户端):发起请求的一方。可以是一个应用,也可以是另一个Agent。
  • A2A Server(服务端,又称 Remote Agent 远程 Agent):暴露 A2A 标准HTTP 端点的 Agent,接收任务、处理、返回结果。

注意:角色是相对的。Agent A 委派任务给 B 时,A 是 Client、B 是 Server;B 再转包给 C 时,B 又成了 Client。

2Agent Card:Agent 的"名片”

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

下面是一个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 写进配置 私有/紧耦合系统

安全提示

  • Agent Card 本身可能包含敏感信息,公开部署时卡片里别放密钥;
  • v1.0 支持对卡片做 JWS 数字签名(signatures 字段),Client 可验签防止"名片被伪造”。

示例:用代码做发现(Python SDK)

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      │
  │ ───────────────────────────────────>│

能力发现之后的第一件事就是发消息、建任务,下一节介绍