A2A协议实战:拆解Agent间通信的完整流程

为什么需要A2A协议
随着AI Agent应用的爆发式增长,单个Agent往往难以独立完成复杂任务。AI Agent(智能代理)是指能够自主感知环境、做出决策并执行动作的AI系统,与传统的聊天机器人不同,Agent具备目标导向、工具调用和多步推理能力。2023年以来,随着GPT-4、Claude等大语言模型能力的飞跃,AutoGPT、CrewAI、LangGraph等Agent框架层出不穷,Agent从概念验证走向生产环境。然而,当多个Agent需要协同工作时,它们之间的通信就成了一个绕不开的问题。如果没有统一的标准,Agent之间的对接会异常繁琐——每接入一个新Agent,就得重新设计一套通信逻辑。
Agent2Agent(简称A2A)协议正是为解决这一痛点而生。A2A并非一个全新的底层协议,而是建立在成熟Web标准之上的一套通信规范,目标是实现**"一次开发,到处对接"**。本文将结合一个具体的Demo,深入拆解A2A协议的底层工作机制。
Demo概览:旅行Agent与天气Agent的协作
为了直观理解A2A协议的运作方式,我们来看一个在本地实现的双Agent协作场景:
- Agent-Client(Travel Agent):作为客户端,能从用户输入中提取旅行目的地,并根据天气信息生成穿衣打包建议。
- Agent-Server(Weather Agent):作为服务端,通过大模型识别字符串中的城市名,并查询对应的天气数据。
实际交互流程如下:当用户在UI终端输入"我想下周去东京旅行,该带什么样的衣服"时,问题首先发送给Travel Agent。Travel Agent通过大模型提取出目的地"东京",随后向Weather Agent发起天气查询请求。Weather Agent查询完毕后将结果返回,Travel Agent再基于天气数据生成最终的着装建议。
这个看似简单的交互,背后正是A2A协议在支撑两个独立Agent之间的标准化通信。
A2A的分层架构
A2A协议在架构设计上分为两个核心层次:应用层和传输层。
应用层:定义"说什么"
应用层包含四大要素:Agent Card、Task、Message和Artifact。这一层定义了Agent之间沟通的语义内容,决定了通信双方需要交换哪些信息。这种应用层与传输层分离的设计,遵循了经典的关注点分离原则——业务语义的变化不会影响底层传输,反之亦然。

传输层:定义"怎么传"
传输层负责实际的数据传输,支持多种方式:JSON-RPC、SSE(Server-Sent Events)、REST以及gRPC。本Demo采用的是JSON-RPC + SSE的组合,这也是官方推荐的最简单方案。
- JSON-RPC:一种无状态的轻量级远程过程调用协议,最早在2005年提出。它的核心理念极其简洁:请求是一个包含method(方法名)、params(参数)和id(请求标识)的JSON对象,响应则包含result或error和对应的id。与REST API相比,JSON-RPC只需要一个HTTP端点,所有调用都通过POST方法发送,由method字段区分不同操作。这种设计简化了路由逻辑,非常适合Agent间这种方法调用语义明确的场景。
- SSE:Server-Sent Events是HTML5规范的一部分,允许服务器通过单向HTTP长连接持续向客户端推送数据。与WebSocket双向通信不同,SSE是纯服务器到客户端的单向流,基于标准HTTP协议,天然支持断线重连和事件ID追踪。在A2A场景中,Agent处理任务可能耗时数秒甚至数分钟,SSE让客户端无需轮询即可实时获取状态更新。相比WebSocket,SSE不需要协议升级握手,对防火墙和代理服务器更友好,部署运维成本更低。
此外,Agent Card、Task、Message等数据结构都通过Protobuf进行定义,并最终序列化为JSON进行传输。Protocol Buffers(Protobuf)是Google开发的一种语言无关、平台无关的结构化数据序列化机制。在A2A协议中,Protobuf扮演的是「数据结构定义语言」的角色——它通过.proto文件精确定义各数据结构的字段类型和约束关系,确保不同语言实现的Agent对数据格式有统一理解。虽然最终传输时序列化为JSON以保证可读性和Web兼容性,但Protobuf定义提供了强类型约束和版本演进能力,避免了纯JSON Schema容易出现的歧义问题。

