2025 不愧是 Agent 元年,业界进展好生迅猛,上个月刚写过一篇「直观理解 MCP 协议」,这周 Google 又发布了个新东西:A2A 协议,今天就来聊聊它。
A2A 是什么?
A2A = Agent2Agent Protocol = 智能体互操作协议
说白了,它也是个「插件协议」,只不过这次「插件」的形态不太典型,它不再是一个传统意义上的「软件」了,而是以一个 agent 智能体的形态出现。
这次我们也用类比的方式,借助 MCP 这个「老概念」来帮大家快速建立起对 A2A 的直观认识(还不了解 MCP 的小伙伴可以先阅读上篇)。
MCP 的核心功能是提供可供远程调用的「tools 服务」。这里 tools 就是传统意义上的「软件」,比如查天气,查股票,计算器,执行代码等功能的软件。
tools 的特点是:
- 以「function 函数」的形态呈现
- 行为确定且单一(因为就是函数嘛,很好理解)
- 入参 (input) 必须是结构化数据,用 json schema 预先声明了数据结构
- 交互上只有一个来回,一次调用必有一次返回,中间没有其他交互过程,也没有中间状态,要么成功要么失败
上期回顾完毕,说回 A2A 协议,它设计的交互模型是这样的:
- 首先澄清「任务 task」是一个核心概念,所有事情是围绕 task 展开的,那种自由对话式的 AI 应用不在 A2A 的职能范畴里
- 用户与一个「客户端智能体 client agent」进行直接对话,向它提需求,要求完成某项任务。注意!这项任务很可能是一个涉及长链路、多步骤的复杂大任务
- client agent 可以把用户的需求拆解成多个步骤的子任务 sub-task,然后去找有能力完成某项子任务的「服务端智能体 remote agent」,把子任务委托给它
- 这个过程中 remote agent 可以和 client agent 沟通互动,包括提问澄清某个需求细节、反馈任务进度等
- remote agent 完成委托的子任务后,会给 client agent 返回最终交付物 (artifacts),这标志着当前步骤已完成
- client agent 重复上述过程,找下一个 remote agent 完成下一个步骤的子任务,直到完成整个大任务,停止运行
Remote agent = 乙方工具人
聪明的读者应该已经反应过来了:remote agent 不就是 tool 的升级版——工具人嘛?一点不错!
如果说 MCP 是给单个 agent 配一些简单的工具,让 agent 自己去干活,那么 A2A 就是直接让 client agent 变身甲方爸爸,给它配了一堆乙方工具人帮它干活。
client agent 只需要负责把大任务拆包成子任务,委托给一个个 remote agent 去完成,然后验收它们的成果,最后汇总一下,向用户交差。
对甲方而言,乙方 remote agent 是不透明的,甲方看不见乙方的内部细节,反之亦然。双方严格遵守 A2A 协议进行信息有限的交互。
但很显然,如果我们打开一个 remote agent,它的内部很可能也使用 A2A 聚合了一堆「丙方工具人」在帮它干活(套娃开始)!
对比于 tools,remote agent 有以下特点:
- 以「agent 智能体」的形态呈现
- 行为不太确定、可能略复杂(毕竟是智能体了嘛,它可能会有自己的想法…)
- 入参 (input) 可以是自然语言(多数情况),也可以是结构化数据(由 remote agent 自己声明)
- 交互上有多个来回,remote agent 可以反馈当前任务进度、向用户提问、中断任务、甚至拒绝服务
协议细节概览
完整协议内容看请看官方文档:
有需要中文版的读者,欢迎关注公众号「阿曜搞 Agent」,后台回复关键字【A2A】领取。
本章节带大家过一下 A2A 协议的关键细节。
MCP 协议本身是在 JSON RPC 之上构建的,协议的核心(有关 tools 的部分)其实就是两个概念:
- 服务发现,通过
tools/list
方法 - 服务调用,通过
tools/call
方法
A2A 协议同样是基于 JSON RPC,核心也是这两个概念。
服务发现
A2A 的「服务发现」职能不在 JSON RPC 协议范围内。协议只约定了一个叫做「agent card」的 json 数据格式,至于发现方法有多种手段:
- 官方推荐服务商把 agent card 暴露在固定地址下
https://example.com/.well-known/agent.json
- 如果是平台型应用,可以通过「agent 应用商店」来公开发布 agent card,或者企业级应用可以通过约定 API 来发布私有 agent
- 还跟 MCP 友情互动了一把:推荐可以通过 MCP 协议的
/resources
能力来暴露 agent card
我们来看一下 agent card 长什么样:
json 代码解读复制代码{
"name": "Google Maps Agent",
"description": "Plan routes, remember places, and generate directions",
"url": "https://maps-agent.google.com",
// ...
// 此处省略若干次要字段
// ...
"defaultInputModes": ["text/plain"],
"defaultOutputModes": ["text/plain", "application/html"],
"skills": [
{
"id": "route-planner",
"name": "Route planning",
"description": "Helps plan routing between two locations",
"examples": [
"plan my route from Sunnyvale to Mountain View",
"what's the commute time from Sunnyvale to San Francisco at 9AM",
"create turn by turn directions from Sunnyvale to Mountain View"
],
"outputModes": ["application/html", "video/mp4"]
}
]
}
和 MCP 的 tools/list
返回数据比较一下:
json 代码解读复制代码{
"tools": [
{
"name": "get_weather",
"description": "Get current weather information for a location",
"inputSchema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name or zip code"
}
},
"required": ["location"]
}
}
]
}
很容易发现,A2A skills 对位的就是 MCP tools 字段,而原本 tool 严格的 inputSchema 变成了一组 examples 示范提示词,表明 agent 接受自然语言作为调用的入参。
同时多了一个概念 input/output modes,声明 agent 能处理的输入/输出的 mimetype。
我们正在加速进入多模态模型的时代,能生图、生视频的模型越来越多,这组字段正是为此准备的,client 需要参考 mimetype 提供多种 UI 形态来呈现 agent 的交付物。
服务调用
前面说过 A2A 的交互模型是围绕「任务」展开的,client agent 是把一个个子任务交给 remote agent 去完成。
这里「子任务」在 A2A 的协议术语里就叫做 task,而 client agent 和用户之间的整个交互/聊天历程称为一个 session,对应一个 UX 概念上的「大任务」。
也就是说 session 和 task 是一对多关系。
session 理论上可以无限延长(尽管正常用户应该不会这么做),但 task 总是处在某个执行状态里,这个状态由 remote agent 决定。
ts 代码解读复制代码type TaskState =
| "submitted" // 收到请求,但还未开始处理
| "working" // 正在处理
| "input-required" // “提问”,需要用户提供额外信息输入
| "completed" // 完成
| "canceled" // 用户主动取消
| "failed" // 失败
| "unknown"; // 兜底的未知状态
值得一提的是,协议说:一个 task 即便已经完成,也允许继续进行下去。例如:GPT-4o 生成图片,任务已经完成了,但用户可能会要求它对图片做进一步的修改。
我们看一个多回合互动的调用例子,场景是新员工入职某大厂,要领取工作电脑。注意看注释。
json 代码解读复制代码// 请原谅这个奇怪的 json 格式化
// 都是为了手机屏幕上阅读能节省点空间
// Request - seq 1
{"jsonrpc": "2.0", "id": 1,
"method": "tasks/send",
"params": {
// 必填:client 生成的 task id
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
// 选填:client 当前的 session id,如果不填 remote agent 会帮你填一个
// 【吐槽】我本人不理解为什么这个字段是选填的...remote 帮填的意义又何在...
"sessionId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"message": {
"role": "user",
"parts": [{
"type": "text",
"text": "我要申请一台工作电脑",
// metadata 是 client agent 根据一些背景信息(比如 agent card)带上的额外信息
// 这里模拟向 IT 部门申请领电脑,要填的表格的字段
"metadata": {
"mimeType": "application/json",
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"assetId": { "type": "string" },
"description": { "type": "string" }
}
}
}
}
}]
}
}}
// Response - seq 2
{"jsonrpc": "2.0", "id": 1,
"result": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"sessionId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
// 任务进度更新
"status": {
// 任务状态:请求用户输入
"state": "input-required",
"message": {
"parts": [
// 给用户的自然语言的指示
{
"type": "text",
"text": "有以下型号的电脑可供选择:"
},
// 结构化 json 数据,
// 也许是根据上面的 metadata 返回,但这不是 A2A 协议内的约束,
// 具体行为全靠 agent 自己决定,这就是前文说的“行为不太确定”
// client agent 可以基于 json 生成一个表单 UI 给用户选择
{
"type": "text",
"text": "[{\"assetId\":\"IT_ASSET_42\",\"description\":\"MacBook Pro 15\"},{\"assetId\":\"IT_ASSET_101\",\"description\":\"ThinkPad X1 Carbon\"}]"
}
]
}
}
}}
// Request - seq 3
{"jsonrpc": "2.0", "id": 2,
"method": "tasks/send",
"params": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"sessionId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"message": {
"role": "user",
"parts": [{
"type": "text",
// 用户在表单 UI 上选择了一个电脑型号,提交,结果以 json 传给 remote agent
"text": "{\"assetId\":\"IT_ASSET_42\"}",
"metadata": {
"mimeType": "application/json",
"schema": {
"type": "object",
"properties": {
"assetId": { "type": "string" }
}
}
}
}]
}
}}
// Response - seq 4
{"jsonrpc": "2.0", "id": 2,
"result": {
"id": "de38c76d-d54c-436c-8b9f-4c2703648d64",
"sessionId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
// 任务进度更新
"status": {
// 任务状态:完成
"state": "completed"
},
// 任务的最终交付产物,必须放在 artifacts 字段里,即便只是普通的 text message
"artifacts": [
{
"name": "order-confirmation",
"parts": [
{
"type": "text",
"text": "已帮您预定 MacBook Pro 15 作为工作电脑,工单号是 R12443,稍后会邮件通知您进度。"
}
]
}
]
}}
A2A 不是什么?
相信大家听到 A2A,第一反应会想,这是不是服务于「多智能体系统」(multi-agent system,下文简称 MAS)的通信协议?
这个问题很微妙,我认为 yes and no:
- Yes,是因为 A2A 把多个 agent 组织在一起干活,显然就是一个符合定义的 MAS,没任何毛病。
- No,是因为 A2A 预设了一种「一个 client agent 和多个 remote agent」进行单线联系的交互模式,强调「一对多」,而基本上忽略了乙方之间作为一个整体的团队的「多对多」交互模式。这跟当前学术界主要研究的 MAS 模型不太一样,是其中一种较简单的形式。
A2A 设计上并没有考虑 MAS 作为一个整体,团队成员 agent 之间信息共享、自主建立合作的需求,而是围绕 client agent 这个大甲方设计的,把其他乙方 remote agents 作为「高级工具人」来看待,不考虑它们的自主性,不希望释放团队合作的潜能。
它的侧重点是 agent 间的「互操作 interoperation」而不是「互相沟通 communication」。
这并不是一个「缺点」,而是 A2A 主动拥抱的设计决策,it's not a bug, it's a feature.
它的目的显然是要服务于企业级应用,强调安全、受控,协议模型简单才不容易出幺蛾子。越简单越容易接入,才能快速建立起跨领域的 agent 应用生态。
但作为开发者,我们需要明白它不是什么:这套协议不适用于构建那种需要高度信息共享、成员紧密合作的 MAS,更适合松散合作关系的 MAS。
总结
A2A 协议的内容并不难理解,就是把 agent 作为高级工具人来看待的 MCP 的升级版。
但它的影响我认为将会是深远的,通过「任务导向型 agent」重塑了软件范式,为跨组织、跨服务商的 agent 协作制定了简洁明了的标准化解决方案。
商业上这个站位非常聪明,我估计 agent 应用商店这个生态位要被 Google 抢先拿下了,就看它能不能及时推出一款好用的「通用 client agent app」。同场发布的 Agentspace 产品目前还在 waitlist,不知能否接住用户的期待。
都说所有 SaaS 都可用 AI 重做一遍,这不第一步棋已经落下了,预计 2025 下半年就能见到 SaaS 型 agent 生态的井喷。相关领域的开发者需要紧密关注机会。
最后附上 A2A 文档链接:
google.github.io/A2A/#/docum…
有需要中文版的读者,欢迎关注公众号「阿曜搞 Agent」,后台回复关键字【A2A】领取。
评论记录:
回复评论: