A2A 协议深度解析:让所有 AI Agent 说同一种语言

A2A 协议深度解析:让所有 AI Agent 说同一种语言

导语

假设你是一家企业的 IT 负责人,公司内部同时使用了三套 AI Agent 系统:HR 部门用 Google ADK 构建的招聘 Agent,销售部门用 LangChain 打造的客户跟进 Agent,财务部门用 CrewAI 搭建的报销审批 Agent。

一个新员工入职,需要同时触发三个流程:HR Agent 完成背调 → 销售 Agent 分配客户资源 → 财务 Agent 开通报销权限。但三个 Agent 分属不同框架、不同团队开发、甚至部署在不同的云上------它们之间完全无法对话。

这就是 A2A 协议要解决的问题。

2025 年 4 月,Google 在 Cloud Next 大会上开源发布了 A2A(Agent-to-Agent Protocol),并贡献给 Linux Foundation。这是一个让不同框架、不同厂商、不同部署环境的 AI Agent 能够相互发现、通信和协作的开放协议。目前已获得 Atlassian、Salesforce、SAP 等 50+ 家企业的支持。

本文是系列第二篇,将深入 A2A 的技术内核。

官方文档:a2a-protocol.org GitHub:github.com/a2aproject/... 协议规范:a2a-protocol.org/latest/spec...


一、设计目标与核心原则

1.1 A2A 要解决什么问题?

一句话:让"不透明"的 Agent 之间也能协作。

什么叫"不透明"?就是你不知道对方 Agent 内部用了什么模型、什么工具、什么逻辑------你只知道它对外暴露了一组能力。这在企业场景中是常态:Salesforce 不会把自己 CRM Agent 的内部实现公开给你,但你的 Agent 需要和它协作。

A2A 的设计目标是在不暴露内部状态的前提下,实现 Agent 之间的:

  • 发现:找到合适的 Agent
  • 协商:确认对方能做什么、需要什么输入
  • 执行:委派任务并跟踪进度
  • 交付:获取结果

1.2 五大设计原则

原则 含义 实际意义
Agent 即 Agent 远程 Agent 是独立的智能体,不是被调用的工具 支持多轮对话、长时任务、主动反馈,而非简单的 request-response
基于标准构建 使用 HTTP、JSON-RPC、SSE 等已有标准 开发者无需学习新的传输协议,降低接入门槛
默认安全 企业级认证和授权 支持 OAuth 2.0、API Key、OpenID Connect 等主流认证方案
支持长时任务 处理持续数小时甚至数天的任务 通过 SSE 和推送通知实时同步进度
支持多模态 不限于文本 支持文本、图片、音频、视频、结构化数据、文件等

二、核心概念:Agent Card

2.1 Agent Card 是什么?

Agent Card 是 Agent 的"名片"------一个 JSON 格式的自描述清单,声明了 Agent 的身份、能力、技能和交互要求。

每个 Agent 在一个标准路径下托管自己的 Agent Card:

arduino 复制代码
https://example.com/.well-known/agent-card.json

其他 Agent 通过访问这个 URL,就能了解该 Agent 能做什么、怎么调用、需要什么认证。

2.2 Agent Card 结构解析

一个完整的 Agent Card 包含以下核心模块:

graph TB AC["Agent Card"] AC --> ID["基础信息
name / description / version / provider"] AC --> IF["接口声明
supportedInterfaces
(URL、协议绑定、版本)"] AC --> CAP["能力声明
capabilities
(streaming / pushNotifications)"] AC --> SK["技能列表
skills[]
(id / name / description / tags / examples)"] AC --> IO["输入输出模态
defaultInputModes / defaultOutputModes
(text/plain, application/json, image/png...)"] AC --> SEC["安全要求
securitySchemes / security
(OAuth2, API Key, OpenID Connect...)"] AC --> SIG["签名验证
signatures[]
(JWS 签名,验证来源和完整性)"] style AC fill:#fff,stroke:#333,stroke-width:2px,color:#333 style ID fill:#fff,stroke:#333,stroke-width:1px,color:#333 style IF fill:#fff,stroke:#333,stroke-width:1px,color:#333 style CAP fill:#fff,stroke:#333,stroke-width:1px,color:#333 style SK fill:#fff,stroke:#333,stroke-width:1px,color:#333 style IO fill:#fff,stroke:#333,stroke-width:1px,color:#333 style SEC fill:#fff,stroke:#333,stroke-width:1px,color:#333 style SIG fill:#fff,stroke:#333,stroke-width:1px,color:#333

一个简化的 Agent Card 示例:

json 复制代码
{
  "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": ["搜索明天北京到上海的航班"]
    },
    {
      "id": "hotel-booking",
      "name": "酒店预订",
      "description": "根据位置、日期、预算搜索和预订酒店",
      "tags": ["travel", "hotel"],
      "examples": ["预订陆家嘴附近明天入住的酒店,预算500以内"]
    }
  ],
  "securitySchemes": {
    "oauth2": {
      "type": "oauth2",
      "flows": {
        "clientCredentials": {
          "tokenUrl": "https://auth.travelcorp.com/token",
          "scopes": {
            "search": "搜索航班和酒店",
            "book": "完成预订"
          }
        }
      }
    }
  },
  "security": [{ "oauth2": ["search", "book"] }]
}

2.3 Agent Card 的发现机制

Agent Card 的发现遵循"Well-Known URI"约定(类似 robots.txt):

  1. 静态发现 :客户端直接访问 /.well-known/agent-card.json
  2. 扩展发现 :通过 GetExtendedAgentCard 方法获取认证后的完整能力描述(部分能力可能仅对已认证客户端可见)
  3. 注册发现:Agent Card 可以注册到目录服务中,供其他 Agent 搜索和匹配

关键设计:Agent Card 支持 JWS 签名。 客户端可以验证 Agent Card 的完整性和来源,防止中间人篡改------这在企业场景中至关重要。


三、核心概念:Task 生命周期

3.1 Task 是什么?

Task 是 A2A 中的核心工作单元。 当一个 Agent 请求另一个 Agent 做事时,就创建了一个 Task。Task 有完整的生命周期管理,支持状态追踪、中断恢复和取消。

3.2 Task 状态机

A2A 定义了 9 种 Task 状态,形成一个清晰的状态机:

stateDiagram-v2 [*] --> SUBMITTED : SendMessage SUBMITTED --> WORKING : Agent 开始处理 WORKING --> COMPLETED : 任务完成 WORKING --> FAILED : 执行失败 WORKING --> CANCELED : 被取消 WORKING --> INPUT_REQUIRED : 需要更多输入 WORKING --> AUTH_REQUIRED : 需要认证 INPUT_REQUIRED --> WORKING : 用户提供输入 AUTH_REQUIRED --> WORKING : 完成认证 SUBMITTED --> REJECTED : Agent 拒绝任务 COMPLETED --> [*] FAILED --> [*] CANCELED --> [*] REJECTED --> [*]
状态 含义 类型
SUBMITTED 任务已提交,等待处理 初始状态
WORKING Agent 正在处理 进行中
INPUT_REQUIRED 需要用户提供更多信息 中断状态
AUTH_REQUIRED 需要额外的认证授权 中断状态
COMPLETED 任务成功完成 终止状态
FAILED 任务执行失败 终止状态
CANCELED 任务被取消 终止状态
REJECTED Agent 拒绝执行该任务 终止状态

关键设计点:

  1. 中断与恢复INPUT_REQUIREDAUTH_REQUIRED 是"中断状态"------Agent 暂停执行,等待客户端提供信息后继续。这支持多轮交互场景。

  2. 拒绝权 :Agent 可以 REJECTED 一个任务。这体现了 A2A "Agent 即 Agent"的设计哲学------远程 Agent 不是工具,它有权评估并拒绝不合适的任务。

3.3 Task 与 Message、Artifact 的关系

A2A 中有三种核心数据对象,它们的关系如下:

yaml 复制代码
Task(任务)
├── Message(消息):客户端与 Agent 之间的对话交互
│   └── Part(部分):消息中的最小内容单元
│       ├── text: 文本内容
│       ├── data: 结构化 JSON 数据
│       ├── raw: 二进制文件(Base64 编码)
│       └── url: 文件链接
└── Artifact(产物):任务生成的最终输出
    └── Part(部分):产物内容,结构同 Message 中的 Part

Message vs Artifact 的区别:

维度 Message Artifact
用途 交互过程中的对话 任务的最终产出
角色 有发送方角色(USER 或 AGENT) 无角色概念
生成时机 任务执行过程中 任务完成时
示例 "请问您的预算是多少?" 生成的旅行方案 PDF

四、通信机制:JSON-RPC + SSE + 推送

4.1 三种交互模式

A2A 支持三种交互模式,覆盖从简单到复杂的所有场景:

sequenceDiagram participant C as Client Agent participant S as Remote Agent Note over C,S: 模式1:同步请求/响应 C->>S: SendMessage (JSON-RPC over HTTP) S-->>C: Task 结果 Note over C,S: 模式2:流式传输 (SSE) C->>S: SendStreamingMessage S-->>C: SSE: Task 状态更新 S-->>C: SSE: 部分结果(流式) S-->>C: SSE: 最终结果 Note over C,S: 模式3:异步推送通知 C->>S: SendMessage + PushNotificationConfig S-->>C: Task ID(立即返回) Note over S: Agent 长时间处理... S->>C: Webhook 推送:任务完成通知
模式 适用场景 技术实现
同步 简单查询、快速任务 HTTP POST + JSON-RPC
流式 生成式 AI 输出、实时进度 SSE(Server-Sent Events)
异步推送 长时间运行任务(小时/天级别) Webhook 回调

4.2 JSON-RPC 方法详解

A2A 基于 JSON-RPC 2.0 定义了一组标准方法:

核心任务方法:

方法 描述 使用场景
SendMessage 发送消息,发起或继续任务 所有交互的入口
SendStreamingMessage 发送消息并建立 SSE 流 需要实时更新的场景
GetTask 获取任务当前状态和结果 异步轮询
ListTasks 列出任务(支持过滤和分页) 任务管理
CancelTask 取消正在进行的任务 用户中止操作
SubscribeToTask 对已有任务建立 SSE 订阅 中途加入监听

推送通知配置方法:

方法 描述
CreateTaskPushNotificationConfig 为任务创建 Webhook 推送配置
GetTaskPushNotificationConfig 获取推送配置
ListTaskPushNotificationConfigs 列出所有推送配置
DeleteTaskPushNotificationConfig 删除推送配置

一个典型的 JSON-RPC 请求示例:

json 复制代码
{
  "jsonrpc": "2.0",
  "method": "SendMessage",
  "id": "req-001",
  "params": {
    "message": {
      "messageId": "msg-001",
      "role": "ROLE_USER",
      "parts": [
        {
          "text": "帮我搜索明天北京到上海的航班,经济舱"
        }
      ]
    },
    "configuration": {
      "acceptedOutputModes": ["text/plain", "application/json"]
    }
  }
}

4.3 流式传输的实际运作

当使用 SendStreamingMessage 时,服务端通过 SSE 推送一系列事件:

vbnet 复制代码
event: task-status
data: {"taskId": "task-001", "state": "WORKING", "message": {"text": "正在搜索航班..."}}

event: task-status
data: {"taskId": "task-001", "state": "WORKING", "message": {"text": "找到 12 个匹配航班"}}

event: task-artifact
data: {"taskId": "task-001", "artifactId": "art-001", "parts": [{"data": {"flights": [...]}}]}

