A2A:让 Agent 从单兵作战走向团队协作

一、为什么会出现 A2A?

我们先从一个真实的业务场景说起。

假设我们现在做了一个智能运维 Agent 系统,里面有几个不同的 Agent:

  • 告警分析 Agent:负责分析 Prometheus 告警;
  • 日志检索 Agent:负责查询日志系统;
  • 知识库 Agent:负责从 RAG 知识库中检索历史方案;
  • 报告生成 Agent:负责把诊断过程整理成报告;
  • 调度 Agent:负责判断下一步该交给谁处理。

如果这些 Agent 都在同一个项目里,同一个 Spring Boot 服务中,那我们可以通过 Java 方法调用、Graph 节点、状态机、消息队列等方式组织它们。

但如果这些 Agent 不是一个系统里的呢?

比如:

  • 告警 Agent 是你自己用 Spring AI 写的;
  • 工单 Agent 是另一个团队用 Python LangGraph 写的;
  • 审批 Agent 是某个 SaaS 平台提供的;
  • CRM Agent 是第三方厂商提供的;
  • 数据分析 Agent 运行在另一个云平台上。

这时候问题来了:

它们怎么互相发现?

怎么知道对方能干什么?

怎么把任务交给对方?

怎么拿到执行结果?

怎么处理长任务?

怎么知道任务是成功、失败、等待中,还是需要补充信息?

这就是 A2A 想解决的问题。

A2A 的出现,本质上是因为 Agent 系统开始从"单体智能体"走向"网络化智能体"。

以前我们关心的是:

我的 Agent 能不能调工具?

现在开始变成:

我的 Agent 能不能和别人的 Agent 协作?

这背后的变化很关键。


二、A2A 到底是什么?

A2A,全称 Agent2Agent Protocol,可以理解为一种 Agent 之间通信和协作的开放协议。

它不是一个大模型。

它不是一个向量数据库。

它不是 RAG。

它也不是 Spring AI、LangChain、LangGraph 这种 Agent 开发框架。

它更像是一套"Agent 之间打交道的通用语言"。

举个生活化的例子。

你去公司找人办事,不能直接冲进每个办公室问:"你会干啥?能不能帮我干活?"

正常流程应该是:

  1. 先知道这个部门负责什么;
  2. 再知道找谁处理;
  3. 把需求说明白;
  4. 对方开始处理;
  5. 处理中可能让你补材料;
  6. 最后给你一个结果。

A2A 做的事情其实也类似。

它让一个 Agent 可以:

  • 发现另一个 Agent 的能力;
  • 读取对方的能力描述;
  • 给对方发送任务;
  • 跟踪任务状态;
  • 接收中间消息;
  • 获取最终产物;
  • 处理任务失败、取消、等待等情况。

也就是说,A2A 不是让模型变聪明,而是让 Agent 之间有了协作规范。

这点非常重要。

很多人一听到 A2A,就以为它是某种"更高级的多 Agent 框架"。其实不是。A2A 更偏通信协议和协作标准,它解决的是 Agent 系统之间的互操作问题。


三、A2A 和 MCP 的区别

这里一定要讲清楚,因为很多人最容易把 A2A 和 MCP 混在一起。

一句话区分:

MCP 解决 Agent 连接工具的问题,A2A 解决 Agent 连接 Agent 的问题。

我们可以这样理解:

对比项 MCP A2A
连接对象 工具、数据源、资源 另一个 Agent
核心问题 Agent 怎么使用外部能力 Agent 怎么和 Agent 协作
典型场景 查数据库、读文件、调 API、访问知识库 委托任务、跨系统协作、多 Agent 联动
对方身份 工具服务 智能体服务
交互特点 更像"调用函数" 更像"派发任务 + 等待结果"
关注重点 tool/resource/prompt capability/task/message/artifact

比如用户问:

帮我查一下最近 1 小时的系统错误日志,并分析是不是数据库连接池打满了。

