☰
A2A 协议:面向异构智能体的互操作标准与工程实践
2026/9/29 3:31:06 网站建设 项目流程

A2A 协议:面向异构智能体的互操作标准与工程实践

说明:本文从一个常见的问题出发——“A2A 协议是什么”——但目标不止于给出一个能应付面试的定义。我们将按照"定位 → 数据模型 → 交互流程 → 传输绑定 → 与 MCP 的关系 → 工程权衡"的顺序,把 A2A(Agent2Agent Protocol)当作一个普通的分布式系统协议来分析:它解决了什么问题、抽象边界在哪里、落地时要注意什么,以及它不是什么。


一、背景:智能体协作的"孤岛"问题

过去两年,围绕单个 Agent 的构建已经形成了相对成熟的工具链:LLM + Prompt + Memory + Tool Use(Function Calling)。但当我们把视野从"单个 Agent"拉到"多个 Agent 协同完成一个复杂目标"时,会立刻撞上一堵墙——异构孤岛。

现实中的 Agent 可能由不同团队、不同框架(LangGraph、CrewAI、AutoGen、Google ADK、Semantic Kernel……)、不同大模型构建,部署在不同的域名与网络环境里。此时让它们协作,常见的临时方案是:把对方的 Agent “包成一个 Tool”,用私有 HTTP 接口 + 自定义 JSON 去对接。这种方式在规模上来后会迅速恶化:

  1. 发现难:没有统一的能力描述格式,调用方只能靠文档或口头约定。
  2. 协作语义弱:普通 HTTP 请求-响应无法原生表达"长时任务、状态流转、多轮澄清、主动回调"。
  3. 重复造轮子:每个集成对都要重新约定鉴权、错误码、进度推送、取消机制。

A2A 的出现,本质上是要把这套"智能体间通信"从私有的点对点集成,提升为标准化的互操作层。它把智能体视为对等的、不透明的协作者(而非被调用的工具),通过一套自描述的能力声明 + 有状态的任务模型 + 可复用的传输绑定,让不同阵营的 Agent 能够互相发现、委派任务、同步状态、交付结果。

一句话定位:A2A 是 Agent 世界的"外交协议"——它不关心对方内部用什么模型、什么框架,只规定"你如何描述自己、如何接活、如何回报"。


二、A2A 是什么:官方定位与演进

A2A 全称Agent2Agent Protocol,是由 Google 于 2025 年 4 月首次发布、后捐赠给Linux Foundation(Agentic AI Foundation)治理的开放标准协议[citation:1]。截至 v1.0.0(2026 年 3 月 GA),规范已经进入稳定维护期,拥有多家云厂商与开源框架的支持[citation:2]。

理解 A2A 最重要的一件事是认清它的设计哲学——“Agents Are Not Tools”:

维度A2A 的立场
对端身份远程 Agent 是独立、有推理能力的对等实体
抽象边界不定义 Agent 内部实现(prompt / memory / tools)
协议范围不做编排框架、不与 MCP 竞争
标准化方式Proto-First,proto 文件为唯一规范性定义

这一点决定了 A2A 的"克制":它只规范 Agent 之间的契约面,而把"Agent 内部怎么想"完全留给实现方。正是这种克制,才让跨厂商互操作成为可能。


三、核心数据模型:五个关键概念

A2A 的数据模型可以概括为"五个名词",用一个口诀记忆非常有效:Agent Card 是简历,Task 是派单,Message 是聊天记录,Artifact 是交付物。下面逐一落到工程细节。

3.1 Agent Card:智能体的"自描述名片"

AgentCard是一份机器可读的 JSON 元数据文档,通常发布在符合RFC 8615的 Well-Known URI 路径下:

GET https://{domain}/.well-known/agent-card.json

客户端(另一个 Agent 或用户应用)通过解析这张卡片,判断"该不该找它干活、怎么跟它通信、需要什么凭据"。一份较完整的 Agent Card 包含以下模块[citation:16][citation:17]:

{"name":"Travel Booking Agent","description":"搜索并预订机票、酒店","version":"1.0.0","provider":{"organization":"TravelCorp","url":"https://travelcorp.com"},"supportedInterfaces":[{"url":"https://api.travelcorp.com/a2a","protocolBinding":"JSONRPC","protocolVersion":"1.0"}],"capabilities":{"streaming":true,"pushNotifications":true},"defaultInputModes":["text/plain","application/json"],"defaultOutputModes":["text/plain","application/json"],"skills":[{"id":"flight-search","name":"机票搜索","description":"按出发地、目的地、日期搜索可用航班","tags":["travel","flight"],"examples":["搜索明天北京到上海的航班"]}],"securitySchemes":{"oauth2":{"type":"oauth2","flows":{"clientCredentials":{"tokenUrl":"https://auth.travelcorp.com/token","scopes":{"search":"搜索航班和酒店","book":"完成预订"}}}}},"security":[{"oauth2":["search","book"]}]}

