Google 的 A2A 协议解决 Agent 间发现与协作,ACP 协议解决客户端到 Agent 的认证与会话管理,两者定位不同且互补。
两个都出自 Google,都打上了"agent"的标签,发布时间也只差几个月。所以问题不断被抛出来:Google 的 Agent-to-Agent 协议和 Agent Client 协议,哪个会赢?诚实的答案是——它们根本不在同一个维度上竞争。Agent2Agent 协议(A2A)和 Agent Client 协议(ACP)解决的是同一个问题的不同切面,它们被明确设计为共存,而且两者都悄悄依赖一个几乎没人谈论的底层:传输层。
在深入之前,先给出一句话版本。A2A 关注的是发现和 agent 之间的协作——一个 agent 如何知道另一个 agent 能做什么,以及如何把任务交给它。ACP 关注的是客户端与 agent 的边界——客户端如何向 agent 认证、如何打开会话、如何驱动它的工具调用循环。不同的切面,同一个技术栈。下面我们逐个来看,然后再看两者共同依赖的那一层。
如果你只是扫了一眼公告,两个看起来都像是"一个面向 agent 的协议"。区别只有在你看清每个协议在线路上标准化了什么时才会显现出来。
A2A 是 Google 推出的开放式 agent 间协作协议。它的核心是 Agent Card:每个 A2A 服务器在 /.well-known/agent-card.json 这样的众所周知的路径上暴露的一个 JSON 文档。这张卡就是 agent 的服务描述——名称、功能、技能、认证要求。它的存在是为了让另一个 agent 能在没有人工介入的情况下回答:"谁能做这个,我怎么和它对话?"
{
"name": "Invoice Agent",
"description": "Extracts fields from uploaded invoices",
"url": "https://agent.example.com/a2a",
"version": "1.0.0",
"capabilities": {
"streaming": true,
"pushNotifications": false
},
"authentication": {
"schemes": ["bearer"]
},
"skills": [
{
"id": "parse-invoice",
"name": "Parse invoice",
"description": "Takes a PDF, returns structured fields",
"tags": ["finance", "documents"]
}
]
}
获取一张卡只需要一个 HTTP GET:
curl https://agent.example.com/.well-known/agent-card.json
调用方拿到卡之后,A2A 通过 JSON-RPC 2.0 定义了任务生命周期:task/send 启动工作,task/get 轮询状态,task/cancel 停止任务,message/send 发送流式更新。任务可以运行几秒钟,也可以运行好几天,协议明确支持长时运行的工作以及流式推送通知。这是一个真正的优势:A2A 为那些异步工作的 agent 而构建,不只是回答问题。
ACP 标准化了另一个边界。它是客户端——一个编辑器、CLI、应用,或者另一个充当客户端的 agent——与单个 agent 之间的协议。A2A 关注的是发现和交接,ACP 关注的则是工作会话的 mechanics:
这个消息流就是它的全部意义。ACP 给你了一种标准方式,将客户端连接到 agent、跨轮次保持状态、并流式返回结果——这就是为什么你在 Gemini CLI 和 AI SDK 生态系统中能看到它的原因。它把" LSP 时刻"的论点应用到了编程 agent 上:一套协议,任何客户端都能驱动任何 agent,而不是每个编辑器都重新实现一遍集成。
关键的认识是,A2A 和 ACP 并不是冗余的——它们是组合关系。
人类使用 IDE 时,是一个 ACP 客户端。一个自主 agent 需要专家来完成一项任务时,是一个 A2A 调用方。没有什么能阻止同一个进程同时扮演两者——也没有什么东西能阻止一个 A2A agent 在与另一个系统对话时充当 ACP 客户端。它们是同一技术栈的不同层,而不是同一个槽位的竞争者。
这里是大多数"A2A vs ACP"文章都会跳过部分。两个协议都是应用层。两个都假设一个可达的端点:稳定的 URL、开放的请求路径、能接收连接的服务器。A2A 的规范说服务器必须暴露一张卡;ACP 的流程假设客户端实际上能够到达 agent 进行认证。
这个假设正是真实 agent 部署中会出问题的地方。Agent 运行在笔记本上、CI runner 里、处于运营商级 NAT 背后的边缘设备上、云端 IP 会轮转的 VM 上。没有入站路径。协议没问题——缺失的是传输层。你无法从一个没有可达地址的 agent 那里获取它的卡。
这正是覆盖网络填补的空白:它给每个 agent 一个永久的虚拟地址,这个地址在重启和 IP 变化后依然存在;加密隧道能穿透 NAT 而无需开放任何端口;还有明确的信任模型,使"可达"和"可信"保持解耦。A2A 和 ACP 这样的协议可以完全像在公共互联网上运行一样,在那个底层之上运行——agent 卡从稳定的覆盖地址提供服务,ACP 会话在同一加密隧道上传输,而且两个协议都不需要关心底层 IP 在凌晨 3 点发生了轮转。
这就是 Pilot Protocol 的 agent 网络设计思路:一个面向 AI agent 的开源覆盖网络——永久地址、NAT 穿透、加密 UDP 隧道——网络上已经有 24.3 万+ 个 agent。它不替换 A2A 或 ACP,它承载它们。可以把它想象成有电话号码(协议)和有一条能在世界任何地方通话的电话线(覆盖网络)之间的区别。
具体来说,流程是这样的。在每个 agent 主机上安装守护进程:
curl -fsSL https://pilotprotocol.network/install.sh | sh
Agent 获得一个地址,通过握手相互发现并建立信任:
pilotctl handshake invoice-agent "task handoff for invoice parsing"
pilotctl send-message invoice-agent --data '{"card": true}'
从那里开始,A2A 卡从覆盖地址提供服务,客户端和 agent 之间的 ACP 会话运行在同一条隧道上——无需端口转发、无需公网 IP、无需维护 webhook 中继。协议层完全按照规范保持不变;只有底层的传输层发生了变化。
别再问哪个 Google 协议会赢了——它们并不竞争。A2A 掌管发现和 agent 间任务;ACP 掌管客户端会话和认证。两者都是应用层,而且都假设了一种大多数 agent 部署实际上并不具备的传输层。如果你的 agent 之间无法互通,协议不是问题所在——传输层才是。先把那一层修好。
开始使用:运行 curl -fsSL https://pilotprotocol.network/install.sh | sh,然后在 pilotprotocol.network/docs 阅读文档。