4241 字
21 分钟
A2A(Agent2Agent Protocol)使用笔记

A2A 是一个用于不同 Agent 之间通信与协作的开放协议。它要解决的问题是:一个 Agent 如何发现另一个 Agent、了解它的能力、向它提交任务、跟踪任务进度,并获取最终结果。

1. A2A 到底解决什么问题?#

假设有两个 Agent:

  • Agent A:负责接收用户需求、拆解任务和调度。
  • Agent B:负责分析代码项目。

用户向 Agent A 提出需求:

帮我分析这个项目的架构。

Agent A 不需要知道 Agent B 内部使用什么模型、什么框架,也不需要知道它内部有哪些工具。

它只需要通过 A2A:

  1. 找到 Agent B。
  2. 查看 Agent B 能做什么。
  3. 向 Agent B 发送任务。
  4. 获取 Agent B 的执行进度。
  5. 接收 Agent B 的最终结果。

整个过程:

用户
│
▼
Agent A
│
│ 1. 发现 Agent B
│ 2. 查看 Agent Card
│ 3. 提交任务
│ 4. 获取任务进度
│ 5. 接收任务结果
▼
Agent B
│
▼
执行任务
│
▼
返回结果

核心思想:A2A 只规定 Agent 之间如何协作通信,不规定 Agent 内部如何执行任务。

2. Agent 如何发现另一个 Agent?#

A2A 使用 Agent Card 描述一个 Agent。

可以把它理解为 Agent 对外公开的能力说明书。

2.1 Agent Card 是什么?#

Agent Card 是一个 JSON 文档,通常包含:

字段作用
nameAgent 名称
descriptionAgent 的介绍
supportedInterfaces支持的通信接口、协议和版本
capabilities支持的协议能力
skillsAgent 能提供的具体技能
securitySchemes支持的认证方式
defaultInputModes默认支持的输入类型
defaultOutputModes默认支持的输出类型
versionAgent 自身的软件版本

例如:

{
"name": "Code Analysis Agent",
"description": "负责代码分析和项目架构分析",
"version": "1.0.0",
"supportedInterfaces": [
{
"url": "https://agent.example.com/rpc",
"protocolBinding": "JSONRPC",
"protocolVersion": "1.0"
}
],
"capabilities": {
"streaming": true,
"pushNotifications": true
},
"defaultInputModes": [
"text/plain"
],
"defaultOutputModes": [
"text/plain",
"application/json"
],
"skills": [
{
"id": "code-analysis",
"name": "代码分析",
"description": "分析代码结构、依赖关系和项目架构",
"tags": ["代码", "架构分析"],
"examples": [
"分析这个项目的整体架构",
"分析项目中的模块依赖"
]
}
]
}

这里重点关注三个部分:

supportedInterfaces:如何连接?

告诉调用方 Agent B 的通信地址、使用什么协议绑定,以及支持哪个 A2A 协议版本。

capabilities:支持哪些协议功能?

例如:

  • streaming:是否支持流式通信。
  • pushNotifications:是否支持任务推送通知。
  • extendedAgentCard:是否支持经过认证后获取扩展 Agent Card。

skills:具体能做什么?

例如代码分析、文件处理、数据分析等。

NOTE

Skills 是能力描述,不代表 Agent 一定能成功完成每个任务。

2.2 去哪里获取 Agent Card?#

A2A 提供了标准发现地址:

GET /.well-known/agent-card.json

例如:

Terminal window
curl https://agent.example.com/.well-known/agent-card.json

除了 Well-Known URI,还可以通过:

  • Agent 注册中心(Registry)。
  • 服务目录(Catalog)。
  • 预先配置的 Agent Card 地址。

获取 Agent Card 后,客户端就可以根据 Skills、协议版本、通信地址和认证要求决定是否调用这个 Agent。

3. A2A 的核心数据结构#

理解 A2A,最重要的是掌握下面几个对象。

3.1 Message:消息#

Message 表示 Agent 之间的一次消息交互。

主要字段:

字段作用
messageId消息唯一标识
role消息发送角色
parts消息内容
contextId所属对话上下文
taskId关联的任务 ID

例如:

{
"messageId": "msg-001",
"role": "ROLE_USER",
"parts": [
{
"text": "帮我分析这个项目的架构"
}
]
}

role 通常表示:

  • ROLE_USER:用户侧发出的消息。
  • ROLE_AGENT:Agent 发出的消息。

3.2 Part:消息内容片段#