关键字段解读:

  • supportedInterfaces:显式声明协议绑定、版本与端点,支持多绑定并存与版本协商(客户端选择兼容版本)[citation:2]。
  • skills:这是能力发现的核心——把"能做什么"结构化、可检索。相比 Tool 清单,它更偏向意图与能力而非具体函数签名。
  • securitySchemes/security:把鉴权要求前置到发现阶段,避免"先调再用、报错才知道要 token"。
  • 签名(signatures,JWS):企业场景下可验证卡片来源与完整性,防止中间人篡改[citation:16]。
  • Extended Agent Card:认证后可获取更丰富的扩展信息(GetExtendedAgentCard),实现分层信息披露——对外只暴露摘要,认证后才给细节[citation:2]。

工程提示:发现机制不止 Well-Known URI 一种,还包括策展注册中心(中心化目录,按 skill/tag 查询)与静态配置(已知关系直接硬编码)[citation:17]。协议没有规定中心化注册表,生产环境通常需要自己加一层"发现/治理层"[citation:5]。

3.2 Task:有状态的核心工作单元

如果说 Agent Card 解决"找到谁",Task解决的就是"怎么把活交出去并盯住它"。Task 是 A2A 中唯一同时具备身份、生命周期、状态和产出物的概念,其数据结构大致为:

{"id":"task-123","contextId":"ctx-001","status":{"state":"working","message":{"text":"正在搜索航班..."}},"artifacts":[],"history":[...]}
  • id:任务全局唯一标识,支持跨 Agent 追踪。
  • contextId:所属上下文(会话/流程),用于把多个 Task 归入同一业务流程。
  • status:当前状态,含state与可选的描述消息。
  • artifacts:最终交付物集合。
  • history:交互历史。

Task 状态机是 A2A 区别于普通 API 调用最关键的部分[citation:1][citation:10]:

┌─────────────┐ │ SUBMITTED │ 已提交,尚未开始处理 └──────┬──────┘ ▼ ┌─────────────┐ │ WORKING │ 正在处理,可能持续推送进度 └──┬───┬───┬──┘ ┌───────────┘ │ └───────────┐ ▼ ▼ ▼ ┌──────────┐ ┌──────────────┐ ┌───────────┐ │COMPLETED │ │ INPUT_REQUIRED│ │AUTH_REQUIRED│ │ (终态) │ │ (暂停,等输入)│ │ (暂停,等认证)│ └──────────┘ └──────┬───────┘ └──────┬────┘ │ │ ▼ │ 回到 WORKING ◄────────────┘ │ ┌────────┬───────┴───────┬─────────┐ ▼ ▼ ▼ ▼ FAILED CANCELED REJECTED (unknown) (终态) (终态) (终态)

需要特别注意的几点:

  1. 终态不可重启:一旦进入COMPLETED/FAILED/CANCELED/REJECTED,该 Task 就不能再次启动,后续操作必须在同一contextId下创建新 Task[citation:7]。这是一个重要的工程权衡——简化了实现与追踪,但意味着"重试"需要由上层业务自己建模。
  2. INPUT_REQUIRED与AUTH_REQUIRED是"暂停态"而非终态:前者支持人机协作 / 多轮澄清,后者把鉴权异常显式建模进状态机,而不是靠错误码偷偷传递。
  3. REJECTED≠FAILED:REJECTED表示"拒绝执行"(如权限不足、无法理解意图),FAILED表示"尝试了但出错了"——语义不同,调用方应区别处理。
  4. unknown:任务状态无法确定(ID 无效、未知、已过期)[citation:10]。

长时任务是 Task 状态机的第一性驱动力。一个供应链优化任务可能跑几小时甚至几天,单纯请求-响应会让连接和资源管理陷入困境——这正是 A2A 引入状态机、轮询、流式、推送多种同步机制的动因。

3.3 Message 与 Part:通信内容的最小单元

Message表示一次通信轮次,包含role(user= 客户端发送 /agent= 服务端发送)和一个或多个Part:

{"role":"user","parts":[{"type":"text","text":"帮我订明天北京到上海的机票"},{"type":"data","data":{"preferred":"经济舱"}}]}