如果是 MCP 思路,Agent 可能会调用:

  • 日志查询工具;
  • 数据库监控工具;
  • Prometheus 查询工具;
  • 知识库检索工具。

这些工具本身不会主动思考,它们只是被调用。

但如果是 A2A 思路,当前 Agent 可能会说:

这个问题需要交给"运维诊断 Agent"处理,它更擅长告警、日志、链路追踪分析。

于是它把任务发给另一个 Agent。

被调用的那个 Agent 不是简单工具,它可能自己也会规划步骤、调用工具、检索知识库、生成诊断结论。

这就是两者最大的区别。

MCP 里的工具通常是"能力"。

A2A 里的 Agent 是"带目标理解和执行过程的协作者"。

所以 MCP 和 A2A 并不冲突,它们反而是互补关系。

一个完整的 Agent 系统里可能是这样的:

复制代码
用户
 ↓
主 Agent / Supervisor Agent
 ↓
A2A 调用其他 Agent
 ↓
每个 Agent 内部再通过 MCP 调用工具
 ↓
工具访问数据库、日志、文档、API、知识库

也就是说:

A2A 管 Agent 之间的协作,MCP 管 Agent 和工具之间的连接。

这就是它们最清晰的边界。


四、A2A 为什么不是简单的 HTTP 调用?

有人可能会说:

Agent 调 Agent,不就是一个 HTTP 接口吗?我写个 RestTemplate 或 OpenFeign 不就行了吗?

这句话对一半,也错一半。

从底层通信看,A2A 确实可以基于 HTTP、JSON-RPC、SSE 这些 Web 技术来实现。

但 A2A 的价值不只是"能发请求"。

真正的问题是:

  • 你怎么描述一个 Agent 的能力?
  • 你怎么让别的 Agent 发现你?
  • 你怎么表示一个任务?
  • 你怎么跟踪任务状态?
  • 你怎么支持长时间任务?
  • 你怎么返回结构化结果?
  • 你怎么处理流式消息?
  • 你怎么表达任务失败原因?
  • 你怎么让不同语言、不同框架的 Agent 都能理解?

普通 HTTP 接口当然也能做,但每个团队都会自己定义一套格式。

比如 A 团队这样写:

复制代码
{
  "question": "分析日志",
  "type": "log_analysis"
}

B 团队这样写:

复制代码
{
  "taskName": "analyze_logs",
  "input": {
    "content": "xxx"
  }
}

C 团队可能又这样写:

复制代码
{
  "messages": [
    {
      "role": "user",
      "content": "帮我分析日志"
    }
  ]
}

如果没有统一协议,系统一多,就会变成接口地狱。

A2A 想做的就是把这些东西标准化。

它不是说你不能自己写 HTTP,而是说:

Agent 之间协作不能永远靠每个项目自己约定格式。

这就像微服务之间当然可以裸写 HTTP,但后来为什么会有 OpenAPI、gRPC、服务注册发现、网关、鉴权、Tracing?

因为系统复杂之后,光能调用是不够的,还需要规范。


五、A2A 中几个关键概念

为了避免讲得太抽象,我们可以把 A2A 拆成几个核心概念理解。

1. Agent Card:Agent 的能力名片

Agent Card 可以理解为一个 Agent 的"自我介绍"。

它告诉别人:

  • 我是谁;
  • 我能做什么;
  • 我支持什么输入;
  • 我支持什么输出;
  • 我有哪些能力;
  • 我访问地址是什么;
  • 我支持哪些交互方式。

这就像一个服务的 API 文档,但它不是单纯描述接口,而是描述一个 Agent 的能力。

比如一个日志分析 Agent 的 Agent Card 可以表达:

复制代码
{
  "name": "LogAnalysisAgent",
  "description": "负责查询和分析应用日志,定位错误堆栈和异常趋势",
  "skills": [
    {
      "name": "analyze_error_logs",
      "description": "分析指定时间范围内的错误日志"
    }
  ]
}

