A2A 协议:Agent 与 Agent 的协作


文档摘要

A2A 协议:Agent 与 Agent 的协作 本节摘要:MCP 是「Agent 调工具」。A2A(Agent2Agent)是「Agent 调 Agent」——一个让基于不同框架构建的、互不透明的 Agent 互相协作的开放协议。2025 年 4 月由 Google 发布,2025 年 6 月捐给 Linux Foundation,2026 年 4 月达到 v1.0,获 AWS、Cisco、Microsoft、Salesforce、SAP、ServiceNow 等 150+ 方支持。它吸收了 IBM 的 ACP,并加入了 AP2 支付扩展。本节走通 Agent Card、Task 生命周期,以及两种传输绑定。

A2A 协议:Agent 与 Agent 的协作

本节摘要:MCP 是「Agent 调工具」。A2A(Agent2Agent)是「Agent 调 Agent」——一个让基于不同框架构建的、互不透明的 Agent 互相协作的开放协议。2025 年 4 月由 Google 发布,2025 年 6 月捐给 Linux Foundation,2026 年 4 月达到 v1.0,获 AWS、Cisco、Microsoft、Salesforce、SAP、ServiceNow 等 150+ 方支持。它吸收了 IBM 的 ACP,并加入了 AP2 支付扩展。本节走通 Agent Card、Task 生命周期,以及两种传输绑定。读完本节,你能区分 Agent 调工具(MCP)与 Agent 调 Agent(A2A),发布 Agent Card,走完 Task 生命周期,并用带 Parts 的 Message 与作为产出的 Artifact。

学习目标

阅读完本节,你应当能够:

  1. 区分 Agent 调工具(MCP)Agent 调 Agent(A2A) 的用例。
  2. /.well-known/agent.json 发布带 skills 与端点元数据的 Agent Card
  3. 走通 Task 生命周期(submitted → working → input-required → completed / failed / canceled / rejected)。
  4. 使用带 Parts(text、file、data)的 Message,以及作为产出的 Artifact

一、问题与直觉

一个客服 Agent 需要把「写报告」这件事委托给一个专门的写作 Agent。A2A 之前的选项:

  • 自定义 REST API:能用,但每对组合都是一次性方案。
  • 共享代码库:要求两个 Agent 跑同一框架。
  • MCP:不合适——MCP 是调工具的,不是让两个 Agent 在各自保持内部推理不透明的前提下协作的。

A2A 填这道缝。它把交互建模成一个 Agent 向另一个 Agent 发送一个 Task,带生命周期、消息与产出。被调 Agent 的内部状态保持不透明——调用方只看到 Task 状态转移与最终产出。

A2A 是「让跨框架的 Agent 互相对话」的协议。它不取代 MCP,两者互补。

时间线

  • 2025-04-09:Google 宣布 A2A。
  • 2025-06-23:捐给 Linux Foundation。
  • 2025-08:吸收 IBM 的 ACP。
  • 2025-09:AP2 扩展(Agent Payments)发布。
  • 2026-04:v1.0 发布,150+ 支持组织。

二、从零实现

Agent Card

每个 A2A 合规的 Agent 在 /.well-known/agent.json 发布一张卡片:

{ "schemaVersion": "1.0", "name": "research-agent", "description": "总结学术论文并起草引文。", "url": "https://research.example.com/a2a", "version": "1.2.0", "skills": [ { "id": "summarize_paper", "name": "Summarize a paper", "description": "读一篇论文 PDF,产出三段摘要。", "inputModes": ["text", "file"], "outputModes": ["text", "artifact"] } ], "capabilities": {"streaming": true, "pushNotifications": true} }

发现基于 URL:拉卡片,得知 A2A 端点 URL,枚举 skills。

签名 Agent Card(AP2)

AP2 扩展(2025 年 9 月)给 Agent Card 加密码学签名。发布者用自己的 JWT 签自己的卡片,消费方校验。防冒充。

Task 生命周期

submitted -> working -> completed | failed | canceled | rejected -> input_required -> working (经消息循环)

客户端用 tasks/send 发起。被调 Agent 在状态间转移,客户端经 SSE 订阅状态更新或轮询。

消息与 Parts

一条 Message 带一个或多个 Part:

  • text——纯内容。
  • file——base64 blob,带 mimeType。
  • data——类型化的 JSON 负载(被调 Agent 的结构化输入)。

示例:

{ "role": "user", "parts": [ {"type": "text", "text": "总结这篇论文。"}, {"type": "file", "file": {"name": "paper.pdf", "mimeType": "application/pdf", "bytes": "..."}}, {"type": "data", "data": {"targetLength": "3 paragraphs"}} ] }

Artifact

产出是 Artifact,不是裸字符串。Artifact 是命名的、类型化的产出:

{ "name": "summary", "parts": [{"type": "text", "text": "..."}], "mimeType": "text/markdown" }

Artifact 可以作为分块流式输出,调用方累积。

两种传输绑定

  1. HTTP 上的 JSON-RPC:/a2a 端点,请求用 POST,流式可选 SSE。默认绑定。
  2. gRPC:面向 gRPC 原生的企业环境。

两种绑定承载同样的逻辑消息形状。

不透明性保持

