Skip to content

A2A(Agent2Agent Protocol)协议机制调研

调研日期:2026-07-29 证据来源:主要为一手来源,直接抓取 github.com/a2aproject/A2Adocs/specification.mdspecification/a2a.protoCHANGELOG.mddocs/whats-new-v1.mddocs/announcing-1.0.md,取自 main 分支,对应已发布 tag v1.0.1),而非二手博客总结。仅治理权移交 Linux Foundation 的具体日期/创始成员名单来自二手信源(Forbes、LF 新闻稿、Google Cloud 博客),已在下文标注。

⚠️ 重要提醒(写笔记/复用代码时务必注意):A2A 在 2026-03-12 发布了破坏性的 v1.0(2026-05-26 打了 patch 到 v1.0.1),把整个 JSON-RPC 方法命名和枚举大小写规则都改了。市面上大多数教程/博客(以及大模型预训练知识里的默认认知)描述的都是 v1.0 之前v0.3.0 及更早)的命名——message/sendtasks/get、小写的任务状态如 "submitted"。这套命名现在已经是 legacy,新代码/新笔记不要再用。

1. 定位:与 MCP 的关系

Spec 附录 B("Relationship to MCP")原文:

"MCP... Focuses on standardizing how AI models and agents connect to and interact with tools, APIs, data sources, and other external resources... Think of MCP as the 'how-to' for an agent to use a specific capability." "A2A... Focuses on standardizing how independent, often opaque, AI agents communicate and collaborate with each other as peers... It's about how agents partner or delegate work."

v1.0 发布公告重申:"MCP is commonly used for tool and context integration at the individual agent level. A2A focuses on communication and coordination between agents... many systems will use both: MCP inside agents, A2A between agents."

一句话总结:MCP 管 agent 怎么用工具/取数据,A2A 管 agent 之间怎么互相通信/委派任务,两者定位互补,不是竞争关系,实际系统里常常同时用(agent 内部用 MCP 接工具,agent 之间用 A2A 通信)。

2. 发现机制:Agent Card

服务在 well-known URI 上(RFC 8615 风格):https://{domain}/.well-known/agent-card.json。Spec §8.2 列了三种发现策略:well-known URI、策展型注册表(curated registries)、直接/静态配置。

AgentCard 关键字段(§4.4.1,示例见 §8.5):namedescriptionproviderAgentProvider)、iconUrlversiondocumentationUrlcapabilitiesstreamingpushNotificationsextendedAgentCard)、securitySchemessecurityRequirementsdefaultInputModes/defaultOutputModesskills[]AgentSkill:id/name/description/tags/examples/inputModes/outputModes)、supportedInterfaces[]AgentInterface:url + protocolBinding + protocolVersion——这个字段取代了旧版单一的 preferredTransport/additionalInterfaces),以及 v1.0 新增的可选 signatures[](对 Agent Card 做加密签名,JWS + RFC 8785 规范化)。

json
{
  "name": "GeoSpatial Route Planner Agent",
  "description": "Provides route planning, traffic analysis, custom maps.",
  "supportedInterfaces": [
    {"url": "https://georoute-agent.example.com/a2a/v1", "protocolBinding": "JSONRPC", "protocolVersion": "1.0"},
    {"url": "https://georoute-agent.example.com/a2a/grpc", "protocolBinding": "GRPC", "protocolVersion": "1.0"}
  ],
  "provider": {"organization": "Example Geo Services Inc.", "url": "https://www.examplegeoservices.com"},
  "version": "1.2.0",
  "capabilities": {"streaming": true, "pushNotifications": true, "extendedAgentCard": true},
  "securitySchemes": {"google": {"openIdConnectSecurityScheme": {"openIdConnectUrl": "https://accounts.google.com/.well-known/openid-configuration"}}},
  "securityRequirements": [{"schemes": {"google": {"list": ["openid", "profile", "email"]}}}],
  "skills": [{"id": "route-optimizer-traffic", "name": "Traffic-Aware Route Optimizer",
    "tags": ["maps","routing"], "inputModes": ["application/json"], "outputModes": ["application/json"]}]
}

(节选自官方 §8.5 示例卡片)

3. 传输与消息层