这样其他 Agent 就能知道:

哦,这个 Agent 适合处理日志分析类任务。

这比硬编码调用某个接口要灵活很多。


2. Task:把问题变成可跟踪的任务

A2A 不是简单地问一句、答一句。

很多 Agent 任务是长流程的。

比如:

分析昨天凌晨数据库连接池异常,并生成复盘报告。

这个任务可能要经历:

  1. 查询告警;
  2. 查询日志;
  3. 查询数据库监控指标;
  4. 检索历史故障知识库;
  5. 判断根因;
  6. 生成报告;
  7. 等待人工确认。

这不是一次普通方法调用能优雅表达的。

所以 A2A 中有 Task 的概念。

Task 可以有状态,例如:

  • submitted:已提交;
  • working:处理中;
  • input-required:需要补充信息;
  • completed:已完成;
  • failed:失败;
  • canceled:已取消。

这样一个 Agent 把任务交给另一个 Agent 后,不是傻等,而是可以持续跟踪任务状态。

这点对企业级 Agent 很关键。

因为真实业务里很多任务不是秒级完成,而是长时间、多步骤、可中断、可恢复的。


3. Message:Agent 之间的对话消息

Message 可以理解为 Agent 之间沟通的基本载体。

一个 Agent 可以给另一个 Agent 发送消息,对方也可以回复消息。

这和普通聊天消息类似,但它不是单纯给人看的聊天内容,而是 Agent 协作过程中的信息交换。

比如:

复制代码
主 Agent:请分析服务 A 在 10:00-11:00 的错误日志。
日志 Agent:需要指定环境,是 dev、test 还是 prod?
主 Agent:prod。
日志 Agent:已开始分析,发现 10:23 开始错误率升高。

你会发现,这更像两个同事之间协作,而不是一个函数调用。

这也是 A2A 和 Function Calling 的区别。

Function Calling 是模型决定调用哪个函数。

A2A 是 Agent 把一个任务交给另一个 Agent 处理。


4. Artifact:任务的最终产物

Artifact 可以理解为 Agent 执行任务后生成的结果产物。

它可以是:

  • 一段文本;
  • 一个 JSON 结果;
  • 一份报告;
  • 一个文件;
  • 一张图;
  • 一组结构化数据。

比如运维诊断 Agent 最终返回:

复制代码
{
  "rootCause": "数据库连接池耗尽",
  "evidence": [
    "10:23 开始 HikariPool active connections 达到上限",
    "应用日志出现大量 connection timeout",
    "同时间段慢 SQL 数量明显增加"
  ],
  "suggestion": "建议扩容连接池并排查慢 SQL"
}

这就是一个结构化 artifact。

在复杂 Agent 系统中,artifact 很重要,因为它让 Agent 的产出不只是自然语言,而是可以继续被其他系统消费。


六、把 A2A 放到我们熟悉的 Spring AI 项目里理解

我们现在从 Java / Spring AI 项目的角度来理解 A2A。

假设我们有一个主 Agent:

复制代码
SupervisorAgent

它负责接收用户问题,然后判断要不要交给其他 Agent。

现在系统里有三个 Agent:

复制代码
RagAgent:负责知识库问答
OpsAgent:负责运维诊断
ReportAgent:负责报告生成

如果它们都在同一个 Spring Boot 应用里,我们可以这样调用:

复制代码
String result = opsAgent.invoke(userQuestion);

这属于进程内方法调用。

如果它们是同一个服务里的不同 Bean,也可以通过 Spring 注入调用。

但是如果 OpsAgent 是另一个服务,甚至是另一个团队写的 Python 服务,那就不能直接 Java 方法调用了。

这时候就需要一个统一的远程协作协议。

A2A 的意义就在这里。

它可以让 SupervisorAgent 不关心对方到底是 Java 写的、Python 写的,还是某个 SaaS 平台提供的。

SupervisorAgent 只需要知道:

复制代码
这个 Agent 能不能处理我的任务?
怎么把任务发给它?
怎么拿到任务状态?
怎么拿到最终结果?

这就像微服务之间通过统一协议通信一样。

只不过过去微服务传递的是确定性业务请求,而现在 Agent 之间传递的是更复杂的任务意图。


七、A2A 和 Graph 编排有什么关系?

我们最近也一直在聊 Graph、DAG、多 Agent 编排。

那 A2A 和 Graph 是不是一个东西?

不是。

Graph 更偏"内部编排"。

A2A 更偏"外部通信"。

比如在一个 Agent 系统内部,我们可以用 Graph 来组织执行流程:

复制代码
用户问题
  ↓
Planner Node
  ↓
Executor Node
  ↓
Reflection Node
  ↓
Replan Node
  ↓
Final Answer Node

这个 Graph 是你系统内部的执行逻辑。

但 A2A 关注的是:

当这个系统需要调用另一个独立 Agent 系统时,双方怎么通信?

所以它们的关系可以这样理解:

复制代码
Graph:管理一个 Agent 系统内部怎么流转
A2A:管理不同 Agent 系统之间怎么协作

当然,它们也可以结合。

比如你的 Graph 中有一个节点叫:

复制代码
CallRemoteAgentNode

这个节点的作用就是通过 A2A 调用外部 Agent。

整体流程可能是:

复制代码
Start
 ↓
理解用户问题
 ↓
判断任务类型
 ↓
如果是本地能力 → 本地工具调用
 ↓
如果是外部能力 → 通过 A2A 委托远程 Agent
 ↓
接收远程 Agent artifact
 ↓
汇总最终答案

这样一来,Graph 负责流程控制,A2A 负责跨 Agent 通信。

这才是比较工程化的理解。


八、A2A 对 RAG 系统有什么价值?

很多人会觉得 A2A 和 RAG 没关系。

其实不是。

传统 RAG 系统通常是这样的:

复制代码
用户问题
 ↓
Query 改写
 ↓
向量检索 / BM25 检索
 ↓
Rerank
 ↓
拼接上下文
 ↓
LLM 生成答案

这是一个单系统内部的链路。

但在真实企业环境里,知识往往分散在多个系统:

  • 一个 Agent 管公司制度文档;
  • 一个 Agent 管项目文档;
  • 一个 Agent 管历史工单;
  • 一个 Agent 管数据库元数据;
  • 一个 Agent 管日志和监控;
  • 一个 Agent 管代码仓库。

如果用户问:

为什么订单服务昨天晚上出现大量超时?结合日志、监控和历史故障记录分析一下。

这时候一个 RAG 知识库可能不够。

你需要多个 Agent 协作:

复制代码
监控 Agent:分析指标异常
日志 Agent:分析错误日志
知识库 Agent:检索历史故障
代码 Agent:分析最近提交
报告 Agent:汇总结论

A2A 的价值就是让这些 Agent 可以互相协作,而不是全部塞进一个超级大的 Agent 里。

这也符合未来 Agent 系统的发展趋势:

不是把一个 Agent 做得无限大,而是让多个专业 Agent 通过协议协作。

这点非常像软件工程里的微服务思想。

以前我们不建议把所有业务写进一个单体应用。

以后我们也不会建议把所有智能能力塞进一个超级 Agent。


九、A2A 带来的工程挑战

A2A 听起来很美好,但真正落地时并不简单。

1. 能力描述可信度问题

一个 Agent 说自己能分析日志,它真的能分析好吗?

一个 Agent Card 写得很漂亮,但实际效果可能很差。

这就带来一个问题:

Agent 的能力声明不等于真实能力。

所以未来 Agent 协作系统里,可能还需要:

  • 能力评估;
  • 调用成功率统计;
  • 历史表现评分;
  • 结果质量反馈;
  • 黑名单 / 白名单机制。

否则主 Agent 很可能把任务交给一个"看起来很强,实际很水"的 Agent。