event: task-status
data: {"taskId": "task-001", "state": "COMPLETED"}

SSE 的优势在于:客户端只需一次 HTTP 请求,就能持续接收 Agent 的状态更新和流式输出------特别适合生成式 AI 的逐步输出场景。


五、安全模型

5.1 认证机制

A2A 不发明新的认证协议,而是复用已有的 Web 安全标准。支持的认证方案包括:

认证方案 说明 典型场景
http (Bearer) HTTP Authorization 头 + Bearer Token OAuth2 访问令牌
apiKey API Key 认证 简单的 API 调用
oauth2 OAuth 2.0 完整流程 企业级应用
openIdConnect OpenID Connect 身份认证 + 授权

认证信息在 Agent Card 的 securitySchemes 字段中声明,客户端根据声明获取凭证后,通过 HTTP Header 传输:

makefile 复制代码
Authorization: Bearer <token>
A2A-Version: 1.0

5.2 Agent 不透明性

A2A 的一个重要安全特性是 Agent 不透明性(Opacity)

  • Agent 不需要暴露内部使用的模型、工具或数据
  • Agent 不需要共享内部记忆或推理过程
  • Agent 只通过 Agent Card 声明"我能做什么",而不是"我怎么做"

这在企业场景中至关重要: 公司的核心业务逻辑和数据,不会因为接入 A2A 协议而被暴露给合作方的 Agent。

5.3 Agent Card 签名验证

Agent Card 支持 JWS(JSON Web Signature,RFC 7515)签名:

  1. Agent Card 的发布者使用私钥对内容进行签名
  2. 客户端获取 Agent Card 时,使用发布者的公钥验证签名
  3. 签名验证使用 JSON Canonicalization(RFC 8785)确保一致性

这防止了中间人攻击------攻击者无法伪造或篡改 Agent Card 来冒充可信 Agent。


六、A2A vs MCP:互补而非竞争

A2A 和 MCP 是 Agent 生态中最常被提及的两个协议,很多人容易混淆。它们的关系是互补,不是竞争。

6.1 核心差异

graph LR subgraph "MCP 协议" A1[AI Agent] -->|"调用工具"| T1[搜索引擎] A1 -->|"读取数据"| T2[数据库] A1 -->|"执行操作"| T3[代码执行器] end subgraph "A2A 协议" A2[Agent A] <-->|"对话协作"| A3[Agent B] A2 <-->|"任务委派"| A4[Agent C] A3 <-->|"结果同步"| A4 end style A1 fill:#fff,stroke:#333,stroke-width:2px,color:#333 style A2 fill:#fff,stroke:#333,stroke-width:2px,color:#333 style A3 fill:#fff,stroke:#333,stroke-width:2px,color:#333 style A4 fill:#fff,stroke:#333,stroke-width:2px,color:#333 style T1 fill:#fff,stroke:#333,stroke-width:1px,color:#333 style T2 fill:#fff,stroke:#333,stroke-width:1px,color:#333 style T3 fill:#fff,stroke:#333,stroke-width:1px,color:#333
维度 MCP A2A
通信方向 Agent → Tool(纵向) Agent ↔ Agent(横向)
对方的身份 工具/数据源(被动) 独立 Agent(主动、有自主性)
交互模式 调用-返回(同步) 对话、协商、多轮交互
状态管理 无状态 有状态(Task 生命周期)
对方能否拒绝 不能(工具只有成功/失败) 可以(Agent 可以 REJECTED)
提出方 Anthropic Google(Linux Foundation)
类比 USB 接口 人与人之间的对话协议

6.2 协同场景

一个典型的协同场景:

css 复制代码
用户 → 你的 Agent
  ├── [A2A] → 航空公司 Agent:协商机票方案
  │     └── [MCP] → 航空公司数据库:查询实时票价
  ├── [A2A] → 酒店 Agent:协商住宿方案
  │     └── [MCP] → 酒店预订系统:查询空房
  └── [MCP] → 用户日历工具:获取行程安排