确认为 JSON-RPC 2.0 over HTTP(S)(§9.1),同时还有一手支持的 gRPC 绑定(§10)和 HTTP+JSON/REST 绑定(§11)——三者都映射到 §3 里定义的、传输无关的同一套底层操作。v1.0 的方法命名改成了匹配 gRPC 约定的 PascalCase(§9.1 原文:"Method Naming: PascalCase method names matching gRPC conventions"),是相对 v1.0 之前 slash 风格命名的一次刻意破坏性变更。

核心 JSON-RPC 方法(§9.4,已对照 a2a.proto 里的 A2AService 确认):SendMessageSendStreamingMessageGetTaskListTasksCancelTaskSubscribeToTaskCreateTaskPushNotificationConfigGetTaskPushNotificationConfigListTaskPushNotificationConfigsDeleteTaskPushNotificationConfigGetExtendedAgentCard

v1.0 之前的旧命名(仍会在旧文档/SDK 里看到,按 docs/whats-new-v1.md 的迁移表对照):message/sendSendMessagetasks/getGetTasktasks/cancelCancelTaskagent/getAuthenticatedExtendedCardGetExtendedAgentCard,等等。

REST 绑定用动词风格路径:POST /message:sendPOST /message:streamGET /tasks/{id}GET /tasksPOST /tasks/{id}:cancelGET/POST/DELETE /tasks/{id}/pushNotificationConfigs[/{configId}]GET /extendedAgentCard(v1.0 里去掉了 /v1 这个 URL 前缀)。SubscribeToTask 在 v1.0.1 发布物中有未解决的不一致:docs/specification.md 的操作映射和 §11.3.2 写 POST /tasks/{id}:subscribe,同一 tag 的 a2a.proto HTTP annotation 却写 GET。实现不能把其中一个说成无争议的唯一映射;生成式 client/server 往往跟随 proto,手写 REST 实现需确认对端,并关注上游勘误。

JSON-RPC binding 的 request/response Content-Typeapplication/json;HTTP+JSON/REST binding 使用 application/a2a+json;SSE 都使用 text/event-stream。v1.0 client 每次请求都必须声明 A2A-Version: 1.0(patch 版本不参与协商),扩展通过 A2A-Extensions 协商。这里的规范文本存在一处张力:通用版本章节 §3.6.1 允许 client 用 request parameter 代替 header,但 JSON-RPC/REST binding 的 §§9.2/11.2 又要求 service parameter 通过 HTTP header 传输;为保证互操作性,HTTP client 应始终发送 A2A-Version header。JSON-RPC、REST、gRPC 是等价 binding,但 wire format 并不相同:gRPC 流式使用 server-streaming RPC,不是 SSE。

4. 任务生命周期

Task 对象:idcontextIdstatusTaskStatus = 状态 + 可选 message/时间戳)、artifacts[]history[]metadata,并新增 createdAtlastModifiedListTasks 支持 contextId、status、更新时间等过滤与 pageToken/nextPageToken 游标分页;无论是否显式传过滤条件,server 都必须按调用者授权边界限制结果。

TaskState 枚举(已对照 a2a.proto 确认,SCREAMING_SNAKE_CASE 加 TASK_STATE_ 前缀——相对 v1.0 之前小写的 "submitted"/"working" 是一次为了符合 ProtoJSON 规范而做的变更,见 ADR-001):

TASK_STATE_UNSPECIFIEDTASK_STATE_SUBMITTEDTASK_STATE_WORKINGTASK_STATE_COMPLETEDTASK_STATE_FAILEDTASK_STATE_CANCELEDTASK_STATE_INPUT_REQUIREDTASK_STATE_REJECTEDTASK_STATE_AUTH_REQUIRED

其中 COMPLETED/FAILED/CANCELED/REJECTED 实质是终态;INPUT_REQUIRED/AUTH_REQUIRED 是被打断、等待 client 补充输入的中间态。长时间运行的任务可以靠 GetTask/ListTasks 轮询,也可以用下面的流式/推送方式消费。

5. 流式与异步

在 JSON-RPC/REST over HTTP binding 中,SendStreamingMessageSubscribeToTask 返回 SSE 流(text/event-stream);gRPC binding 使用 server streaming。事件统一映射为 StreamResponse,可包含初始 Task/MessageTaskStatusUpdateEventTaskArtifactUpdateEvent。task lifecycle stream 必须先返回当前 Task,并在终态关闭;message-only stream 恰好返回一个 Message 后关闭。这个能力受 AgentCard.capabilities.streaming 开关控制。如果任务已经是终态,SubscribeToTask 会报 UnsupportedOperationError