Part 是 Message 或 Artifact 内部最小的内容单元。

它可以承载:

  • 文本。
  • 文件。
  • 图片。
  • 结构化数据。

例如文本:

{
"text": "分析项目架构"
}

例如文件内容引用:

{
"file": {
"name": "project.zip",
"uri": "https://example.com/project.zip"
}
}

Part 不只是文本,因此 A2A 可以支持不同模态的数据交换。

实际传输文件时,也可以根据规范使用内嵌字节数据,而不是必须提供 URL。

3.3 Task:任务#

Task 是 A2A 中非常重要的对象。

Message 表示一次消息交互,而 Task 表示一个需要被跟踪的工作过程。

例如:

Agent A:帮我分析这个项目。
Agent B:收到,开始分析。
Agent B:正在分析依赖关系。
Agent B:分析完成。

这整个过程可以对应一个 Task。

Task 主要包含:

字段作用
id任务唯一标识
contextId所属上下文
status当前任务状态
history任务相关消息历史
artifacts任务产生的结果
metadata附加元数据

3.4 Artifact:任务产物#

Artifact 表示 Agent 执行任务后产生的结果。

例如:

  • 一份 Markdown 分析报告。
  • 一张图片。
  • 一个生成的文件。
  • 一段结构化 JSON 数据。

示例:

{
"artifactId": "artifact-001",
"name": "架构分析报告",
"parts": [
{
"text": "# 项目架构分析\n\n项目采用前后端分离架构..."
}
]
}

这里要区分:

  • Message:通信消息。
  • Task:正在执行或已经执行的任务。
  • Artifact:任务产生的结果。

3.5 Context:上下文#

contextId 用于把相关的消息和任务关联起来。

例如:

context-001
│
├── Task 001:分析项目架构
│
├── Task 002:分析项目依赖
│
└── Task 003:根据分析结果生成报告

它主要用于多轮交互中的上下文关联。

NOTE

contextId 本身不是记忆系统,也不会自动把一个 Agent 的内部对话历史、模型上下文或私有数据共享给另一个 Agent。

4. 如何向另一个 Agent 提交任务?#

理解完数据结构,就可以看实际调用。

假设 Agent A 想让 Agent B 分析项目架构。

4.1 第一步:找到通信地址#

Agent A 从 Agent B 的 Agent Card 中获取:

{
"url": "https://agent.example.com/rpc",
"protocolBinding": "JSONRPC",
"protocolVersion": "1.0"
}

假设双方选择 JSON-RPC 2.0 绑定。

4.2 第二步:发送消息#

在 A2A 1.0 中,JSON-RPC 方法使用 PascalCase 命名,例如 SendMessage。

请求:

POST /rpc HTTP/1.1
Host: agent.example.com
Content-Type: application/json
A2A-Version: 1.0

请求体:

{
"jsonrpc": "2.0",
"id": 1,
"method": "SendMessage",
"params": {
"message": {
"messageId": "msg-001",
"role": "ROLE_USER",
"parts": [
{
"text": "帮我分析这个项目的架构"
}
]
}
}
}

这里:

内容作用
HTTP POST通过 HTTP 发送请求
jsonrpc指定 JSON-RPC 2.0
method指定调用 SendMessage
params传递 A2A 消息和配置
idJSON-RPC 请求标识
A2A-Version指定 A2A 协议版本

4.3 第三步:Agent B 返回响应#

Agent B 可能返回两种结果:

情况一:直接返回 Message

适合不需要持续跟踪的简单交互。

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"message": {
"messageId": "msg-002",
"role": "ROLE_AGENT",
"parts": [
{
"text": "你好,我可以帮你分析项目架构。"
}
]
}
}
}

情况二:返回 Task

适合需要后台执行和跟踪进度的任务。

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"task": {
"id": "task-001",
"contextId": "context-001",
"status": {
"state": "TASK_STATE_WORKING"
}
}
}
}

Agent A 拿到 task-001 后,就可以继续跟踪任务。

5. Task 的生命周期#

Task 不只是一个任务 ID,它有自己的状态变化过程。

5.1 常见状态#

状态含义
TASK_STATE_SUBMITTED任务已接收
TASK_STATE_WORKING正在执行
TASK_STATE_INPUT_REQUIRED需要调用方补充输入
TASK_STATE_AUTH_REQUIRED需要完成认证
TASK_STATE_COMPLETED任务成功完成
TASK_STATE_FAILED任务执行失败
TASK_STATE_CANCELED任务被取消
TASK_STATE_REJECTED任务被拒绝

