A2A 协议:智能体之间怎么对话,以及它到底解决了什么
我平时主要用 Claude Code 给自己的几个小项目写代码,所以对 MCP 那一套——把模型接到工具、数据库、文件系统上——算是熟门熟路。上一篇写并行子代理的时候,我让一个工作流编排出十几个子代理同时干活,那种「多个智能体协作」的体感,其实已经摸到 A2A 想解决的问题边上了:当智能体不止一个,它们之间该怎么说话?
A2A(Agent2Agent)就是冲这个问题来的。它是 Google 在 2025 年 4 月放出的开放协议,2025 年 6 月连同 SDK 和工具一起捐给了 Linux Foundation,今年 3 月发布了第一个稳定的 1.0 版本。
一、解决「孤岛」问题
先说清楚 A2A 和 MCP 不是一回事,这是理解它的前提。
MCP 解决的是「一个智能体怎么用上外部工具」:把模型接到数据库、API、文件系统这些系统上,让它能查能调。这是一种纵向的集成——智能体在上,工具在下,模型伸手去够。
A2A 解决的是另一个方向:「一个智能体怎么和另一个智能体说话」。这是横向的。Google 那篇《AI 智能体协议开发者指南》里有个我觉得很贴切的说法:MCP 回答的是「我手上有什么」,A2A 回答的是「别人懂什么」。你的厨房管理智能体能查自己的库存(MCP),但它不知道今天的批发价、供货商的品质分级、到货窗口——这些知识在另外几个智能体那里,得问它们(A2A)。
这里有个关键的设计取向,我觉得是 A2A 最值得记住的一点:它把对方当成一个不透明的黑盒(opaque agent)来对待。两个智能体协作时,不共享各自的内部状态、记忆、工具和提示词,只通过协议规定的消息往来。这跟「把对方的能力当成自己的函数库直接调进来」是两种思路——A2A 假定你根本不知道、也不需要知道对方内部是怎么实现的,它可能是别家公司、用别的框架、跑在别的云上造出来的。你只管按协议说话。
另一个取向是尽量复用现成标准,不另起炉灶:传输走 HTTP,调用用 JSON-RPC 2.0(1.0 起也支持 REST 和 gRPC 两种绑定),实时更新用 Server-Sent Events。这点我比较认可——一个想被广泛接受的协议,越少要求对方学新东西越好。
二、Agent Card
两个素未谋面的智能体要协作,第一步是发现:我怎么知道你是谁、你会干什么、该往哪发请求、要不要鉴权?
A2A 的答案是一张「名片」,叫 Agent Card,本质是一个 JSON 文档。约定俗成地放在服务的 /.well-known/agent-card.json 路径下,对方一个 HTTP GET 就能拿到。
名片里大致有这么几样东西:
- 身份:
name、description、提供方信息; - 端点:
url,也就是这个智能体的 A2A 服务地址; - 能力:
capabilities,比如支不支持流式(streaming)、支不支持推送通知(pushNotifications); - 技能:
skills,一组它能干的活,每个技能有 id、名字、描述; - 鉴权:
securitySchemes,声明要用 Bearer、OAuth2 还是别的方式才能调它。
顺嘴提一句历史:这个路径早期是 /.well-known/agent.json,后来才改成 agent-card.json。这种细节上的变动正好说明协议还年轻,后面第七节我会再回到这点。
三、核心概念:Task、Message、Part、Artifact
拿到名片、知道对方会干什么之后,真正的协作靠四个对象撑起来。把这四个词搞清楚,A2A 的报文基本就能读懂了。
Task(任务) 是整个协议的核心,也是一切的单位。它是一个有状态的工作单元,由服务端在收到消息时生成,带一个唯一 id、一个状态、一段消息历史,以及一组产出物。注意它是有状态、可能长时间运行的——这跟 HTTP 那种「一问一答完事」很不一样,是 A2A 一个重要的区别,下一节细说。
Message(消息) 是一次来回的发言,带个 role(user 或 agent),内容装在一个 parts 数组里。一来一回的若干条 Message 就组成了 Task 的历史。
Part(部件) 是内容的最小单元,分三种:text(纯文本)、file(文件,可以是字节也可以是一个 url 引用)、data(结构化的 JSON)。这种拆分让 A2A 是模态无关的——一条消息里可以同时塞文字、图片和一段结构化参数,不挑内容类型。
Artifact(产出物) 是任务最终的输出,同样由若干 Part 组成。它和 Message 的区别在于定位:Message 是过程中的对话,Artifact 是结果。
我个人觉得这套词汇里最值得玩味的是 Task 的「有状态」。它等于承认了一件事:智能体干的活往往不是一秒钟能回的,可能要查好几个地方、要等人确认、要跑很久。协议如果只支持一问一答,根本兜不住这种场景。所以 A2A 把任务的「一生」专门做成了一个状态机。
四、状态机
一个任务从 submitted(已受理)开始,进入 working(处理中)。然后有几种走向:
- 顺利干完,进
completed,带着产出物收尾; - 出错了进
failed,被取消进canceled,对方直接不接这活儿进rejected——这几个都是终止态,到此结束。
中间还有两个有意思的「可中断」状态:input-required(需要你补充更多信息才能继续)和 auth-required(需要先完成鉴权)。任务卡在这里不算结束,等你把缺的东西补上,它能从 working 继续往下走。这恰好对应了真实协作里那种「我需要再问你一句」的来回——比如一个订机票的智能体处理到一半,发现要你确认选哪个航班。
把这一整套状态摊开看,我觉得设计者心里装的不是「调一个 API」,而是「托付一件可能要花点时间、中途可能要商量的事」。这跟我们平时写 RESTful 接口的心智模型是有差别的。
五、一次完整的交互长什么样
把前面的拼起来,一次典型的协作大致是这样:
先 GET 到名片、确认对方能干这活、知道怎么鉴权,然后发起任务。用 JSON-RPC 绑定的话,发起一个任务长这样:
{
"jsonrpc": "2.0",
"id": 1,
"method": "message/send",
"params": {
"message": {
"role": "user",
"parts": [
{ "kind": "text", "text": "把 100 美元换算成今天的日元" }
]
}
}
}
服务端收到后生成一个 Task 返回。如果你不想干等,可以改用 message/stream,对方会通过 SSE 把进度一段段推回来:先是状态变成 working 的 TaskStatusUpdateEvent,接着是产出分片的 TaskArtifactUpdateEvent,最后任务落到 completed。
更新结果一共有三种取法,按场景选:
- 轮询——隔一阵
tasks/get问一次「好了没」,最省事,但不实时; - 流式——
message/stream,用一条 SSE 长连接实时收事件,适合要看进度的交互; - 推送——长任务别挂着连接干等,注册一个 webhook,对方有进展了 POST 通知你,断线了再
tasks/get把状态捞回来。
这套方法名(message/send、message/stream、tasks/get、tasks/cancel 等)是 JSON-RPC 绑定下的写法。规范完整的对象定义、三种传输绑定的差异、鉴权细节,都在官方规范里,参考实现和各语言 SDK 在 GitHub 的 a2aproject/A2A 仓库。想读代码跑个 demo 的,从那里入手最快。
六、那它和 MCP 到底是什么关系
我知道很多人——包括一开始的我——第一反应是「这俩是不是打架的」。不是。它们是互补的,工作在不同的层。
还是用那个供应链的例子最直观:你的智能体用 MCP 查自己的库存数据库(连工具),再用 A2A 去问一个外部的定价智能体今天的市场行情(连智能体),两者拼在一个工作流里。MCP 管「接系统」,A2A 管「接同行」,谁也替代不了谁。
更有意思的是大背景:MCP 是 Anthropic 提出来开放的,A2A 是 Google 提出、现在交给了 Linux Foundation。两家最大的模型厂商各自把一层的连接标准开源出来,而且方向上没怎么撞车。对我们写代码的人来说这是好事——少一点私有协议的绑定,多一点能互通的东西。所谓「A2A vs MCP 之争」,多半是标题党,别被带节奏。想从工具这一层补一下,可以看 MCP 官网。
七、碎碎念
第一,对大多数人,真实需求还早。 A2A 真正发光的地方,是跨组织、跨厂商的边界:你的智能体要去调一个别人造的、你管不着内部的智能体。可现在大部分团队,连「多个独立造出来的智能体需要互相说话」这个前提都还没有。同一个项目里的协作,你直接调函数、共享上下文就完了,犯不着架一套网络协议。对我这种单人小项目,这条边界基本不存在。所以它现在对我,更像是「知道有这么回事」,而不是「明天就要上」。
第二,「黑盒对黑盒」是把双刃剑。 不共享内部状态确实换来了解耦和互通,但反过来——你在跟一个自己没法完全预测的东西协作。它的输出对不对、会不会乱花钱、有没有安全隐患,你都得自己兜底。协议在鉴权上是「默认要安全」的(名片里就声明了 securitySchemes),但「怎么信任一个远端智能体吐出来的结果」这件事,协议给不了你答案,得靠你自己加校验。这方面 Red Hat 那篇讲 A2A 安全的文章值得一读。
第三,协议还年轻,别拿它当冻结的地基。 1.0 是今年 3 月才发布的第一个稳定版,前面也提到 well-known 路径已经改过一次名,传输绑定也从一种变成了三种。生态在快速动,现在就把某个关键链路死死焊在「它不会变」的假设上,我觉得为时尚早。
话说回来,势头是真的。 从 2025 年的 50 多家到现在 150 多家组织在跟进,主流云平台都在接,背后又是 Linux Foundation 这种中立基金会托管——如果你正在做跨厂商的多智能体系统,这门「共同语言」基本就是在你眼前成形的,值得持续盯着。Google 那篇周年回顾里有更全的进展数据。
小结
一句话概括:A2A 之于「智能体↔智能体」,就像 MCP 之于「智能体↔工具」。 它把发现(Agent Card)、有状态的任务(Task)、模态无关的消息(Message / Part)、产出(Artifact)这几件事标准化了,让两个互不了解内部的智能体能照着同一套规矩协作。
要不要现在就用,取决于一个很朴素的问题:你手头有没有真的需要跨边界说话的智能体? 有,那这就是你绕不开的协议;没有,那花半小时把概念读懂,当个「知道它在那儿」的储备就够了——这点和我当初对并行子代理的态度差不多。对一个所有代码都要自己负责的人来说,先看清楚一个东西解决了什么、又没解决什么,比急着上车重要。
等我手上真有一个该用 A2A 的场景、亲手接过一遍之后,再回来更新这篇,写点踩坑的实感。