过去,一个系统调用另一个系统,我们称之为 API 调用;一个服务把任务交给另一个服务,我们称之为 RPC;一个耗时任务需要查询进度,我们会返回一个 task_id;一个服务需要向调用方持续发送结果,我们会使用 SSE、WebSocket 或消息队列。

现在,只要调用链路两端都接入了大模型,这些已经存在多年的工程动作,似乎突然需要换一套更宏大的语言:它们不再是服务,而是 Agent;不再是接口调用,而是 Agent 协作;不再是任务状态,而是智能体之间的长期委托;不再是服务发现,而是 Agent Discovery。 最后,我们得到了一套新的 Agent-to-Agent 协议,也就是 A2A。
A2A 的设计当然是完整的。它定义了 Agent Card、Skill、Message、Task、Artifact、流式更新、任务状态和认证方式,看起来像是为“智能体社会”准备了一整套外交制度。
但问题在于:今天绝大多数所谓的 Agent,真的已经发展到需要外交协议了吗?
我的观点是:
对绝大多数企业 Agent 系统来说,Agent 不需要 A2A。它需要的是稳定的接口、确定性的编排、清晰的状态管理,以及一套已经被软件工程验证过的服务治理体系。
A2A 不是完全没有价值,而是它试图标准化的场景,远远没有行业宣传中那么普遍。很多团队引入 A2A,并不是因为现有技术解决不了问题,而是因为“两个 Agent 在通信”听起来比“一个服务调用另一个服务”更像 AI 原生架构。
这很像给公司里的每一个部门都发一本外交护照。部门之间确实需要沟通,但未必需要建立联合国。
Agent 首先是软件,其次才是 Agent
讨论 A2A 之前,必须先回答一个经常被忽略的问题:什么是 Agent?
一个典型 Agent 可能包含大模型、Prompt、工具调用、短期记忆、长期记忆、规划器、工作流和若干业务规则。它可以根据输入判断下一步动作,也可能在执行过程中进行多轮推理。

但这些特征描述的是它的内部实现,而不是它对外暴露的接口形式。
假设有一个市场研究 Agent。它收到一个行业名称,搜索公开信息,调用内部数据库,分析竞争格局,最后生成一份报告。
从它自己的视角看,它可能是一个复杂的自主 Agent:
理解任务
↓
制定检索计划
↓
调用搜索工具
↓
提取竞争对手
↓
补充行业数据
↓
生成报告
↓
自我检查
但从调用方的视角看,它完全可以只是一个接口:
report = research_agent(
topic="AI survey software",
depth="deep",
output_format="markdown"
)
调用方通常不需要知道它内部使用了几个模型、执行了几轮反思、是否建立了计划,也不需要知道它究竟算不算“真正的 Agent”。
调用方真正关心的是:输入是什么,输出是什么,什么时候完成,失败后怎么重试,是否具有幂等性,消耗了多少资源,以及出现问题时如何追踪。这正是软件接口一直在解决的问题。
所以,Agent 是否具有自主性,并不能自动推出“它需要一套新的通信协议”。内部复杂性,不等于外部必须复杂。
Agent as Tool 已经覆盖了大多数协作场景
A2A 支持者经常强调,工具与 Agent 不一样。工具通常是确定性的,而 Agent 具有自主性;工具执行一次明确的操作,而 Agent 可能自主规划多个步骤;工具返回一个结果,而 Agent 可能要求补充信息、持续更新任务状态,甚至在较长时间后才完成工作。
这些区别在概念层面成立,但它们没有改变接口设计的基本事实。一个接口背后可以是一行代码,也可以是一个运行数小时的工作流。接口并不要求实现简单,也不要求实现确定。

例如,下面这个工具定义看起来很普通:
{
"name": "generate_market_report",
"description": "Generate a market research report",
"inputSchema": {
"type": "object",
"properties": {
"topic": {
"type": "string"
},
"depth": {
"type": "string",
"enum": ["brief", "standard", "deep"]
}
},
"required": ["topic"]
}
}
它背后的实现可以是一个简单函数,也可以是一个具备规划、搜索、反思和多轮工具调用能力的 Agent。
对于主控 Agent 来说,这种区别并不重要。主控 Agent只需要判断:当前任务是否适合调用 generate_market_report,应该传入什么参数,以及如何处理返回结果。这就是 Agent as Tool。
有人会认为,把 Agent 描述为 Tool 是对 Agent 自主性的降维。实际上,这是一种非常有价值的工程抽象。
一个系统越复杂,越应该在边界处隐藏内部细节。把远程 Agent 封装成 Tool,不是说它内部没有自主性,而是说它的自主性不应该泄漏到整个系统。
Task、Artifact 和 Agent Card 并不是新的计算原语
A2A 最有代表性的几个概念是 Task、Artifact 和 Agent Card。这些概念确实清晰,但换一个熟悉的软件工程词汇就会发现,它们并不陌生。
| A2A 概念 | 传统工程中的对应概念 |
|---|---|
| Agent Card | 服务描述、OpenAPI 文档、注册中心元数据 |
| Agent Skill | API 能力、工具描述、服务能力标签 |
| Message | 请求或事件 |
| Task | 异步任务、工作流实例、Job |
| Task Status | 任务状态机 |
| Artifact | 文件、对象存储结果、结构化响应 |
| Push Notification | Webhook、事件回调 |
| Streaming | SSE、WebSocket、流式 RPC |
| Agent Discovery | 服务发现、能力注册中心 |
这并不是说 A2A 的抽象没有意义。统一术语本身可以产生价值。但术语统一和新协议必要性是两件事。