其中:

  • INPUT_REQUIRED:Agent 缺少必要信息,需要调用方补充。
  • AUTH_REQUIRED:Agent 需要调用方完成认证或授权。
  • COMPLETED、FAILED、CANCELED、REJECTED:终止状态。

5.2 状态流转示意#

SUBMITTED
│
▼
WORKING
│
┌────────┼─────────┐
│ │ │
▼ ▼ ▼
COMPLETED FAILED INPUT_REQUIRED
│
▼
WORKING
其他可能状态:
AUTH_REQUIRED
CANCELED
REJECTED
NOTE

这只是帮助理解的简化示意,不代表每种状态之间都允许任意转换。

5.3 如何处理人工介入?#

假设 Agent B 在分析项目时发现:

项目中存在多个配置文件,不确定应该分析哪个。

它可以把任务状态设置为:

{
"state": "TASK_STATE_INPUT_REQUIRED",
"message": {
"role": "ROLE_AGENT",
"parts": [
{
"text": "请问需要分析 dev.yaml 还是 prod.yaml?"
}
]
}
}

Agent A 收到后,可以向用户询问。

用户回答后,Agent A 再通过 SendMessage 继续向 Agent B 提交消息,并关联原来的任务或上下文。

所以 A2A 提供了任务中断、等待输入和继续交互的协议基础。

但具体如何展示审批页面、如何验证用户权限,仍然由应用自身实现。

6. 如何获取任务进度?#

A2A 提供三种主要方式:

  1. Polling:轮询。
  2. Streaming:流式通信。
  3. Push Notification:推送通知。

6.1 Polling:轮询#

最简单的方式。

Agent A 提交任务后,拿到:

task-001

然后定期查询任务。

A2A 1.0 的 JSON-RPC 方法:

GetTask

请求:

{
"jsonrpc": "2.0",
"id": 2,
"method": "GetTask",
"params": {
"id": "task-001",
"historyLength": 10
}
}

返回:

{
"jsonrpc": "2.0",
"id": 2,
"result": {
"id": "task-001",
"status": {
"state": "TASK_STATE_WORKING"
}
}
}

Agent A 可以隔一段时间再次调用 GetTask。

直到返回:

{
"state": "TASK_STATE_COMPLETED"
}

优点:

  • 实现简单。
  • 不需要维持长连接。
  • 适合低频任务状态查询。

缺点:

  • 可能产生大量重复请求。
  • 无法第一时间知道任务完成。

6.2 Streaming:流式通信#

如果希望实时接收任务进度,可以使用流式通信。

A2A 1.0 的 JSON-RPC 方法:

SendStreamingMessage

它相当于:

发送任务消息 + 建立流式事件连接。

客户端发送请求后,服务端通过 SSE 持续推送事件。

HTTP 响应:

HTTP/1.1 200 OK
Content-Type: text/event-stream

SSE 数据示意:

data: {"jsonrpc":"2.0","id":1,"result":{"taskStatusUpdate":{"status":{"state":"TASK_STATE_WORKING"}}}}
data: {"jsonrpc":"2.0","id":1,"result":{"taskArtifactUpdate":{"artifact":{"parts":[{"text":"正在分析项目依赖"}]}}}}
data: {"jsonrpc":"2.0","id":1,"result":{"taskStatusUpdate":{"status":{"state":"TASK_STATE_COMPLETED"}}}}

这里需要理解:

  • SSE 是一种服务器向客户端持续推送事件的机制。
  • Agent B 可以在任务执行过程中多次推送事件。
  • Agent A 不需要一直重复调用 GetTask。

如果任务已经创建,也可以使用:

SubscribeToTask

订阅已有任务的更新。

适合:

  • 实时任务进度展示。
  • Agent 聊天界面。
  • 多 Agent 协作过程的实时监控。

前提是 Agent Card 声明支持:

{
"capabilities": {
"streaming": true
}
}

6.3 Push Notification:Webhook 推送#

如果任务可能执行几分钟、几小时,甚至更久,客户端不一定适合一直维持 SSE 连接。

这时可以使用 Push Notification。

它的工作方式是:

Agent A Agent B
│ │
│ 1. 提交任务 │
├──────────────────────────────►│
│ │
│ 2. 提供 Webhook 地址 │
│ │
│ │
│ 执行任务
│ │
│ 3. 任务状态发生变化 │
│◄──────────────────────────────┤
│ HTTP POST │
│ │
▼ │
接收通知 │
│ │
▼ │
查询最终任务结果 │