一条核心设计原则:被调 Agent 的内部状态是不透明的。调用方看到 Task 状态与 Artifact。被调 Agent 的思维链、它的工具调用、它的子 Agent 委托——全部不可见。这与 MCP 不同,后者的工具调用是透明的。

理由:A2A 让竞争对手在不暴露内部的前提下协作。「调这个客服 Agent」时,调用方无需知道那个 Agent 怎么实现客服。

与 MCP 的关系

维度 MCP A2A
用例 Agent 调工具 Agent 调 Agent
不透明度 工具调用透明 内部推理不透明
典型调用方 Agent 运行时 另一个 Agent
状态 工具调用结果 带生命周期的 Task
授权 OAuth 2.1(第 16 节) JWT 签名的 Agent Card(AP2)
传输 Stdio / Streamable HTTP HTTP 上的 JSON-RPC / gRPC

想调一个具体工具就用 MCP;想把一整件事委托给另一个 Agent 就用 A2A。许多生产系统两者都用:一个 Agent 用 MCP 做工具层,用 A2A 做协作层。

最小 Task 协调器骨架

def run_task(endpoint, message_parts): task = httpx.post(f"{endpoint}", json={ "jsonrpc": "2.0", "method": "tasks/send", "params": {"message": {"role": "user", "parts": message_parts}}}).json() while task["status"]["state"] not in ("completed", "failed", "canceled", "rejected"): if task["status"]["state"] == "input-required": ans = clarify(task) # 调用方/用户补信息 task = httpx.post(endpoint, json={"method": "tasks/send", "params": {"id": task["id"], "message": ans}}).json() else: task = httpx.post(endpoint, json={"method": "tasks/get", "params": {"id": task["id"]}}).json() return task["artifacts"]

设计要点:A2A 的精髓是「生命周期 + 不透明产出」。调用方只关心 Task 走到哪了、产出是什么;被调方怎么推理、调了哪些工具,一概不可见。这种边界让互不信任的双方也能协作。

三、框架对比

维度 MCP A2A 自定义 REST
调用对象 工具 Agent 任意
不透明度 透明 不透明 视实现
标准化 强(MCP 规范) 强(A2A v1.0)
生命周期 无(即时返回) 有(submitted→completed) 视实现
跨框架
流式 支持 SSE / gRPC 流 视实现

💡 心法:别把 A2A 当成「另一个 MCP」。MCP 的工具是透明的原子动作;A2A 的 Task 是不透明的整件事。判断标准很简单:这件事要不要一个会思考、会用工具的 Agent 来完成?要就 A2A,不要就 MCP。

四、可复用产物

本节产出 outputs/skill-a2a-agent-spec.md——给定一个应能被其他 Agent 调用的新 Agent,这个 skill 产出 Agent Card JSON、skills schema 与端点蓝图。

code/main.py 实现一个最小 A2A 测试具:一个 research Agent 发布它的卡片,一个 writer Agent 收到一个 tasks/send,带含 PDF 与文本指令的 parts,经 working → input_required → working → completed 转移,返回一个文本 Artifact。全 stdlib,用内存传输聚焦消息形状。可重点看:Agent Card JSON 形状、Task id 分配与状态转移、混合类型 parts 的消息、Task 中途的 input-required 分支、完成时的 Artifact 返回。

五、练习

  1. 追踪生命周期:运行 code/main.py,追踪完整 Task 生命周期,包括被调 Agent 请求澄清时的 input-required 暂停。

  2. 加签名卡片:用 HMAC 对卡片的规范 JSON 签名,写一个校验器,确认它对被篡改的卡片失败。

  3. Task 流式:让 writer Agent 经 SSE 发出三个增量 Artifact 分块,调用方累积。

  4. 包 MCP 服务端:设计一个 A2A Agent 包裹一个 MCP 服务端,把每个 MCP 工具映射成一个 A2A skill。留意代价——丢了什么不透明度?

  5. 读 v1.0 公告:读 A2A v1.0 公告,找出截至 2026 年 4 月尚无任何框架实现的那一个特性(提示:与多跳 Task 委托有关)。

本节要点回顾

  1. MCP 是 Agent 调工具,A2A 是 Agent 调 Agent:两者互补,不是替代。
  2. Agent Card 在 /.well-known/agent.json:URL 发现,枚举 skills 与端点;AP2 用 JWT 签名防冒充。
  3. Task 有生命周期:submitted → working → completed/failed/canceled/rejected,中间可经 input-required 循环。
  4. Message 带 Parts:text、file、data 三种,一条消息可混合。
  5. 产出是 Artifact:命名、类型化,可分块流式。
  6. 两种传输:HTTP 上的 JSON-RPC(默认,可选 SSE)、gRPC(企业)。
  7. 不透明性是核心:被调方的思维链、工具调用、子 Agent 委托对调用方全不可见。
  8. 时间线:2025-04 Google 发布 → 2025-06 入 Linux Foundation → 2026-04 v1.0,150+ 支持。

下一节,我们看怎么把这些跨进程的调用串成一条 trace——OpenTelemetry GenAI 语义约定,以及 LLM / 工具 / MCP / Agent 的 span 层次。


发布者: 作者: Rohit Gupta 转发
评论区 (0)
U