过去,一个系统调用另一个系统,我们称之为 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 的抽象没有意义。统一术语本身可以产生价值。但术语统一和新协议必要性是两件事。

假设一个研究任务需要运行二十分钟。服务端可以立即返回:
{
"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,往往只是把原来的一种失败方式变成两种。
大多数“多 Agent”其实只是一个应用里的多个模块
多 Agent 系统经常被画成一群拥有不同职业的数字员工:研究 Agent 负责找资料,分析 Agent 负责总结,写作 Agent 负责生成文章,审校 Agent 负责检查质量,管理 Agent 负责协调全局。
从产品演示上看,它们像一个虚拟团队。但从工程实现上看,它们通常属于同一个代码仓库、共享同一个数据库、运行在同一个 Kubernetes 集群,甚至由同一个进程中的几个 Python 对象组成。
在这种场景下使用 A2A,就像同一个函数里的两个对象为了交换一个字典,先分别部署成服务器,再通过标准外交电文进行沟通。
系统确实变得更“分布式”了,但业务能力没有因此增强。对于同进程 Agent,直接函数调用最简单。对于跨进程但同一团队管理的 Agent,普通 HTTP、gRPC、消息队列或 MCP 通常已经可以满足需求。
A2A 最大的问题不是做不到,而是做得太早
A2A 并不是一个糟糕的协议。恰恰相反,它的问题可能是设计得太完整,也太超前。
它预设了一个未来:大量独立 Agent 由不同组织提供,拥有不同框架和模型,通过公开能力描述发现彼此,协商任务,持续交换状态,并交付结构化成果。
在这样的未来里,A2A 很有意义。它有点像互联网早期的电子邮件协议。只要不同组织都遵守同一个标准,彼此就可以通信,而不需要关心对方内部使用什么系统。
但今天的 Agent 生态距离这个未来仍然很远。当前多数 Agent 的能力描述缺乏稳定性。同一个 Agent 换一个 Prompt、一个模型版本或者一组工具,行为就可能发生明显变化。
Skill 的语义也难以像传统 API 那样精确定义。“市场分析”“深度研究”“制定策略”都不是可以仅靠 JSON Schema 完整描述的确定性能力。
更关键的是,企业还没有解决如何评估一个外部 Agent 是否可信、是否稳定、是否会泄露数据,以及输出质量是否达到业务标准。
在能力、评测、责任和信任机制都不成熟时,优先标准化 Agent 之间如何互相发送消息,很可能是在给一座还没建成的城市设计国际机场。
MCP 也不是唯一答案
认为 Agent 不需要 A2A,并不意味着所有 Agent 都必须使用 MCP。MCP 同样不是万能协议。
对于简单的内部调用,函数接口可能比 MCP 更合适;对于高吞吐低延迟服务,gRPC 可能更合适;对于可靠的长任务,Temporal 或消息队列可能更合适;对于固定业务流程,DAG 和状态机可能比任何 Agent 协议都更重要。
真正应该坚持的不是“MCP 战胜 A2A”,而是:
不要因为参与通信的是 Agent,就假设传统软件工程已经失效。
协议选择应该由问题决定,而不是由参与者的名字决定。当一个 Agent 被封装成稳定能力时,它可以是一个函数、一个 HTTP API、一个 MCP Tool,也可以是一个异步 Job。
只有在普通接口明显无法表达业务需求时,才需要进一步考虑 A2A。这比从“这是两个 Agent”直接推导出“它们应该使用 Agent-to-Agent Protocol”更加可靠。
哪些情况下 A2A 才真正值得使用
A2A 的价值主要出现在以下特征同时存在时:
系统需要调用由其他公司或独立团队运营的 Agent。 调用方无法控制远程 Agent 的内部实现和升级节奏。 任务可能持续较长时间,并且存在补充输入、认证中断和异步恢复。 远程 Agent 不只是执行一个窄工具,而是接受目标后自主完成一整段工作。 不同 Agent 框架之间需要共享统一的任务和结果语义。 生态中已经形成足够多的 A2A 服务,使用标准协议的收益高于维护适配层的成本。
在这种真正跨组织、跨信任域的协作中,A2A 的 Agent Card、Task、Artifact、认证和状态模型可以减少重复集成工作。
此时,A2A 不是为了让几个 Python 对象互相聊天,而是在尝试建立一种跨企业的 Agent 服务契约。
一个更务实的技术选型顺序
面对 Agent 之间的调用需求,可以按照由简单到复杂的顺序选择方案。
首先判断是否可以使用函数调用。如果两个 Agent 运行在同一进程,函数或统一接口通常已经足够。 其次判断是否可以作为普通服务。跨进程或跨语言时,HTTP、gRPC 和消息队列拥有成熟的治理、监控和部署体系。 然后判断是否适合建模为工具。主控 Agent 只需要调用对方的一项能力时,可以将远程 Agent 封装为 MCP Tool 或 Function Tool。 如果任务耗时较长,则增加任务 ID、状态查询、Webhook、SSE 或工作流引擎,而不是立即更换整个协议栈。
最后,只有当系统确实涉及跨组织 Agent 协作、开放能力发现和统一任务语义时,再考虑 A2A。
这个顺序背后的原则是:
Function
↓
Service API
↓
Tool Protocol
↓
Asynchronous Task
↓
Cross-organization Agent Protocol
复杂性应该随着业务边界逐步增加,而不是因为代码里出现了 Agent 这个类名,就直接跳到最后一层。
先把 Agent 做成好服务,再考虑让它参与协议
A2A 描绘了一个迷人的未来:不同组织、不同模型和不同框架构建的 Agent,可以像互联网服务一样自由发现、委托任务和交换成果。
这个未来可能会到来。但在那之前,大多数 Agent 团队面对的现实问题不是“如何让全球 Agent 互联”。在这些基础问题没有解决之前,引入 A2A,就像一家只有三名员工的创业公司,先制定了一套跨国并购流程。
流程很专业,只是暂时用不上。
所以,“Agent 不需要 A2A”并不是说 A2A 永远没有价值,而是强调一个更朴素的工程判断:
Agent 并不会因为具有自主性,就脱离软件系统的基本规律。能用函数解决的问题,不要先部署服务;能用服务解决的问题,不要先发明协议;能把 Agent 当作工具调用,就不要急着让它们建立外交关系。