例如,Agent A 提供:

https://agent-a.example.com/webhook/a2a

Agent B 在任务发生状态变化时,向这个地址发送 HTTP POST。

A2A 1.0 的 JSON-RPC 配置方法包括:

CreateTaskPushNotificationConfig
GetTaskPushNotificationConfig
ListTaskPushNotificationConfigs
DeleteTaskPushNotificationConfig

配置示意:

{
"taskId": "task-001",
"pushNotificationConfig": {
"url": "https://agent-a.example.com/webhook/a2a",
"token": "your-webhook-token"
}
}

实际使用时,具体字段结构应按照所使用版本的 TaskPushNotificationConfig 定义填写。

Agent A 需要实现一个 HTTP 接收接口:

POST /webhook/a2a

收到通知后:

  1. 验证通知来源和身份。
  2. 读取任务 ID 和事件内容。
  3. 更新本地任务状态。
  4. 必要时调用 GetTask 获取完整任务信息。
  5. 对重复通知进行幂等处理。
NOTE

Webhook 是 Agent B 主动向 Agent A 发起 HTTP 请求,不是 Agent A 不断去查询 Agent B。

6.4 三种方式对比#

方式通信方式适用场景
Polling客户端定期查询简单任务、低频查询
StreamingSSE 持续推送实时进度、交互界面
Push NotificationWebhook 主动通知长时间任务、异步服务

7. A2A 还有哪些常用操作?#

除了提交消息和获取任务,还有一些常用操作。

JSON-RPC 1.0 方法名用途
SendMessage发送消息、创建或继续任务
SendStreamingMessage发送消息并接收流式事件
GetTask查询任务
ListTasks查询任务列表
CancelTask取消任务
SubscribeToTask订阅已有任务的事件
CreateTaskPushNotificationConfig创建推送配置
GetTaskPushNotificationConfig查询推送配置
ListTaskPushNotificationConfigs查询推送配置列表
DeleteTaskPushNotificationConfig删除推送配置
GetExtendedAgentCard获取认证后的扩展 Agent Card

注意:上表列出的是 A2A 1.0 JSON-RPC 绑定的方法名。

如果你看到旧文章使用:

message/send
message/stream
tasks/get
tasks/cancel
tasks/resubscribe

这些是 A2A 0.3 及更早版本中常见的命名。

A2A 1.0 对 JSON-RPC 方法名进行了调整,例如:

message/send
↓
SendMessage
message/stream
↓
SendStreamingMessage
tasks/get
↓
GetTask
tasks/cancel
↓
CancelTask
WARNING

看 A2A 资料时一定要注意版本,不能把 0.3 和 1.0 的调用方式混在一起。

8. A2A 使用什么通信协议?#

A2A 定义了统一的交互模型,同时支持不同的协议绑定。

常见的有:

8.1 JSON-RPC 2.0#

通过 HTTP(S) 发送 JSON-RPC 请求。

例如:

POST /rpc
Content-Type: application/json

请求体中使用:

{
"jsonrpc": "2.0",
"id": 1,
"method": "SendMessage",
"params": {}
}

优点:

  • JSON 格式,容易调试。
  • 对语言和框架要求较低。
  • 适合常见 Agent 服务之间的通信。

8.2 gRPC#

使用 Protocol Buffers 定义服务和数据结构,通过 gRPC 调用远程 Agent。

例如:

rpc SendMessage(SendMessageRequest)
returns (SendMessageResponse);

适合已有 gRPC 基础设施、需要强类型接口的服务。

8.3 HTTP+JSON / REST#

通过 HTTP 方法和资源路径调用。

例如:

POST /message:send

查询任务:

GET /tasks/task-001

取消任务:

POST /tasks/task-001:cancel

8.4 对比#

绑定方式通信形式特点
JSON-RPCJSON-RPC 2.0 over HTTP(S)通过 method 调用
gRPCProtobuf + gRPC强类型、适合服务间通信
HTTP+JSONHTTP API使用 URL 和 HTTP 方法

它们只是不同的通信方式,背后遵循的 A2A 核心交互模型是一致的。

9. A2A 的安全机制#

Agent 之间的通信不代表可以直接互相信任。

A2A 需要考虑:

  • 身份认证。
  • 权限控制。
  • 通信加密。
  • Agent Card 的可信性。
  • Webhook 的身份验证。

Agent Card 可以声明支持的安全方案,例如:

