A2A 协议落地 —— 从“前瞻设计“到“标准化接入“
讨论 MCP 时我们用标准协议替代手写胶水解决工具暴露问题。但那是纵向的——Agent 怎么调用工具。本文讨论横向的问题当有多个 Agent 要相互协作或者外部系统想把 Shop-Agent 当成一个黑盒能力直接调用时他们怎么发现 Shop-Agent 能做什么、怎么把任务提交给它、怎么拿到结果答案是 A2AAgent-to-Agent协议。与 MCP 一样A2A 本身不是功能是接口标准化——它不替代业务逻辑但让业务逻辑能被更多人、更多系统发现和使用。先看问题外部系统怎么用 Shop-Agent在没有标准协议之前外部系统要集成 Shop-Agent 只有两条路直接调 HTTP API看源码找到对话端点自己构造请求体、解析响应格式。问题是这套接口是为人设计的——同步阻塞、一次一问、没有任务概念。用 WebSocket更低延迟但协议完全自定义。两个方案的共同问题没有人能仅凭标准约定就知道 Shop-Agent 对外暴露了什么。你永远需要看源码或文档——这就是胶水。A2A 的核心价值不在于更快或更准在于让机器通过标准协议自动发现和调用 Agent。A2A 协议的四层设计以 Google A2A 规范为参考实现了四层P0 异步任务提交任务并返回task_id支持轮询结果和取消——区别于同步 HTTP API 的核心能力。P1 Webhook任务完成后主动回调订阅方HMAC 签名防伪造替代高频轮询。P2 对话共享外部系统可拉取历史消息让多个 Agent 读同一段上下文避免重复提问。P3 健康检查不只报告进程存活性对 LLM、向量库、Redis、MCP Server 逐一做依赖探测。配合Agent CardGET /.well-known/agent-card.json外部系统在访问任何业务 API 之前就先知道这个 Agent 叫什么、能做什么、能力边界在哪。核心设计决策实现中几个关键决策值得展开聊聊——不是怎么写而是**“为什么这么选”**。1. Agent Card 与 MCP 的数据同源Agent Card 和 MCP 的tools/list都在描述Shop-Agent 能做什么——如果两套描述来自不同数据源早晚会不一致。所以Agent Card 的 skill 列表直接从SkillRegistry生成与 MCP 共享同一份数据。skills/目录下的 Markdown 文件是唯一的 truth source加一个 skill 两处自动同步。Card 里除了 skill 列表还声明了capabilities.asyncTaskstrue——这是 A2A 协议区别于普通 REST API 的关键字段。外部系统看到它就明白任务异步执行需要轮询或等 Webhook 回调。首次构建触发冷启动之后内存缓存命中——对 discovery 端点来说足够了。2. 异步任务的薄壳模式A2A 的任务 API 不是另起炉灶重写一套 Agent 调用逻辑。提交任务后立即创建任务记录状态pending返回task_id然后在后台异步调已有的对话服务。这是刻意为之——只在现有同步调用外面包一层异步外壳。好处很明显A2A 层薄到不需要维护自己的 Agent 逻辑所有意图识别、路由、工具调用的改进自动对 A2A 入口生效。任务状态机只有五个值pending → running → completed | failed | cancelled。cancelled是终态不可恢复。列表接口支持分页当前使用内存存储。3. Webhook 与轮询的取舍轮询方案最简单每 N 秒查一次任务状态。但高频轮询浪费带宽低频轮询增加端到端延迟。Webhook 是 push 模式——任务完成后主动 POST 到订阅方。代价是订阅方需要暴露 HTTP 端点而且需要防止伪造回调。所以加上了 HMAC-SHA256 签名注册时提供secret每次回调在X-A2A-Signature头携带签名。订阅有 TTL 过期机制内部定时清理。两个方案不是非此即彼——A2A 协议同时支持轮询和 Webhook集成方按自己的场景选择。轻量集成比如脚本用轮询生产级集成n8n、Dify用 Webhook。4. 对话共享A2A 层的公共存储多 Agent 协作有一个常见痛点BuyerAgent 问了用户订单号轮到 MediatorAgent 时又要再问一遍。A2A 层的对话共享就是解这个的——每次对话完成后自动存入公共存储外部系统通过 API 拉取历史。公共存储根据数据特点保存到 Redis 或数据库中。5. 健康检查与服务降级健康检查对 LLM、向量库、Redis、MCP Server 等依赖做独立探测返回各自状态。上游编排系统可据此做降级路由——比如 LLM 不可用时暂停任务分发、向量库断连时 RAG 退化为纯 BM25。A2A MCP 的职责边界这两个协议经常被放在一起讨论但它们的职责完全不重叠业务逻辑层SkillRAGDisputeCoordinatorEmotion DetectionMCP 层 — Agent → Tool工具暴露资源访问Schema 自描述A2A 层 — Agent ↔ Agent发现提交任务轮询WebhookA2A 管谁跟谁说话——发现 Agent、提交任务、等结果。MCP 管手里有什么工具——列出工具、调工具、取资源。两层互不重叠A2A 不关心 ReActAgent 调了哪个 toolMCP 不关心任务是谁提交的。MCP 和 A2A 不能提升意图识别准确率不能降低 RAG 延迟。它们解决的是另一个层级的问题当你把系统做完了谁能看见它如果没有标准协议答案是只有你自己——因为别人要读懂你的源码才知道怎么调用你。有了 MCP 和 A2A任何遵循相同协议的系统都可以自动发现你、调用你——不需要看源码不需要写胶水。配合 MCP 实践MCP 管纵向Agent → ToolA2A 管横向Agent → Agent两协议构成了 Shop-Agent 的标准化层。接入成本从读源码翻文档降为读一张 Agent Card 调一次tools/list。实现上有一条核心原则值得单拎出来A2A 是对外的门不是对内的水管道。ReActAgent ↔ ToolService 同进程内走直接函数调用就够了——不必把 JSON-RPC 序列化强塞进进程内部。反过来也没有把DisputeCoordinator内部的 BuyerAgent/SellerAgent/MediatorAgent 拆成独立进程走 A2A 通信——因为它们在同一进程中闭环拆了只增加网络开销没有显性收益。知道什么时候不用一个协议和知道什么时候用它一样重要。