【从零理解 A2A:当一个 Agent 需要另一个 Agent 帮忙

从零理解 A2A:当一个 Agent 需要另一个 Agent 帮忙

MCP 解决了 Agent 和工具之间的问题。但 Agent 和 Agent 之间呢?


目录


一个 Agent 搞不定的事

假设你在做一个电商系统,搭了两个 AI Agent:

  • 库存 Agent:监控库存水平,发现哪些商品快卖完了
  • 采购 Agent:负责联系供应商,下单补货

库存 Agent 发现某商品只剩 10 件,需要补货。但它不能自己下单------那是采购 Agent 的职责。问题来了:库存 Agent 怎么告诉采购 Agent「帮我订 500 件商品 X」?

你可能会说:这不就是一个函数调用的事吗?

没那么简单。

上一篇我们讲了 MCP(Model Context Protocol),解决了 Agent 和工具之间的问题------让 AI 能查数据库、调 API、读文件。但 MCP 的视角是「Agent ↔ 工具」,是一个 Agent 使用外部资源。

A2A 要解决的是另一个问题:Agent ↔ Agent,两个独立的 AI 智能体之间怎么沟通、协作、分配任务。

一句话区分:MCP 是给 Agent 配工具,A2A 是让 Agent 之间能开会协作。


为什么不能直接调用?

我最初的想法是:两个 Agent 都是程序,为什么不能直接函数调用?

java 复制代码
// 库存 Agent 直接调用采购 Agent 的方法
purchaseAgent.createOrder("商品X", 500);

如果两个 Agent 在同一个项目里、同一个进程里,确实可以这么做。但现实世界往往是这样的:

  • 库存 Agent 是 Python 写的,采购 Agent 是 Java 写的
  • 库存 Agent 部署在北京的服务器,采购 Agent 部署在上海
  • 库存 Agent 是你公司的,采购 Agent 是合作伙伴提供的
  • 甚至你都不知道采购 Agent 内部是怎么实现的,你只知道它能下单

直接函数调用的前提是:同语言、同进程、同部署环境。现实世界几乎不满足这些条件。

那怎么办?

你需要一个跨语言、跨网络、跨组织的通用协议。就像人与人之间用中文或英文沟通一样,Agent 之间也需要一种「通用语言」。

这就是 A2A(Agent-to-Agent)协议要解决的核心问题:互操作性。不管你是 Python 还是 Java,不管你部署在哪里,只要大家都说 A2A 这种「语言」,就能互相沟通。


A2A 是什么

A2A(Agent-to-Agent)协议是一个由 Google 发起、现由 Linux 基金会托管的开放标准。它的目标很明确:让不同 AI Agent 能相互发现、通信、协作,共同完成复杂任务。

你可以把它理解为 AI 智能体世界的「互联网协议」。就像 HTTP 让不同的网站能互相链接一样,A2A 让不同的 Agent 能互相合作。

五个设计原则

A2A 的设计遵循五个核心理念,用大白话说:

  1. 互操作性:不管你是哪个厂商的 Agent,用什么语言写的,都能聊。就像不管你是中国移动还是中国联通,打电话都能接通。

  2. 协作性:复杂任务可以拆分给别人。你做你擅长的,我做我擅长的,合在一起就行。

  3. 可发现性:Agent 能动态发现「谁能帮我」。不需要提前硬编码所有合作伙伴的地址。

  4. 异步优先:任务可能要跑几小时甚至几天,不能干等着。A2A 原生支持长时间任务和实时状态更新。

  5. 安全黑盒:你不需要知道我内部怎么实现的,我也不需要暴露我的专有数据和工具。大家只通过标准化接口沟通。

一个类比

把 A2A 想象成商务会议的礼仪:

  • 交换名片:Agent Card(智能体名片)------告诉你我是谁、我能干什么
  • 分配任务:Task(任务)------我请你帮忙做一件事
  • 汇报进度:Message(消息)------实时告诉你任务进展
  • 交付成果:Artifact(工件)------任务完成后的最终结果

不管你是哪个公司的人,只要大家都遵守这套礼仪,会议就能顺利进行。


Agent 怎么发现其他 Agent?

好,A2A 让 Agent 之间能沟通。但第一个问题是:库存 Agent 怎么知道采购 Agent 的存在?怎么知道它能干什么?

答案是:Agent Card(智能体名片)

Agent Card 是什么

每个 A2A 兼容的 Agent 都会发布一份 JSON 文档,相当于它的「自我介绍」。里面包含:

  • 我叫什么(name)
  • 我是干什么的(description)
  • 我有什么技能(skills)
  • 怎么联系我(endpoint)
  • 我支持什么样的交互方式(文本、文件等)
