一次讲清 A2A 协议与 MCP 边界:从 Agent Card 到 Task 生命周期

一次讲清 A2A 协议与 MCP 边界:从 Agent Card 到 Task 生命周期

**文章摘要:**A2A 和 MCP 分别解决什么问题?本文以 A2A v1.0 为基线,从调度 Agent 调用天气 Agent 的完整链路出发,讲清 Agent Card 发现机制、Message 与 Part、Task 生命周期、Artifact 交付、各种 ID、JSON-RPC、gRPC、HTTP+JSON 三种绑定,以及轮询、流式与 Webhook 更新方式;同时对比 A2A 与 MCP 的职责边界,补充安全要求、旧版迁移陷阱和生产落地检查清单。

当一个 Agent 同时连接天气、机票、酒店、支付等能力时,我们很容易产生一个疑问:这些能力究竟应该作为工具接入,还是应该拆成能够自主协作的专业 Agent?

这正是 MCP 与 A2A 的分界线:

text 复制代码
Agent 调用工具、资源和 API → MCP
Agent 委派目标给另一个 Agent → A2A

两者不是竞争关系。一个常见架构是:调度 Agent 通过 A2A 把目标委派给天气 Agent,天气 Agent 再通过 MCP 使用天气 API 或数据库。

本文以截至 2026 年 8 月 21 日的 A2A 正式规范 1.0.0 为基线。需要特别注意:规范发布版本写作 1.0.0 ,但请求头和 Agent Card 中用于协议协商的版本是 1.0

一、A2A 到底解决什么问题

A2A 全称 Agent2Agent Protocol,是面向独立 Agent 系统的互操作协议。

它关注的是:两个可能由不同团队、不同框架和不同厂商实现的 Agent,怎样在不了解对方内部模型、Prompt、Memory 和工具的前提下完成协作。

A2A 提供五类核心能力:

  1. 能力发现:远程 Agent 是谁、会什么、在哪里调用;
  2. 消息交换:传递文本、文件、二进制和结构化数据;
  3. 任务跟踪:管理长任务和多轮交互的生命周期;
  4. 结果交付:用结构化 Artifact 交付正式产物;
  5. 异步更新:支持轮询、流式连接和 Webhook 推送。

最容易记住的心智模型是:

text 复制代码
Agent Card 负责认识对方
Message 负责交流
Task 负责跟踪工作
Artifact 负责交付结果

A2A 不负责定义 Agent 内部如何推理,也不是 LangGraph、CrewAI、ADK 一类 Agent 开发框架。它只规定跨系统边界时的公共语言。

二、一个最直观的协作场景

假设用户提出目标:

找出未来三天西雅图天气最好的一天,再查询那一天飞往纽约的机票。

系统可以拆成三个角色:

text 复制代码
用户
  ↓
调度 Agent:理解目标、拆分任务、汇总结果
  ├─ A2A → 天气 Agent
  │            └─ MCP → 天气 API
  └─ A2A → 机票 Agent
               └─ MCP → 航班系统

这里的关键不是"远程服务也能返回天气",而是天气 Agent 可以自主理解天气目标、选择数据源、进行多步处理、要求补充地点或日期,并以可跟踪任务的形式交付结果。

如果只需要调用一个参数明确的天气查询函数,那么 MCP Tool 往往已经足够;如果委派的是一个需要自主规划和多轮协作的目标,A2A 更合适。

三、理解 A2A v1.0 的三层结构

A2A 不能简单理解成"某种 JSON-RPC API"。v1.0 可以分成三层:

层次 解决的问题 典型内容
Canonical Data Model 双方交换什么对象 Agent Card、Message、Part、Task、Artifact
Abstract Operations 可以执行哪些动作 SendMessage、GetTask、CancelTask
Protocol Bindings 动作怎样映射到网络 JSON-RPC、gRPC、HTTP+JSON

三层关系如下:

text 复制代码
A2A 领域语义
  ├─ 数据模型:Message、Task、Artifact......
  └─ 抽象操作:SendMessage、GetTask......
                   ↓ 选择一种 Binding
       JSON-RPC / gRPC / HTTP+JSON
                   ↓
              网络与安全机制

也就是说,JSON-RPC 只是一种绑定方式,不等于 A2A 本身。