SSE 断线重连没有类似 Last-Event-ID 的可靠补发保证;spec 明确提醒重连后可能漏掉 status message,关键结果应从 Task/artifacts 重新读取,不能只依赖瞬时 stream message。

对于断线/长时间运行的场景,推送通知(webhook)通过 TaskPushNotificationConfig 系列方法配置,受 capabilities.pushNotifications 开关控制。§13.2 强制要求:webhook 调用方必须对自己的回调做鉴权、用超时(建议 10–30s)加退避重试、并对目标 URL 做 SSRF 校验(拒绝内网/回环地址段);接收方必须校验鉴权信息和 task ID,并以幂等方式响应 2xx。

6. 鉴权

按 scheme 声明在 AgentCard.securitySchemes 里(§4.5):APIKeySecuritySchemeHTTPAuthSecuritySchemeOAuth2SecuritySchemeOpenIdConnectSecuritySchemeMutualTlsSecurityScheme。v1.0 里的 OAuth2 flow 只保留 AuthorizationCodeOAuthFlowClientCredentialsOAuthFlowDeviceCodeOAuthFlow;implicit 和 password(ROPC)flow 被移除,authorization code flow 可声明 PKCE。Agent Card 只描述“如何取得凭证”,不替应用执行认证授权;server 仍必须在每个 operation 上校验身份、tenant、task/context 所有权和 scope。

7. 治理与版本历史

  • Google 在约 2025 年 4 月公开发布 A2A。
  • Google Cloud 在 2025-06-23 于 Open Source Summit North America 上把协议治理权移交给 Linux Foundation,成立了包含 AWS、Cisco、Google、IBM Research、Microsoft、Salesforce、SAP、ServiceNow 的技术指导委员会(TSC)。[secondary:这个具体日期和创始成员名单来自 Forbes/LF 新闻稿/Google Cloud 博客交叉印证,官方 spec 仓库本身没有找到带日期的移交公告原文,仅有 TSC 相关描述]
  • 仓库内版本历史:0.1.00.2.60.3.01.0.0(2026-03-12 发布,第一个稳定/破坏性版本)1.0.1(2026-05-26,bugfix:HTTP media type 和错误码修正)。截至 2026-07-29,最新已发布版本是 1.0.1

8. 安全相关面(仅列出,不展开分析——留给后续安全向调研)

  • Agent Card 伪造/MITM——签名校验目前是可选的(spec 里是 MAY 级别),在强制签名校验落地前存在冒充风险。
  • 未鉴权或权限范围不当的 ListTasks/GetTask,如果 §13.1 的授权范围控制实现有误,可能泄露跨租户的任务数据。
  • 推送通知 webhook 的 SSRF 风险——如果 agent 不按 §13.2 校验 webhook URL,可能被诱导对攻击者控制的/内网地址发起服务端请求。
  • Extended Agent Card 的访问控制绕过(§13.3)——把本应受限的技能/端点暴露给未鉴权调用方。
  • 通过任务委派链条产生的跨 agent 信任升级——不透明的执行模型意味着下游 agent 的异常行为对委派方是不可见的。
  • 任务劫持/任务 ID 猜测或跨上下文复用。
  • AgentSkill 元数据里的恶意或误导性技能广告(和提示注入相邻——技能描述会被 LLM planner 消费)。
  • 多租户隔离失效(新增的 tenant 路径段/scope 字段)导致共享同一端点的租户间数据泄露。
  • 降级攻击——利用 supportedInterfaces 里 v1.0/v0.3 双重声明,把 client 强行拉到较弱的旧版行为上。

引用清单

关联

  • 与 MCP 的定位区分见 mcp-protocol.md。两者都可在 HTTP 响应中使用 SSE,但都不能简化为“协议基于 SSE”:A2A 还有 gRPC/REST binding,MCP 的普通调用也可直接返回 JSON。可与 vendor-streaming-comparison.md 对照事件与断线语义。
  • 第 8 节安全面后续应与 [[agent-security]] track(尤其 multi-agent trust propagation 相关笔记)交叉链接展开分析,而不是在本文件里深入。