Part是内容与多模态的最小载体,支持text(文本)、file(文件,含 MIME)、data(结构化 JSON)[citation:1]。这让 A2A 天然支持多模态:文本、图片、音频、视频、结构化数据、文件都能在消息/交付物中流转。

Message与Artifact的分工:

  • Message:通信过程中的非交付内容——指令、上下文、思考过程、状态更新。
  • Artifact:任务完成后正式的、不可变的交付物,可包含多个 Part[citation:12]。

一句话:Message 是过程,Artifact 是结果。把两者分开,才能让"中间讨论"和"最终成果"不混在一起,也便于做产物管理与审计。


四、交互流程:一次完整委派长什么样

把上面四个概念串起来,一个典型的 A2A 交互时序如下:

Client Agent Remote Agent │ │ │── GET /.well-known/agent-card.json ──▶│ ① 发现 │◀── AgentCard (能力/接口/安全) ────────│ │ │ │── SendMessage (Task, Message) ───────▶│ ② 委派 │◀── Task(id, status=SUBMITTED) ───────│ │ │ │◀── SSE: status=WORKING ──────────────│ ③ 进度 │◀── SSE: artifact delta ──────────────│ │ │ │── GetTask (轮询/兜底) ──────────────▶│ ④ 查询 │◀── Task(status, artifacts) ──────────│ │ │ │◀── Task(status=COMPLETED, artifacts) │ ⑤ 交付

对应到**抽象操作(Abstract Operations)**层,主要方法为[citation:9][citation:12]:

操作作用
SendMessage发送消息,创建或继续一个 Task
SendStreamingMessage发送消息并通过流接收更新(SSE)
GetTask查询 Task 当前状态与结果
ListTasks按条件列出任务
CancelTask请求取消任务
SubscribeToTask订阅已有 Task 的流式更新
Create/Get/List/DeleteTaskPushNotificationConfig配置异步 Webhook 推送
GetExtendedAgentCard认证后获取扩展 Agent Card

长时任务的三套同步机制

A2A 对"任务进度如何同步到调用方"给出了三种等价机制,开发者按场景选择[citation:2]:

  1. 轮询(Polling):SendMessage后周期性GetTask——实现简单,适合秒级延迟可接受的场景。
  2. 流式(SSE,Server-Sent Events):SendStreamingMessage,服务端持续推送TaskStatusUpdateEvent/TaskArtifactUpdateEvent——适合需要实时进度、但调用方需维持长连接的场景。
  3. 推送通知(Push Notification):预先配置 Webhook,任务状态变化时由服务端主动回调——最适合小时级/天级的超长任务,调用方无需维持连接。

这三套机制共用同一套StreamResponse数据模型,是 A2A 设计中"多种传输、统一语义"的典型体现。


五、传输绑定:分层架构的工程价值

A2A 规范按Data Model → Abstract Operations → Protocol Bindings三层组织[citation:9]。第三层协议绑定允许同一套语义映射到多种传输,且规范保证它们之间语义等价[citation:2]:

绑定传输方式流式支持典型场景
JSON-RPC 2.0HTTP POST,application/jsonSSE(text/event-stream)最简单、生态最广
gRPCHTTP/2 + ProtobufServer Streaming RPC高性能、强类型
HTTP+JSON / REST标准 RESTful 端点SSE对接既有 REST 基础设施

示例:一个"发送消息"操作在不同绑定下的映射[citation:9]:

// JSON-RPC 2.0 请求{"jsonrpc":"2.0","id":1,"method":"SendMessage","params":{"message":{"role":"user","parts":[{"type":"text","text":"我要一杯拿铁"}]},"taskId":null}}
# REST 等价端点 POST /message:send Content-Type: application/json { "message": {...} }
// gRPC 等价服务 service AgentService { rpc SendMessage(MessageRequest) returns (Task); rpc SendStreamingMessage(MessageRequest) returns (stream StreamResponse); }

HTTP 层的约定也不容忽视:规范额外定义了A2A-Version头(如1.0)、A2A-Extensions头(逗号分隔的扩展 URI),以及自定义 media typeapplication/a2a+json;生产环境必须使用 HTTPS(推荐 TLS 1.3+)[citation:17]。

为什么这种"分层 + 多绑定"设计值得学习:它把"业务语义"和"传输细节"解耦,让不同技术栈都能接入,同时通过 proto 作为唯一规范性来源消除"规范漂移(specification drift)"。这是协议设计的通用最佳实践,即便你不用 A2A,这套思路也可借鉴。