四、第一步:怎样发现另一个 Agent

"发现 Agent"其实包含两个不同阶段。

1. 先找到候选 Agent

调度 Agent 首先要知道可能存在哪些 Agent。常见来源有:

  • 配置文件或环境变量;
  • 企业内部服务目录;
  • 平台私有 API;
  • Curated Registry,即受治理的 Agent 注册中心;
  • 已知的公开域名。

A2A v1.0 没有规定一个全球统一的"搜索全部 Agent"接口,也没有规定 Registry 必须使用什么注册和查询 API。

2. 再读取 Agent Card

已经知道某个候选域名后,Client 可以访问标准地址:

text 复制代码
https://{agent-server-domain}/.well-known/agent-card.json

注意,这个地址只能回答"该域名上的 Agent 是谁、会什么",不能自动扫描网络找到所有 Agent。

3. Agent Card 包含什么

Agent Card 可以理解成 Agent 的"能力说明书 + 接入说明书"。一个简化示例如下:

json 复制代码
{
  "name": "Weather Agent",
  "description": "查询指定城市的未来天气",
  "supportedInterfaces": [
    {
      "url": "https://weather.example.com/a2a",
      "protocolBinding": "HTTP+JSON",
      "protocolVersion": "1.0"
    }
  ],
  "version": "2.3.0",
  "capabilities": {
    "streaming": true,
    "pushNotifications": false
  },
  "defaultInputModes": ["text/plain"],
  "defaultOutputModes": ["text/plain", "application/json"],
  "skills": [
    {
      "id": "weather-forecast",
      "name": "天气预报",
      "description": "查询城市未来七天的天气",
      "tags": ["weather", "forecast"]
    }
  ]
}

阅读 Agent Card 时,重点检查:

字段 需要回答的问题
supportedInterfaces[] 调用地址、Binding 和协议版本是什么
skills[] Agent 具体能完成哪些任务
capabilities 是否支持流式、Push 等能力
输入输出模式 支持哪些 Media Type
安全要求 使用 OAuth、API Key、mTLS 还是其他方案
version Agent 自身版本,不是 A2A 协议版本

一个 Agent 可以声明多种 Binding。supportedInterfaces[] 按偏好排序,Client 选择自己支持的第一项。

五、第二步:用 Message 发送请求

选定接口后,Client 调用抽象操作 SendMessage

如果选择 HTTP+JSON Binding,请求可以写成:

http 复制代码
POST /message:send HTTP/1.1
Host: weather.example.com
Content-Type: application/a2a+json
A2A-Version: 1.0
Authorization: Bearer <token>

{
  "message": {
    "messageId": "msg-001",
    "role": "ROLE_USER",
    "parts": [
      {
        "text": "查询西雅图未来三天的天气",
        "mediaType": "text/plain"
      }
    ]
  },
  "configuration": {
    "acceptedOutputModes": ["application/json"],
    "returnImmediately": false
  }
}

如果选择 JSON-RPC Binding,A2A 领域对象基本不变,只是外面套上 JSON-RPC 信封:

json 复制代码
{
  "jsonrpc": "2.0",
  "id": "rpc-001",
  "method": "SendMessage",
  "params": {
    "message": {
      "messageId": "msg-001",
      "role": "ROLE_USER",
      "parts": [
        {"text": "查询西雅图未来三天的天气"}
      ]
    }
  }
}

两份请求表达的是同一个 A2A 操作。一次调用只会选择其中一种 Binding,不会同时发送两份请求。

六、Part:消息和产物的最小内容单元

Part 可以出现在 Message 或 Artifact 中。每个 Part 必须且只能包含以下四种内容字段之一:

字段 用途
text 文本内容
raw 内联二进制,JSON 中使用 Base64
url 文件或内容地址
data 任意 JSON 结构化数据

例如:

json 复制代码
{"text": "天气晴朗", "mediaType": "text/plain"}
json 复制代码
{"data": {"highC": 24, "condition": "sunny"}, "mediaType": "application/json"}
json 复制代码
{
  "url": "https://example.com/report.pdf",
  "filename": "report.pdf",
  "mediaType": "application/pdf"
}

filenamemediaTypemetadata 是辅助字段,不是新的内容类型。