假设一个研究任务需要运行二十分钟。服务端可以立即返回:
{
"task_id": "task_20260724_001",
"status": "working"
}
调用方随后轮询:
GET /tasks/task_20260724_001
或者通过 SSE 订阅:
GET /tasks/task_20260724_001/events
任务完成后返回:
{
"task_id": "task_20260724_001",
"status": "completed",
"result": {
"report_url": "https://example.com/report.md"
}
}
这已经覆盖了 A2A Task、状态更新和 Artifact 的核心语义。
多轮交互也不是 A2A 的专属能力
A2A 的另一个卖点,是 Agent 之间可以进行多轮交互。例如,一个旅行 Agent 委托酒店 Agent 预订房间,酒店 Agent 发现用户没有提供入住人数,于是把任务状态设为 INPUT_REQUIRED,要求调用方补充信息。
这听起来很 Agent,但在工程上仍然是一个普通的中断恢复流程。
服务端可以返回:
{
"task_id": "booking_001",
"status": "input_required",
"required_fields": [
{
"name": "guest_count",
"type": "integer",
"description": "Number of guests"
}
]
}
调用方补充信息:
{
"task_id": "booking_001",
"input": {
"guest_count": 2
}
}
这既可以通过普通 REST API 实现,也可以通过 MCP Tool 的结构化响应实现,还可以放入工作流引擎的 Human-in-the-loop 节点。
换句话说,A2A 给复杂任务准备了一套漂亮的语法,但生产系统真正需要解决的是语义。
不要把编排问题误写成通信问题
支持 A2A 的一个重要观点是:MCP 主要面向工具使用,却没有解决多 Agent 编排问题。这个观察是对的,但结论未必成立。

MCP 的确不负责完整的多 Agent 编排。可是,A2A 同样不应该负责业务编排。通信协议负责定义消息怎么传递,编排系统负责决定谁先执行、谁后执行、失败后如何补偿、哪些步骤可以并行,以及哪些决策必须由确定性规则控制。
这两者不应该混为一谈。
例如,一个内容生产系统包含以下节点:
选题分析
↓
资料检索
↓
文章生成
↓
事实检查
↓
风格审校
↓
发布审批
这些节点背后可以分别由不同 Agent 实现,但它们之间的顺序不是一个开放式对话问题,而是一个工作流问题。
A2A 可以成为节点之间的一种传输方式,却不能替代编排。把它描述为多 Agent 编排的答案,很容易再次犯下一个常见错误:把 DAG 的确定性调度理解成让 LLM 决定执行顺序。
真正成熟的 Agent 架构,不是让 Agent 获得更多发言权,而是明确哪些地方允许它发言。
服务发现不是 Agent 的核心竞争力
A2A 相对独特的能力,是 Agent Card 和 Agent Discovery。一个 Agent 可以公开自己的名称、说明、Skill、输入输出形式、认证要求和服务地址。其他 Agent 获取 Agent Card 后,可以判断它是否适合当前任务。
这看起来像一个开放的 Agent 市场:Agent 可以像人在招聘网站上阅读简历一样,动态寻找合作者。
这是一个很有想象力的场景。问题是,绝大多数企业系统并不希望 Agent 在互联网上自由寻找合作伙伴。

在这种情况下,企业需要的不是开放式 Agent Discovery,而是一个受治理的服务目录。这个目录完全可以由 API Gateway、服务注册中心、内部工具市场、配置中心或者 MCP Server Registry 实现。能力元数据也可以使用 JSON Schema、OpenAPI 扩展字段或内部标签描述。
当所有远程 Agent 最终都必须预先注册并经过审批时,开放发现带来的价值会大幅下降。它最后仍然会变成一个服务注册中心,只是字段名称更加 Agent 化。
A2A 会制造第二套状态和治理体系
引入一套协议的成本,从来不只是安装一个 SDK。当系统同时使用 MCP 和 A2A 时,团队需要维护两套概念模型。
MCP 中有 Tool、Resource、Prompt 和 Session;A2A 中有 Agent、Skill、Message、Task、Context 和 Artifact。二者之间存在重叠,却不是完全一一对应。
于是,工程团队开始编写适配层:
MCP Tool Call
↓
转换为 A2A Message
↓
创建 A2A Task
↓
接收 TaskStatusUpdateEvent
↓
转换为 MCP Progress Notification
↓
把 Artifact 转换为 Tool Result
真正棘手的不是字段转换,而是语义转换。技术架构有一个朴素规律:
每增加一个抽象层,系统就会多一种失败方式。
只有当新增抽象带来的收益明显高于其长期维护成本时,这一层才值得存在。
对于多数内部 Agent 系统,A2A 提供的能力可以通过现有 API、MCP、任务系统和工作流引擎组合完成。此时再增加 A2A,往往只是把原来的一种失败方式变成两种。