六、A2A 与 MCP:精确辨析,而非口号

"A2A 管同事、MCP 管工具"是很好记的口诀,但要写出客观的技术分析,需要把边界讲到更细。

6.1 分工:一横一纵

维度A2AMCP
提出方 / 治理Google 发起,LF 治理Anthropic 提出
通信对象Agent ↔ AgentAgent ↔ Tool / 资源
对端智能性两端都有推理能力仅 Agent 端智能,Tool 端是确定性服务
核心概念Agent Card、Task、Message、ArtifactTool、Resource、Prompt
状态性有状态,Task 完整生命周期通常无状态Tool 调用
交互模式多轮对话、委派、协商结构化函数调用、读写资源
发现机制Agent Card(能力声明)Tool 清单
典型延迟秒到分钟级(长时任务)毫秒级
认证双向认证,OAuth 2.0 / OIDC服务端控制为主
抽象层次高级(意图与能力)低级(具体功能/接口)

[citation:4][citation:8]

6.2 何时用哪个

判断依据很朴素——对端是"确定性函数"还是"需要推理的实体"[citation:4]:

  • 用 MCP:远程端是一个确定性函数——数据库查询、API 调用、代码执行沙箱、读文件。Agent 完全掌控交互过程。
  • 用 A2A:远程端需要对模糊指令做推理——解释意图、做判断、调用自己的 Tool、进行多轮对话。
  • 两者都用:编排 Agent 通过 A2A 把任务委派给专家 Agent,而每个专家 Agent 通过 MCP 访问自己的工具[citation:4]。

6.3 组合架构:一张分层图

┌──────────────────────────────┐ │ 用户复杂目标 │ └──────────────┬───────────────┘ ▼ ┌──────────────────────────────┐ │ 编排 Agent(总监) │ └──┬───────────┬───────────┬───┘ │ A2A │ A2A │ A2A ← 横向:Agent 间 ▼ ▼ ▼ ┌──────┐ ┌──────┐ ┌──────┐ │机票Agent│ │酒店Agent│ │报销Agent│ └──┬───┘ └──┬───┘ └──┬───┘ │ MCP │ MCP │ MCP ← 纵向:Agent→工具 ▼ ▼ ▼ ┌──────┐ ┌──────┐ ┌──────┐ │航司API│ │OTA平台│ │财务系统│ └──────┘ └──────┘ └──────┘

企业差旅实例:用户说"下周去上海,帮我订机票和酒店,还要能报销"。编排 Agent 通过 A2A发现机票、酒店、报销三个 Agent(可能分别来自航司、OTA、公司财务系统),读取各自的 Agent Card,用 Task委派并收集 Artifact,最终汇总成一份完整方案。而机票 Agent 内部,则用 MCP 去查航司库存 API。

常见误区澄清(这也是面试高频扣分点):

  • ❌ “有了 A2A,就要统一底层大模型” → A2A不管模型,只规定 Agent 间如何交流。
  • ❌ “A2A 只是 API 封装” → 它包含能力发现 + 任务状态机 + 交付物 + 多轮协商等协作语义。
  • ❌ “A2A 和 MCP 二选一” → 它们是互补关系,正经企业级系统通常两个都要[citation:8][citation:11]。

七、工程落地:优势与真实挑战

客观分析必须同时讲清楚收益和代价。A2A 的优势很明显:标准化互操作、解耦(新增 Agent 只需加 URL,不改代码)、原生支持长时/多轮/异步任务、安全前置。但它也带来了实实在在的工程挑战:

需要正视的几个问题

  1. 状态一致性管理复杂:多 Agent 长时协作下,Task 状态、上下文(contextId)、重试语义的分布一致性,需要业务层自己保证。
  2. 部分故障处理尚不成熟:一个编排流程里某个 Agent 长时间无响应、返回unknown、或交付物格式不兼容时,补偿与重试策略规范并未给出标准答案。
  3. 鉴权与权限治理不可忽视:跨厂商协作必须先确认"你是谁 + 你能做什么"——OAuth2/OIDC、scope、最小权限都要落地,不能因为是"Agent 内部"就省略。
  4. 协议仍在演进:v1.0 才刚稳定,真实生产部署的规模与最佳实践仍在积累中;生态的采纳广度最终决定协议的实际价值[citation:2]。
  5. 性能与成本:相比直接函数调用,引入 Agent 推理 + 多轮通信会显著增加延迟与 token 开销,不适合对延迟敏感的确定性链路。