MCP 解决的是"Agent 如何使用工具",A2A 解决的是"Agent 如何与另一个 Agent 合作"。 两者共同构成了 Agent 能力的完整拼图。


七、开发者快速入门

7.1 多语言 SDK

A2A 提供了丰富的 SDK 支持:

语言 安装方式
Python pip install a2a-sdk
Go go get github.com/a2aproject/a2a-go
JavaScript npm install @a2a-js/sdk
Java Maven 依赖
.NET dotnet add package A2A

7.2 快速体验:3 步创建一个 A2A Agent

Step 1:定义 Agent Card

python 复制代码
from a2a.types import AgentCard, Skill

card = AgentCard(
    name="Weather Agent",
    description="提供全球天气查询服务",
    version="1.0.0",
    skills=[
        Skill(
            id="weather-query",
            name="天气查询",
            description="根据城市名查询当前天气",
            tags=["weather"],
            examples=["北京今天天气怎么样?"]
        )
    ],
    default_input_modes=["text/plain"],
    default_output_modes=["text/plain", "application/json"]
)

Step 2:实现消息处理逻辑

python 复制代码
from a2a.server import A2AServer, TaskHandler

class WeatherHandler(TaskHandler):
    async def handle_message(self, message, context):
        city = extract_city(message.parts[0].text)
        weather = await get_weather(city)
        return {
            "parts": [{"text": f"{city}当前天气:{weather}"}]
        }

Step 3:启动 Agent 服务

python 复制代码
server = A2AServer(
    agent_card=card,
    handler=WeatherHandler()
)
server.start(port=8080)
# Agent Card 自动托管在 http://localhost:8080/.well-known/agent-card.json

八、写在最后

A2A 协议的出现,标志着 AI Agent 从"单兵作战"进入了"组队协作"时代。

它的设计哲学有三个值得关注的点:

  1. 尊重 Agent 的主体性:Agent 不是工具,它可以拒绝任务、主动要求补充信息、异步回报结果。这为构建复杂的多 Agent 系统奠定了基础。

  2. 基于已有标准:JSON-RPC、HTTP、SSE、OAuth------A2A 没有发明新轮子,而是组合了已被验证的技术标准。这极大降低了开发者的学习成本。

  3. 不透明协作:Agent 之间可以协作,但不需要暴露内部实现。这让企业在享受 Agent 协作红利的同时,保护了核心业务逻辑。

下一篇,我们将深入 AP2(Agent Payments Protocol)------看看当 Agent 需要"花钱"时,如何用可验证数字凭证来确保每一笔交易都有用户的真实授权。


关注公众号「coft」,获取更多 AI 时代的深度洞察和技术实战干货。

相关推荐
后端小肥肠3 小时前
喂饭级教程!免费部署云端 OpenClaw + 打通飞书,自动抓取 ClawHub 技能并写入飞书表格
人工智能·agent
桂花很香,旭很美4 小时前
Anthropic Agent 工程实战笔记(六)安全与生产
笔记·架构·agent
桂花很香,旭很美9 小时前
Anthropic Agent 工程实战笔记(四)长任务与多 Agent
笔记·架构·agent
Kayshen9 小时前
春节期间我们开源了一个 AI-Native 的矢量设计工具,对标 Pencil.dev,让 AI Agent 直接画 UI
前端·aigc·agent
数据智能老司机10 小时前
面向产品经理的 Claude Code——为什么产品经理该用 Claude Code,而不是 Claude.ai?
llm·agent·vibecoding
桂花很香,旭很美12 小时前
Anthropic Agent 工程实战笔记(五)评测与 Eval
笔记·架构·agent
大鹏的NLP博客1 天前
LangGraph Task Graph 任务规划Agent工作流系统
agent·工作流
冬奇Lab1 天前
一天一个开源项目(第31篇):awesome-openclaw-usecases - OpenClaw 真实用例集合
人工智能·开源·agent