json 复制代码
{
  "name": "采购Agent",
  "description": "负责商品采购和供应商管理",
  "skills": [
    {
      "name": "create_order",
      "description": "向供应商下单采购"
    },
    {
      "name": "query_supplier",
      "description": "查询供应商信息和报价"
    }
  ],
  "endpoint": "https://purchase-agent.example.com/a2a"
}

三种发现方式

Agent 怎么拿到其他 Agent 的名片?有三种方式:

1. 知名 URI(推荐)

这是最标准的方式。每个 Agent 把自己的名片放在一个固定的路径上:

复制代码
https://{agent域名}/.well-known/agent-card.json

就像公司官网的 /robots.txt 一样,约定俗成。库存 Agent 只要知道采购 Agent 的域名,发一个 HTTP GET 请求就能拿到名片。

2. 集中式注册中心

类似企业内部的「黄页」。Agent 们把自己的名片注册到一个中央目录里。其他 Agent 可以去这个目录搜索,按技能、标签等条件筛选。

适合企业内部或特定生态系统的 Agent 管理。

3. 直接配置

开发阶段最简单的方式:硬编码目标 Agent 的地址。跳过发现过程,直接通信。

发现流程

复制代码
库存 Agent
    |
    | 1. GET https://purchase-agent.example.com/.well-known/agent-card.json
    |
    v
采购 Agent 返回 Agent Card
    |
    | 2. 库存 Agent 解析名片,确认采购 Agent 有 create_order 技能
    |
    | 3. 开始通信
    v

这个设计的巧妙之处在于:库存 Agent 不需要提前知道采购 Agent 的具体实现,只需要知道它的域名,剩下的靠名片来了解。


发现之后,怎么通信?

拿到名片了,知道对方能干什么了。然后呢?怎么发消息?发什么格式?

基础协议

A2A 的所有通信都基于:

  • HTTP(S):传输层
  • JSON-RPC 2.0:消息格式。所有请求和响应都是 JSON-RPC 格式

选择 JSON-RPC 而不是 REST API,是因为 JSON-RPC 天然支持「方法调用」的语义------你可以告诉对方「请执行这个方法」,而不只是「操作这个资源」。

三个核心概念

Task(任务)

任务是 A2A 通信的核心单元。库存 Agent 给采购 Agent 发的不是一个「消息」,而是一个「任务」。任务有生命周期:

复制代码
submitted → working → completed
              |
              +→ input-required → (等待客户端补充信息) → working
              |
              +→ failed
              |
              +→ canceled
  • submitted:任务刚提交
  • working:采购 Agent 正在处理
  • input-required:需要库存 Agent 补充信息(比如「你要采购的具体数量是多少?」)
  • completed:任务完成
  • failed:任务失败
  • canceled:任务被取消

Message(消息)

客户端和服务端之间的通信单元。一条消息可以包含多个 Part:

  • TextPart:文本内容
  • FilePart:文件(可以是内联数据或 URL)

比如库存 Agent 发的消息可能包含一段文字说明 + 一份库存报告文件。

Artifact(工件)

任务完成后生成的最终结果。比如采购 Agent 完成下单后,返回一个订单确认信息。工件是不可变的------一旦生成就不会改变。

两种通信模式

同步请求-响应

适合简单、快速的任务。库存 Agent 发送请求,等待采购 Agent 返回结果。

复制代码
库存 Agent ---{tasks/send}---> 采购 Agent
库存 Agent <---{任务结果}--- 采购 Agent

异步流式传输(SSE)

这是 A2A 的核心能力之一,专为耗时较长的任务设计。基于 SSE(Server-Sent Events)实现。

复制代码
库存 Agent ---{tasks/send + 订阅}---> 采购 Agent
库存 Agent <---{状态更新: 正在联系供应商}--- 采购 Agent
库存 Agent <---{状态更新: 已下单,等待确认}--- 采购 Agent
库存 Agent <---{状态更新: 订单确认完成}--- 采购 Agent
库存 Agent <---{final: true, 工件: 订单详情}--- 采购 Agent (连接关闭)

整个过程中,采购 Agent 持续推送状态更新,库存 Agent 能实时知道任务进展。当任务完成(或失败)时,服务器发送一个带有 final: true 标志的事件,然后关闭连接。

如果连接意外中断怎么办?客户端可以重新订阅,恢复对正在运行任务的监听。


出问题了怎么办?

跨 Agent 通信,中间环节很多,出问题是常态。A2A 协议设计了完善的错误处理机制。

标准错误类型

A2A 定义了一套标准错误,都继承自 A2AError

错误类型 什么时候出现
AgentCardResolutionError 获取或解析 Agent Card 失败
TaskNotFoundError 操作一个不存在的任务
InvalidRequestError 请求格式不对或参数无效
InternalError Agent 服务器内部出错

这些错误会映射到标准的 HTTP 状态码,方便客户端统一处理。

重试与熔断