七、Message、Task 与 Artifact 有什么区别

SendMessage 的响应不一定是 Task,也可以直接是 Message。

对象 适用场景
Message 简单回复、补充信息、澄清问题和状态说明
Task 需要状态、历史、追加输入、取消或异步更新的工作
Artifact Task 的正式交付物,如报告、文件或结构化结果

可以把一次有状态工作理解成:

text 复制代码
Message:请查询天气
    ↓
Task:正在查询,需要跟踪
    ↓
Message:请补充城市
    ↓
Task:继续执行
    ↓
Artifact:正式天气结果

一个已完成的 Task 可以是:

json 复制代码
{
  "task": {
    "id": "task-001",
    "contextId": "ctx-001",
    "status": {
      "state": "TASK_STATE_COMPLETED"
    },
    "artifacts": [
      {
        "artifactId": "forecast-001",
        "name": "未来三天天气",
        "parts": [
          {
            "data": {
              "city": "Seattle",
              "condition": "sunny",
              "highC": 24
            },
            "mediaType": "application/json"
          }
        ]
      }
    ]
  }
}

正式任务结果应该进入 Artifact,而不是只藏在一条状态 Message 中。

八、四种 ID 不要混淆

ID 作用 通常由谁创建
JSON-RPC id 关联一次 RPC 请求和响应 RPC 调用方
messageId 唯一标识一条 Message Message 创建方
Task id 标识一个有状态工作单元 A2A Server
contextId 把相关 Message 和 Task 归入同一交互上下文 通常由 Agent 生成
artifactId 标识 Task 中的某个交付物 Artifact 创建方

第一次请求通常省略 taskIdcontextId。服务端返回后,Client 保存这些不透明标识,并在后续交互中复用。

如果 Task 尚未结束且需要补充信息,可以同时携带 taskIdcontextId;如果一个新 Task 要引用旧 Task,可以使用 referenceTaskIds

九、Task 生命周期

Task 状态可以分成三组:

text 复制代码
处理中
  TASK_STATE_SUBMITTED
  TASK_STATE_WORKING

暂停但可以继续
  TASK_STATE_INPUT_REQUIRED
  TASK_STATE_AUTH_REQUIRED

终态
  TASK_STATE_COMPLETED
  TASK_STATE_FAILED
  TASK_STATE_CANCELED
  TASK_STATE_REJECTED

典型状态流转为:

text 复制代码
SUBMITTED → WORKING → COMPLETED
                ├→ INPUT_REQUIRED → WORKING
                ├→ AUTH_REQUIRED  → WORKING
                ├→ FAILED
                └→ CANCELED

进入 INPUT_REQUIRED 后,Client 可以补充消息继续执行;进入终态后,该 Task 不再接受新消息。如果还要修改或扩展结果,应创建新 Task,并保留必要的上下文或旧任务引用。

十、长任务怎样获取进度

A2A 提供三种互补机制:

机制 工作方式 适用场景
Polling Client 定期调用 GetTask 简单集成、更新不频繁
Streaming 通过 SSE 或对应 Binding 持续接收事件 交互式 UI、实时进度、增量产物
Push Notification Server 主动请求 Client 的 Webhook 超长任务、离线通知、不保持长连接

SendMessageConfiguration.returnImmediately 决定普通发送是否立即返回:

  • false 或不填:等待到 Task 进入终态或暂停态;
  • true:先返回已创建的 Task,再用轮询、流式或 Push 跟踪。

使用流式能力前,需要确认 Agent Card 的 capabilities.streamingtrue。网络断开后,还可以对未终止 Task 使用 SubscribeToTask 重新订阅。

Push Notification 不能只关注"能否回调成功",还必须防止 SSRF、伪造通知、重复投递和重放攻击。

十一、JSON-RPC 与 A2A 的边界

最简单的理解是:

JSON-RPC 规定远程方法怎样封装,A2A 规定 Agent 之间有哪些对象、操作和任务语义。

JSON-RPC 只认识 methodparamsidresulterror。它并不知道什么是 Agent、Task、Artifact 或任务生命周期。