这和人类团队协作也一样。

一个人简历写得很强,不代表项目一定能交付。


2. 上下文传递问题

Agent 协作不是简单传一句话。

比如用户问:

结合我上周上传的那份系统架构文档,分析一下这次告警原因。

这里面包含大量上下文:

  • 用户是谁;
  • 文档是哪份;
  • 权限是否允许;
  • 历史对话说了什么;
  • 当前任务目标是什么;
  • 输出格式有什么要求。

如果 A2A 调用时只传一句"分析告警",远程 Agent 很可能答偏。

所以 A2A 解决通信标准,但不自动解决上下文工程。

真正落地时,仍然要设计:

  • 上下文裁剪;
  • 敏感信息过滤;
  • 用户权限传递;
  • 会话 ID;
  • traceId;
  • taskId;
  • 引用材料;
  • 输出约束。

这也是为什么 Agent 工程不是只学协议就够了。

协议解决"能不能通信",上下文工程解决"通信时带什么"。


3. 安全和权限问题

Agent 调 Agent 的时候,权限边界会更复杂。

比如 A Agent 有权限访问日志系统,B Agent 没有。

那 B Agent 通过 A2A 调用 A Agent 时,能不能间接获得日志数据?

再比如一个外部 Agent 请求内部 Agent 查询用户订单信息,它是否有权限?

所以企业里做 A2A,必须考虑:

  • 身份认证;
  • 权限校验;
  • 数据脱敏;
  • 审计日志;
  • 调用链路追踪;
  • 结果可解释性。

否则 Agent 之间一旦乱调,风险会非常大。

过去微服务里有接口权限问题。

未来多 Agent 系统里会有 Agent 权限问题。


4. 失败处理问题

普通工具调用失败,可能就是抛异常。

但 Agent 任务失败可能更复杂。

比如:

  • 远程 Agent 不可用;
  • 任务超时;
  • 对方需要补充信息;
  • 对方返回低置信度结果;
  • 对方执行到一半失败;
  • 多个 Agent 结果互相冲突。

所以主 Agent 不能只写:

复制代码
try {
    callRemoteAgent();
} catch (Exception e) {
    return "调用失败";
}

而是要有更完整的任务状态处理:

复制代码
如果远程 Agent 需要补充信息 → 回问用户
如果远程 Agent 超时 → 尝试降级方案
如果结果置信度低 → 调用另一个 Agent 交叉验证
如果多个结果冲突 → 进入 Reflection / Replan

这就和我们之前聊的 Plan-Execute-Replan 联系起来了。

A2A 提供协作通道,但真正的智能调度逻辑,仍然要由你的编排层完成。


十、一个简单的 Java 伪代码理解

虽然目前我们在 Spring AI 项目中不一定直接使用完整 A2A SDK,但可以先用伪代码理解它的调用方式。

假设我们有一个远程运维 Agent。

主 Agent 先读取它的能力信息:

复制代码
AgentCard card = a2aClient.getAgentCard("https://ops-agent.example.com");

if (card.hasSkill("incident_analysis")) {
    Task task = a2aClient.createTask(
            "https://ops-agent.example.com",
            new TaskRequest("""
                请分析订单服务在 10:00-11:00 的超时告警,
                结合日志、监控指标和历史故障知识库给出根因。
            """)
    );

    TaskResult result = a2aClient.waitForResult(task.getId());

    return result.getArtifact();
}

这段代码不重要,重要的是它背后的思想:

复制代码
先发现能力
再提交任务
再跟踪状态
最后获取产物

这就是 A2A 思维和普通接口调用的区别。

普通接口调用更像:

复制代码
我调用你这个函数

A2A 更像:

复制代码
我知道你是一个 Agent,我把一个任务委托给你,你处理完后把结果交给我

这个变化很微妙,但非常关键。


十一、A2A 对 Agent 工程师意味着什么?

如果以后我们要往 Agent 工程师方向发展,A2A 这个东西不能只停留在概念层面。