SDK 通常内置了重试和熔断逻辑:

  • 智能重试:遇到临时错误(比如网络超时)自动重试,遇到认证错误触发重新认证
  • 熔断:如果某个 Agent 连续失败多次,暂时停止向它发请求,避免雪崩

任务状态监控

通过异步模式下的状态更新事件,客户端可以实时监控任务状态。如果任务进入 failed 状态,客户端可以:

  1. 查看失败原因
  2. 决定是否重试
  3. 通知用户或启动备选方案

一句话:A2A 的错误处理不是「出了问题就报错」,而是「出了问题知道怎么应对」。


A2A 和 MCP 是什么关系?

上一篇讲了 MCP,这篇讲 A2A。很多人会问:这俩是竞争关系吗?

不是。它们解决的是不同层面的问题,而且可以组合使用。

对比

维度 A2A MCP
核心目的 Agent 之间通信 Agent 调用工具和数据
交互对象 智能体 ↔ 智能体 智能体 ↔ 工具/数据
类比 不同部门的同事开会 给同事配电脑和数据库
协议基础 HTTP + JSON-RPC HTTP + JSON-RPC
状态管理 有状态(Task 生命周期) 无状态(单次调用)
发起方 另一个 Agent Agent 自己

一句话:MCP 让 Agent 能用工具,A2A 让 Agent 能找帮手。

一个完整的例子

回到开头的库存 + 采购场景,看看 MCP 和 A2A 怎么配合:

复制代码
库存 Agent
    |
    | 1. 通过 MCP 查询数据库(工具调用)
    |    -> 发现商品 X 库存只剩 10 件
    |
    | 2. 通过 A2A 发送任务给采购 Agent(Agent 间通信)
    |    -> 请为商品 X 下单补货 500 件
    |
    v
采购 Agent
    |
    | 3. 通过 MCP 查询供应商 API(工具调用)
    |    -> 获取供应商报价和交货时间
    |
    | 4. 通过 MCP 创建采购订单(工具调用)
    |    -> 订单创建成功
    |
    | 5. 通过 A2A 返回结果给库存 Agent(Agent 间通信)
    |    -> 订单已创建,预计 3 天到货
    |
    v
库存 Agent 收到结果,更新库存预期

整个流程中,MCP 负责「Agent 和工具之间的交互」,A2A 负责「Agent 和 Agent 之间的协作」。两者各司其职,缺一不可。


应用场景

理解了 A2A 的机制,什么时候该用它?

适合用 A2A 的场景

多 Agent 协作

最典型的场景。比如:

  • 库存 Agent + 采购 Agent:自动补货
  • 客服 Agent + 工单 Agent + 知识库 Agent:客户问题自动流转
  • 面试 Agent + 评分 Agent + 追问 Agent:AI 面试系统

跨组织协作

你的 Agent 需要和合作伙伴的 Agent 配合。比如你的库存 Agent 需要调用供应商的采购 Agent,双方用 A2A 协议通信,不需要暴露各自的内部实现。

复杂任务分解

一个大任务可以拆成多个小任务,分发给不同的专业 Agent。比如「帮我做一份市场分析报告」可以拆成:数据采集 Agent、数据分析 Agent、报告生成 Agent。

不适合用 A2A 的场景

  • 单 Agent 任务:一个 Agent 就能搞定的事,不需要 A2A
  • Agent 调工具:用 MCP 就够了,不需要 A2A 的复杂性
  • 同进程内的简单调用:直接函数调用更简单,没必要走网络协议

一句话:当你需要「一个 Agent 请另一个 Agent 帮忙」时,就该用 A2A。


总结

回顾一下我们走过的路:

  1. 起点:一个 Agent 搞不定的事------库存 Agent 能发现缺货但不能下单
  2. 问题:为什么不能直接函数调用?------不同语言、不同部署、不同组织
  3. 解法:A2A 协议------一个跨 Agent 的通用通信标准
  4. 发现:Agent Card(智能体名片)------告诉你我是谁、我能干什么
  5. 通信:HTTP + JSON-RPC + SSE------同步和异步两种模式
  6. 容错:标准错误类型 + 重试熔断------出了问题知道怎么应对
  7. 定位:A2A 和 MCP 互补------MCP 管工具,A2A 管 Agent 间通信

A2A 的核心价值:让 AI Agent 从「单兵作战」变成「团队协作」。

它不是一个 Agent 框架,而是一个通信协议。你不需要用特定的语言或框架来实现 Agent,只需要遵守 A2A 协议,你的 Agent 就能和其他任何 A2A 兼容的 Agent 合作。

目前 A2A 已经发布了 1.0 正式版本,有超过 50 家技术伙伴支持,包括 Google、Atlassian、Salesforce、SAP、LangChain 等。官方资料在 a2a-protocol.org

下一篇可以聊聊:在一个实际项目中,怎么同时用 MCP 和 A2A 搭建一个多 Agent 协作系统。