A2A 则定义:

  • SendMessageGetTaskCancelTask 等抽象操作;
  • Agent Card、Message、Part、Task、Artifact 等领域对象;
  • 状态、多轮上下文、异步更新和错误语义;
  • 上述操作怎样映射到 JSON-RPC、gRPC 和 HTTP+JSON。

可以类比为:JSON-RPC 是信封格式,A2A 是信里的业务表单和办理规则。

十二、A2A 与 MCP 的核心边界

维度 A2A MCP
主要交互对象 独立 Agent 或 Agent 系统 Tool、Resource、Prompt 等能力
任务粒度 委派一个目标 调用明确能力或读取资源
自主程度 Remote Agent 可自行规划、调用工具 Client 选择具体 Primitive
状态特点 支持长任务、多轮、状态和异步更新 通常是边界清晰的请求与结果
能力发现 Agent Card 与 Skills Tools、Resources、Prompts 列表与 Schema
正式交付 Task 与 Artifact Primitive 的调用结果
内部实现 Remote Agent 保持不透明 Client 明确知道 Server 暴露的能力

做选型时可以问三个问题:

1. 调用方是在指定"步骤"还是委派"目标"

  • "执行 get_weather(city)"更像 MCP Tool;
  • "比较未来三天天气并选出最适合出行的一天"更像 A2A Task。

2. 被调用方是否需要自主规划

如果被调用方只执行一个明确函数,不必包装成 Agent;如果它需要自主拆解、选择工具、处理中断并交付结果,更适合暴露 A2A。

3. 是否需要跨团队、跨框架或跨信任边界

同一进程内的简单子 Agent 未必需要 A2A。A2A 更适合独立部署、内部实现不透明、需要稳定协议边界的 Agent 系统。

最常见的组合是:

text 复制代码
调度 Agent
  └─ A2A → 天气 Agent
                ├─ MCP Tool → 天气 API
                └─ MCP Resource → 历史天气数据

十三、生产环境必须补齐的安全能力

A2A 面向跨 Agent、跨系统甚至跨组织协作,安全不能只依赖 Prompt。

至少应做到:

  1. 使用 HTTPS,并验证服务端身份;
  2. 从 Agent Card 读取认证要求,通过带外流程获得凭据;
  3. 凭据放在 Header 或 Binding Metadata 中,不塞进 Message 文本;
  4. 按调用者、用户、Skill、Task、数据和具体业务动作授权;
  5. Task 查询和列表只返回当前身份有权访问的内容;
  6. 对输入、输出和日志执行数据最小化;
  7. 为高风险业务动作增加人工确认、幂等和审计;
  8. 公共 Agent Card 不暴露密钥和敏感内部能力;
  9. 必要时使用认证后的 Extended Agent Card;
  10. 对 Agent Card 做缓存、刷新,并在提供签名时验证 JWS。

Remote Agent 内部"不透明",只表示实现封装,并不意味着它天然可信或安全。

十四、旧教程最容易踩的版本坑

A2A 在 v1.0 前经历过明显变化。阅读旧视频和旧文章时,重点检查:

旧写法 v1.0 写法
/.well-known/agent.json /.well-known/agent-card.json
把 A2A 等同于 JSON-RPC JSON-RPC 只是标准 Binding 之一
message/send JSON-RPC 操作名 SendMessage
message/stream SendStreamingMessage
kind 区分对象 v1.0 由成员字段区分
role: "user" role: "ROLE_USER"
state: "completed" TASK_STATE_COMPLETED
文件放进嵌套 file 对象 Part 使用 rawurl 等内容字段
Agent Card 只有顶层 url 使用有序的 supportedInterfaces[]
每次请求都返回 Task 简单交互也可以直接返回 Message

如果要做真实实现,应固定规范版本,并以正式 Specification 和规范性 Proto 定义为准,不要直接照搬早期 Demo。

十五、生产落地检查清单

发现与兼容性

  • 候选 Agent 来自可信配置或受治理的 Registry;
  • 正确读取 /.well-known/agent-card.json
  • 检查 Skill、Binding、协议版本和输入输出模式;
  • Agent Card 支持缓存与刷新;
  • 不把 Agent 自身版本和 A2A 协议版本混为一谈。