{
"securitySchemes": {
"bearerAuth": {
"type": "http",
"scheme": "bearer"
}
},
"securityRequirements": [
{
"bearerAuth": []
}
]
}

客户端根据 Agent Card 声明的认证方式获取凭证,再调用对应接口。

实际请求可能携带:

Authorization: Bearer YOUR_ACCESS_TOKEN
NOTE

需要注意:

  1. Agent Card 不应该直接保存或公开访问密钥。
  2. HTTPS 用于保护传输过程。
  3. Agent B 应验证 Agent A 是否有权调用相应能力。
  4. Webhook 应验证请求来源,防止伪造通知。
  5. Agent 之间不应该因为使用了 A2A 就默认互相信任。

10. A2A 与 MCP、ACP 有什么区别?#

这三个协议都与 Agent 生态有关,但解决的问题不同。

对比A2AMCPACP
主要定位Agent 与 Agent 通信Agent 与工具、数据源交互Agent 与代码编辑器/开发工具协作
通信对象远程 AgentMCP Server 提供的能力Agent 与支持 ACP 的客户端
核心概念Agent Card、Message、Task、ArtifactTool、Resource、PromptSession、Message、Content、Permission
主要作用委派任务、协作、跟踪结果调用工具、读取资源统一 Agent 与开发环境之间的交互
典型场景一个 Agent 把任务交给另一个 AgentAgent 调用数据库、文件系统等IDE 连接不同的代码 Agent

10.1 MCP 举例#

Agent 想读取数据库:

Agent
│
▼
MCP Client
│
▼
MCP Server
│
▼
Database

MCP Server 向 Agent 提供工具:

query_database(sql)

Agent 调用工具获取数据。

10.2 A2A 举例#

Agent A 想让 Agent B 分析项目:

Agent A
│
▼
A2A Client
│
▼
A2A Server
│
▼
Agent B

Agent A 提交任务,Agent B 执行并返回结果。

10.3 ACP 举例#

IDE 想连接不同的代码 Agent:

IDE
│
▼
ACP Client
│
▼
ACP Server
│
▼
Coding Agent

IDE 可以通过 ACP 统一与支持 ACP 的 Agent 进行会话交互。

10.4 三者可以一起使用吗?#

可以。

例如一个代码开发系统:

用户
│
▼
Agent A
/ \
/ \
A2A MCP
/ \
▼ ▼
Agent B MCP Server
代码分析 文件系统
│ │
▼ ▼
分析项目 读取文件
IDE 还可以通过 ACP 与代码 Agent 建立会话。

这里:

  • A2A:负责 Agent 之间委派任务。
  • MCP:负责 Agent 使用外部工具和数据。
  • ACP:负责 IDE 与代码 Agent 之间的会话交互。

11. 最后总结:完整调用流程#

把前面所有内容串起来,A2A 的一次典型任务交互就是:

1. 发现 Agent
GET /.well-known/agent-card.json
│
▼
2. 读取 Agent Card
查看 Skills、Capabilities、接口地址、认证方式
│
▼
3. 建立通信
根据 supportedInterfaces 选择协议绑定
│
▼
4. 提交任务
SendMessage
│
▼
5. 获取 Task
taskId + contextId
│
▼
6. 跟踪任务
├── GetTask(轮询)
├── SendStreamingMessage / SubscribeToTask(流式)
└── Push Notification(Webhook)
│
▼
7. 处理任务状态
WORKING / INPUT_REQUIRED / AUTH_REQUIRED ...
│
▼
8. 获取最终结果
Task.artifacts
│
▼
9. 交付结果
Agent A 返回给用户

关键概念记忆#

概念记忆方式
Agent CardAgent 的说明书
SkillsAgent 能做什么
CapabilitiesAgent 支持哪些协议功能
MessageAgent 之间发送的消息
Part消息或产物中的内容片段
Task一项可跟踪的任务
Artifact任务最终产生的结果
Context关联多轮交互的上下文
Polling主动定期查询
Streaming保持连接接收实时事件
Webhook对方主动向我发送通知

一句话理解 A2A:

A2A 让不同框架、不同厂商、不同运行环境中的 Agent,可以通过统一的协议发现彼此、交换消息、委派任务、跟踪执行过程,并交付任务结果。

参考资料#

A2A(Agent2Agent Protocol)使用笔记
https://blog.xqcherry.top/posts/ai/a2a-protocol/
作者
xqcherry
发布于
2026-11-05
许可协议
CC BY-NC-SA 4.0