五大核心概念详解
Agent Card:Agent的名片
Agent Card是客户端发现服务端的第一个入口,它回答了三个关键问题:我是谁、我能做什么、怎么调用我。
- "我是谁":由
name、description、version等字段描述; - "我能做什么":由
skills列表描述,包含每个技能的具体信息; - "怎么调用我":由
supported interfaces描述,包括支持的协议及协议URL。
客户端获取Agent Card非常简单:只需向A2A规范约定的路径 /.well-known/agent-card.json 发起GET请求,就能拿到服务端完整的Agent Card信息。这里使用的/.well-known/路径前缀是IETF在RFC 5785中定义的标准机制,用于在Web站点上暴露元数据信息而不与业务路由冲突。著名案例包括Let's Encrypt使用的/.well-known/acme-challenge/(域名验证)、OAuth使用的/.well-known/openid-configuration(服务发现)等。A2A协议完全遵循这一互联网最佳实践,使得任何客户端只需知道服务端域名即可自动发现其Agent能力,无需额外的注册中心或目录服务。
Task:有状态的工作单元
Task是A2A协议中最有特色的概念之一。它不是一次性请求,而是一个有状态、可追踪、可中断恢复的工作单元,内部维护着一个完整的状态机:
- Task创建后状态为
submitted; - Agent开始处理时状态变为
working; - 处理结果有三种可能:成功完成(
completed)、处理失败(failed)、需要用户额外输入(input-required)。
这种有状态Task设计的工程意义在于:它借鉴了工作流引擎(如Temporal、Airflow)的理念,但做了极大简化。submitted→working→completed/failed/input-required这个状态流转模型,覆盖了Agent交互中最常见的场景:长时间运行的推理任务需要进度反馈(working)、多轮对话需要追加输入(input-required)、网络故障后需要恢复上下文(通过task id重新查询状态)。这种设计让A2A天然支持异步工作模式,Agent可以接收任务后在后台处理数小时,客户端随时通过task id查询进度。
每次状态变更,服务端都会通过SSE向客户端推送 status update 事件,让客户端实时掌握任务进度。Task还支持取消(cancel)、认证(auth-required)、推送通知(webhook回调)等能力。
Message:对话的载体
Message是Agent之间一次通信的基本单位,包含以下核心字段:
- message id:一条Message的唯一标识;
- role:标识发送方是user还是agent;
- task id:标识该Message属于哪个Task;
- context id:标识该Message属于哪个会话;
- parts:承载具体的通信内容。
其中,context id的设计值得关注。一个context可以跨越多个Task,这意味着多个相关但独立的任务可以共享同一个会话上下文。例如在旅行规划场景中,查询天气、预订酒店、规划路线可能是三个独立的Task,但它们共享同一个context id,从而让每个Agent都能获取到完整的对话历史。

Part:内容的最小构建单元
Part是内容的最小构建单元,一个Message或Artifact可以包含多个Part。Part有四种类型:
- text:纯文本字符串,用于承载对话文字;
- data:结构化的JSON数据,如天气数据、表格、API响应;
- url:引用外部文件的URL字符串,如图片、文档链接;
- raw:二进制字节流,可直接传输文件。
正是这种灵活的Part设计,让A2A协议能够传输任意复杂的内容。一条Message可以同时包含一段文字说明(text Part)、一张分析图表的链接(url Part)和一段结构化数据(data Part),这种多模态内容的组合能力是Agent间复杂协作的基础。在Demo中,客户端发送单个text类型的Part,服务端则返回包含天气数据的Artifact。
Artifact:Task的交付物
Artifact是Task完成后产出的结果。一个Task可以产出多个Artifact——比如先返回摘要,再返回详细报告。Artifact还支持分块流式传输,非常适合大文件或长文本的逐步交付场景。Artifact与Message的关键区别在于:Message是对话过程中的交互内容,而Artifact是任务完成后的正式产出物。这种区分让客户端可以清晰地将「中间讨论」与「最终结果」分开处理。
完整通信流程拆解
理解了核心概念后,来看A2A协议的完整通信流程。整个过程可以分为三个阶段。
第一阶段:Discovery(服务发现)
客户端通过GET请求向服务端的 /.well-known/agent-card.json 路径请求Agent Card,服务端返回200 OK及完整的Card信息。此时客户端就知道了对方叫"Weather Agent"、能够执行"weather query"任务,并且可以通过JSON-RPC在指定端点通信。