消息与任务

  • 为每条 Message 生成唯一 messageId
  • 正确区分直接 Message 与可跟踪 Task;
  • 保存并复用服务端返回的 taskIdcontextId
  • Task 正式结果进入 Artifact;
  • 正确处理 INPUT_REQUIREDAUTH_REQUIRED 和各种终态。

异步与可靠性

  • 根据任务时长选择等待、Polling、Streaming 或 Push;
  • 流式断开后能够恢复订阅或查询 Task;
  • Webhook 防止 SSRF、伪造、重放和重复处理;
  • 取消、超时和重试具备明确语义;
  • 记录 Message、Task、Context 和 Artifact 的关联关系。

安全与治理

  • 认证凭据不进入 Message 正文;
  • 每个 Skill 和业务动作都经过授权;
  • 高风险动作具备人工确认和审计记录;
  • 不在公共 Agent Card 暴露敏感信息;
  • 跨 Agent 传输遵循数据最小化原则。

十六、面试版回答

如果面试中被问到 A2A 与 MCP 的区别,可以这样回答:

MCP 主要解决 Agent 如何连接工具、资源和 Prompt 等外部能力,交互通常边界明确;A2A 主要解决独立 Agent 系统之间如何发现能力、委派目标、跟踪有状态任务并交付结果。A2A 的核心对象包括 Agent Card、Message、Task 和 Artifact,一个 Agent 常常对外使用 A2A 协作,对内使用 MCP 调用工具。因此二者是互补关系,不是替代关系。

总结

A2A v1.0 的主线可以压缩成一条完整链路:

text 复制代码
配置或 Registry 找到候选 Agent
              ↓
Agent Card 确认能力、接口与认证
              ↓
SendMessage 发送 Message 与 Part
              ↓
简单请求直接返回 Message
复杂工作创建 Task 并跟踪生命周期
              ↓
通过 Polling、Streaming 或 Push 获取更新
              ↓
最终用 Artifact 交付正式结果

而 A2A 与 MCP 的边界可以记成一句话:MCP 让 Agent 使用能力,A2A 让 Agent 与另一个 Agent 协作完成目标。

如果这篇文章帮你理清了 A2A、MCP、Agent Card 和 Task 生命周期这些容易混淆的概念,别忘了点个赞、收藏一下,方便以后设计多 Agent 系统时随时回来查。如果还有没看懂的地方,或者你想看 A2A Python Demo、A2A 与 MCP 组合架构等实战内容,欢迎在评论区告诉我。后续还会继续分享 Agent、MCP、多智能体协作和后端工程相关内容,感兴趣的话点个关注,我们下一篇见!

参考资料

  1. 原始学习笔记:\[20_Workspaces/20_Portfolio/Agent/notes/A2A/A2A协议与MCP边界总览\|A2A 协议学习总览(v1.0)]
  2. A2A Protocol 官方网站
  3. A2A Protocol Specification 1.0.0
  4. What's New in A2A Protocol v1.0
  5. A2A Core Concepts
  6. Agent Discovery
  7. Life of a Task
  8. Streaming and Asynchronous Operations
  9. A2A and MCP
  10. A2A Enterprise Features
相关推荐
阿祖zu10 小时前
训练师 Agent 小程序产品上线啦
微信小程序·llm·agent
slacker-kian10 小时前
[实践]-本地大模型Agent使用自定义MCP服务实现与SAP系统集成(二)
ai·llm·sap·agent·mcp·odata·qwen-agent
樊小肆11 小时前
离谱,每轮请求 25% 的 token,竟在重发模型想完就扔的内心独白
前端·人工智能·agent
七牛开发者12 小时前
告别反复调参,一个 Skill 让 AI 掌握论文图的视觉语法:以 DeepSeek V4.1 Flash 论文图为例
github·agent·deepseek
阿里云大数据AI技术12 小时前
DataWorks Data Agent 实战课堂(八):数据质量巡检服务
人工智能·agent
酒旅Agent开发实战12 小时前
酒店供应链MCP实践分享
人工智能·大模型·酒店预订·ai agent·mcp
Yanjun2i13 小时前
Agent学习记录四:多工具时如何处理
人工智能·python·学习·agent
DigitalOcean14 小时前
Omarchy 将研发基础设施迁移至 DigitalOcean 云平台
linux·agent