一次讲清 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
相关推荐
安逸sgr2 小时前
AI 应用怎么评测?离线评测、人工评估和线上反馈如何结合?
人工智能·ai·大模型·agent·智能体
demo007x3 小时前
DSH harness 中的上下文管理探秘
程序员·agent·deepseek
xrlfreedom4 小时前
大厂 MCP 面试实录:本地 Server 远程化改造中的技术选型与落地实践
docker·json schema·mcp
MicrosoftReactor5 小时前
技术速递|GitHub Copilot App 入门指南:管理你的工作
ai·github·copilot·agent
七夜zippoe5 小时前
OpenClaw 边缘部署实战:IoT 场景下的轻量级 Agent 集群与离线自治
agent·集群·lot·轻量级·边缘部署·openclaw
不叫猫先生6 小时前
2026 Web Scraping 实战:页面改 class 就归零?用 Bright Data 搭稳定的 Agent 爬虫
爬虫·agent
Flynt6 小时前
DeepSeek终于能看图了:V4 Flash Vision实测,1分钱9张图但有个大坑
agent·ai编程·deepseek
闲猫6 小时前
LangGraph / Capabilities / Stores
python·agent·langgraph
天涯明月19936 小时前
AI Agent应用深度研究报告
人工智能·大模型·agent