最小可运行骨架(概念代码)

下面这段 Python 伪代码用于理解协议报文结构,不依赖官方 SDK:

# ---------- A2A Server 侧(简化)----------fromuuidimportuuid4fromdataclassesimportdataclass,fieldfromtypingimportList,OptionalimportjsonclassTaskState:SUBMITTED,WORKING,COMPLETED,FAILED,INPUT_REQUIRED=\"submitted","working","completed","failed","input-required"@dataclassclassTask:id:str=field(default_factory=lambda:f"task-{uuid4().hex}")context_id:str=field(default_factory=lambda:f"ctx-{uuid4().hex}")state:str=TaskState.SUBMITTED artifacts:List[dict]=field(default_factory=list)# Agent Card 发现端点@app.get("/.well-known/agent-card.json")defagent_card():return{...}# 见 3.1 完整卡片# JSON-RPC: 同步发送任务@app.post("/message:send")defsend_message(params:dict)->dict:task=Task()# ... 交由 task_handler 异步处理 ...task.state=TaskState.WORKINGreturn{"jsonrpc":"2.0","id":params.get("id"),"result":{"id":task.id,"status":{"state":task.state}}}# SSE: 流式发送任务@app.post("/message:stream")defsend_stream(params:dict):defevent_stream():yield'event: task-status\ndata: {"state":"working","message":"处理中..."}\n\n'yield'event: task-artifact\ndata: {"parts":[{"type":"text","text":"结果"}]}\n\n'yield'event: task-status\ndata: {"state":"completed"}\n\n'returnStreamingResponse(event_stream(),media_type="text/event-stream")# ---------- A2A Client 侧(简化)----------defdiscover(base:str)->dict:returnhttp.get(f"{base}/.well-known/agent-card.json").json()defdelegate(endpoint:str,text:str)->dict:payload={"jsonrpc":"2.0","method":"SendMessage","id":1,"params":{"message":{"role":"user","parts":[{"type":"text","text":text}]}}}returnhttp.post(endpoint,json=payload).json()defget_task(endpoint:str,task_id:str)->dict:payload={"jsonrpc":"2.0","method":"GetTask","id":2,"params":{"id":task_id}}returnhttp.post(endpoint,json=payload).json()

生产建议:真实项目优先使用官方 SDK(Python / JS / Java / Go / .NET)而非手写,避免重复实现状态机、错误模型与绑定细节[citation:2]。


八、总结:把单体智能连接成协同网络

回到开头的问题——“A2A 协议是什么”,一个相对完整、能在面试或技术评审中站得住脚的回答是:

A2A 是面向异构 AI Agent 的开放互操作协议。它通过Agent Card(能力发现)、Task(有状态任务生命周期)、Message / Part(多模态通信)、Artifact(交付物)四个核心抽象,配合JSON-RPC / REST / gRPC三种等价传输绑定,解决了不同厂商、不同框架 Agent 之间的发现、认证、委派、状态同步与结果交付问题。它与 MCP 互补而非竞争:MCP 管 Agent 调用工具(纵向),A2A 管 Agent 之间协作(横向)。

更本质地说,A2A 体现的是一种架构视角迁移:把 AI 系统从"单体能力"推向"智能体生态"——单个 Agent 是专家,协议让专家之间能像团队一样协作。这也是它被称为"Agent 世界的 HTTP"的原因。

但要记住客观边界:A2A 不是银弹。它解决的是"通信与协作的标准化",不解决模型能力、工具质量、业务正确性,也不替你处理所有分布式系统的复杂性。引入前请先问自己:你的场景是否真的存在跨框架/跨团队的 Agent 互操作需求?如果只是同一框架内的多 Agent 编排,框架自带机制往往更简单;只有当"异构协作"真实存在时,A2A 的标准化价值才会真正兑现。


参考资料

  • A2A 官方规范:https://a2a-protocol.org/latest/specification/
  • A2A 项目仓库:https://github.com/a2aproject/A2A
  • 腾讯云技术百科:A2A 协议架构与核心组件[citation:1]
  • A2A 中文社区规范翻译(TaskState、Message 等)[citation:10]
  • A2A vs MCP 精确对比与组合架构[citation:4][citation:8][citation:11]

延伸思考:如果你对"要不要自研一套 Agent 通信协议"还有犹豫,不妨把 A2A 的分层架构(Data Model → Operations → Bindings)当作评估模板——即便最终不用 A2A,这套"语义与传输解耦 + 自描述发现 + 有状态任务"的设计思想,也值得在你的系统里复用。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询