我们至少要能说清楚四件事。

第一,A2A 解决的是 Agent 互操作问题

它不是用来做 RAG 的,也不是用来直接调数据库的。

它解决的是:

不同 Agent 系统之间如何标准化协作。

第二,A2A 和 MCP 是互补关系

MCP 让 Agent 能够使用工具。

A2A 让 Agent 能够调用另一个 Agent。

完整链路应该是:

复制代码
Agent --A2A--> Agent --MCP--> Tool / Resource / Data

这句话一定要记住。

第三,A2A 不等于多 Agent 编排框架

Graph、DAG、Supervisor、Planner、Executor 这些是编排思想。

A2A 是通信协议。

编排层决定"该找谁"。

A2A 负责"怎么找、怎么发任务、怎么拿结果"。

第四,A2A 落地时最难的是上下文、安全和可信度

协议只是第一步。

真正企业落地还要考虑:

  • 权限;
  • 认证;
  • 审计;
  • trace;
  • 上下文传递;
  • 结果验证;
  • 失败降级;
  • 任务状态管理。

这些才是工程化难点。


十二、总结:A2A 是 Agent 时代的"协作协议"

前面我们学习 Function Calling 的时候,重点是让模型会调用函数。

学习 MCP 的时候,重点是让 Agent 能连接工具、数据和外部资源。

学习 Multi-Agent 的时候,重点是让多个 Agent 能分工完成复杂任务。

而 A2A 更进一步,它关注的是:

当 Agent 越来越多、越来越分散、来自不同团队和平台时,它们如何像一个网络一样协作?

这就是 A2A 的价值。

它不是让单个 Agent 更聪明,而是让 Agent 生态更容易连接。

未来真正复杂的智能系统,很可能不是一个超级 Agent 解决所有问题,而是多个专业 Agent 通过协议协作:

复制代码
一个 Agent 负责理解问题
一个 Agent 负责检索知识
一个 Agent 负责查询日志
一个 Agent 负责分析指标
一个 Agent 负责生成报告
一个 Agent 负责审计和确认

A2A 就是这些 Agent 之间的协作语言。

所以,如果我们站在 Agent 工程师的角度看,A2A 最值得关注的不是"它用了什么协议格式",而是它代表的趋势:

Agent 正在从单点能力,走向互联协作。

这也意味着,未来做 Agent 项目,不能只会写 prompt、调模型、接工具。

还要理解:

  • Agent 如何描述自己的能力;
  • Agent 如何发现其他 Agent;
  • Agent 如何委托任务;
  • Agent 如何处理长任务;
  • Agent 如何传递上下文;
  • Agent 如何保证安全和可信;
  • Agent 如何在复杂系统中协作。

这才是 Agent 工程真正有意思的地方。

相关推荐
有Li1 小时前
HOI-Brain:从fMRI中准确提取带符号高阶交互用于脑疾病诊断的多通道
论文阅读·人工智能·交互·文献·医学生
geovindu1 小时前
go: Coroutines Pattern
开发语言·后端·设计模式·golang·协程模式
RSTJ_16251 小时前
PYTHON+AI LLM DAY SEVENTY-TWO
人工智能
weixin_422329311 小时前
企业级 RAG 系统实战详解
ai·rag
weixin_495248401 小时前
短剧漫剧批量译制全流程指南:短剧漫剧如何规模化译制?
人工智能
JAMSAN09301 小时前
16.0% 高增长!全球异构计算架构服务市场扩容态势
汇编·人工智能·架构
江屿风1 小时前
C++图论基础拓扑排序算法流食般投喂
开发语言·c++·笔记·算法·排序算法
天才少年曾牛1 小时前
Android新增服务添加selinux权限
android·java·frameworks
郝学胜-神的一滴1 小时前
Qt 高级开发 030:QListWidget 右键菜单全解,从策略配置到精准删除的优雅实现
开发语言·c++·qt·程序人生·用户界面