这一阶段完全标准化,是A2A实现"一次开发、到处对接"的基础。值得注意的是,这种去中心化的服务发现模式与微服务架构中的服务注册中心(如Consul、Eureka)形成了有趣的对比——A2A选择了更轻量的方式,不依赖任何中心化组件,每个Agent自描述、自发布,降低了系统部署的复杂度。
第二阶段:Task执行(核心交互)
这是整个通信的核心环节。客户端构建 send message request,通过JSON-RPC发送到服务端端点。具体来说,这个JSON-RPC请求的method字段为tasks/send,params中包含了完整的Message对象(含task id、context id和parts)。服务端不会一次性返回结果,而是通过SSE逐步推送事件:
- 第一条事件:告知客户端Task已创建完成;
- 第二、三条事件:告知正在处理Task(状态为working);
- 最后一条事件:告知Task处理完成(状态为completed),并附带结果Artifact。
客户端收到的每个event都是独立的SSE消息,因此可以实时显示进度(如"正在查询天气")、提前拿到部分结果、在中间状态做决策,甚至在状态为failed时执行重试逻辑。这种流式交互模式的优势在实际生产中尤为明显:当Agent需要调用多个外部API或执行复杂推理时,用户不会面对一个长时间无响应的等待界面,而是能看到任务的逐步进展。
第三阶段:流结束
当服务端推送完最后一个event后,SSE连接关闭。客户端汇总所有event,提取最终结果。至此,一次完整的Agent间A2A通信就结束了。如果客户端在流传输过程中意外断开连接,可以通过task id重新查询任务状态——Task的持久化特性确保了不会丢失已完成的工作。
总结
A2A协议巧妙地复用了成熟的Web标准(JSON-RPC、SSE、HTTP),通过Agent Card实现了去中心化的服务发现,通过有状态的Task和流式的SSE推送支撑起复杂的异步交互。对于正在构建多Agent系统的开发者而言,理解A2A协议的工作机制能够帮助我们避免重复造轮子,让不同来源、不同厂商的Agent真正实现互联互通。
值得一提的是,A2A协议与另一个热门协议MCP(Model Context Protocol)是互补关系而非竞争关系:MCP解决的是Agent与工具(Tool)之间的通信问题,而A2A解决的是Agent与Agent之间的通信问题。在一个完整的多Agent系统中,每个Agent内部可能通过MCP调用各种工具,而Agent之间则通过A2A协议进行协作。
如果你对A2A协议的实际运行效果感兴趣,可以尝试在本地搭建类似的双Agent Demo,这将是理解A2A协议最直接有效的方式。
相关推荐

Claude Code入门指南:终端原生AI编程助手完整教程
详解Claude Code安装部署、多模型切换、代码生成与项目重构等核心功能。掌握这款终端原生AI编程工具,告别IDE依赖,在命令行实现高效开发闭环。

Modelstamp:为ML模型持久化加上完整性校验与环境漂移检测
Modelstamp是一款轻量级开源工具,为scikit-learn等ML模型的保存加载流程添加SHA-256完整性校验、依赖漂移报告和HMAC认证,解决模型持久化中环境不一致的隐患。

Claude Code接入DeepSeek完整教程:低成本AI编程实战指南
详细介绍Claude Code安装配置全流程,通过CC-Search工具接入DeepSeek大模型,实现低成本AI编程体验。涵盖Node.js环境搭建、配置文件修改、API密钥获取及实战演练。