现代复杂 AI 系统常由多个各司其职的专家智能体协同组成(例如在企业商品知识助手中,分别设立商品搜索、关联推荐、库存核查与订单处理智能体)。在实际工程中,这些智能体可能由不同团队使用不同开发框架(如 LangGraph、CrewAI 或 Google ADK)甚至不同编程语言构建。此前课程已使用 LangGraph 与 Agentic RAG 实现了商品库存与评论检索,本周将结合 CrewAI 引入购物车与订单智能体,并重点探讨如何通过标准化的 Agent-to-Agent(A2A)通信协议将这些异构智能体安全、可靠地连接起来。
此前课程已经使用 LangGraph、Agentic RAG 等构建智能体,并实现库存和用户评论搜索。本周将使用 CrewAI 增加购物车或订单智能体,同时研究如何连接这些组件,以及 A2A 通信的含义和必要性。
什么是 Agent-to-Agent(A2A)通信?
A2A 通信是指自主 AI 智能体之间直接交换结构化消息以协作完成任务的过程:一个智能体可以像微服务调用一样,向另一个智能体发起任务请求或索取信息;接收方智能体作为具备内部推理与决策能力的独立服务,接收请求、调用自身工具完成处理并返回结果。
Google 于 2025 年 4 月与多家合作伙伴发布 Agent2Agent 开放协议,目标是让不同平台和框架中的智能体通过共同规则安全协作。智能体能够作为独立参与者交换任务,这对于组织跨多个 AI 组件的复杂流程很重要。
2025 年 4 月,Google 联合多家行业合作伙伴正式发布了开放的 Agent2Agent(A2A)协议,旨在让运行在不同平台与框架上的智能体能够遵循统一的通信规范安全协作。完整的 A2A 协议涵盖了能力发现(Agent Card)、支持多模态内容的结构化消息交换、长耗时任务的生命周期与进度同步,以及身份认证与安全机制;其底层构建在成熟的现代网络标准之上(不同版本支持 JSON-RPC、HTTP/JSON 等传输绑定),可直接复用企业现有的网络与安全基础设施。
为什么需要 A2A 通信与跨框架互操作?
拆分多个专业智能体提升了系统的模块化程度,但也带来了跨组件集成成本:如果缺乏统一的通信协议,每两对智能体之间都需要单独定制一套 HTTP 接口、JSON 字段格式与错误处理逻辑,维护成本会随智能体数量增长而急剧膨胀。
引入 A2A 统一协议后,任何兼容该协议的智能体均可直接对话,无需逐对编写专用适配器。这对于异构多智能体系统尤为关键:例如由 Python + LangGraph 编写的顶层 Supervisor 智能体,可以通过标准 A2A 消息将“创建商品订单”子任务直接委派给运行在另一套环境中、由 CrewAI 构建的 Ordering Agent,并接收结构化的订单确认结果。
购物助手最终可能包含 Supervisor、Ordering、Shopping Cart 和 Product Search 等角色。监督者需要将子任务交给专家,再汇集结果。A2A 为每个专家提供明确服务接口,例如向 Ordering Agent 提交商品订单任务,并接收结构化结果。系统由此能够通过标准消息完成委派。
异构智能体之间的互操作
互操作意味着不同系统能够共同工作并理解彼此。A2A 通过消息格式和交互规则连接不同框架或语言实现的智能体。
例如,LangGraph 管理者可以调用 CrewAI、Google ADK 或其他框架构建的服务。内部逻辑可以完全不同,只要双方遵循同一协议版本及对应消息结构,就可以交换请求和结果。
互操作通常需要考虑以下方面。
- 统一数据格式:采用 JSON 等通用序列化格式,并共同遵守约定的请求与响应 schema。
- 统一传输协议:通过标准的 HTTP(S) 或 JSON-RPC 接口收发网络消息。
- 明确的身份与能力发现:每个智能体公开声明自身身份与可承接的任务范围(在 A2A 协议中通过 Agent Card 描述自身能力与服务端点),支撑动态发现与任务路由。
- 一致的业务语义:收发双方对任务名称(如
PlaceOrder)及参数、返回字段的业务含义保持完全一致的理解。
这些约定使异构智能体可以组成相互连接的系统。用户看到的是能够处理完整请求的购物助手,无需了解内部如何交接任务。统一接口也能减少组件之间的直接依赖。
设计简化的智能体通信协议(教学示例)
为了直观理解跨智能体通信的核心要素(发送方身份、接收方标识、任务意图与结构化参数),下面先展示一个基于 HTTP/JSON 的简化教学协议(该格式仅用于教学演示概念,正式的 A2A 生产实现需严格遵循对应版本的官方规范 schema)。
简化协议的消息体可包含以下核心字段:
sender:发送方智能体的名称或 ID(如LangGraphSupervisorAgent),用于日志记录与回复路由(注意:消息体内的字符串标识仅用于路由与记录,真实身份认证必须由传输层与协议安全机制独立完成)。recipient:可选的接收方标识(如CrewAIOrderingAgent)。虽然点对点 HTTP 请求的目标 URL 通常已决定了接收方,但在经过网关中转或单端点托管多个智能体时,显式声明接收方非常有帮助。task(或action):请求执行的操作短名称(如PlaceOrder、GetReviews或CheckInventory),类似于 RPC 方法名。parameters(或payload):执行该任务所需的业务参数字典(如商品 SKU、购买数量、用户 ID 等),接收方智能体拿到参数后可在内部自主调用多个工具完成任务。task_id:教学协议中可选的任务关联 ID,用于将请求、响应与重试记录关联起来(在正式 A2A 协议中,对taskId、messageId及传输层请求 ID 的生成方与生命周期均有严格区分)。- 其他可选元数据:如时间戳、任务优先级或单向通知标记。
请求消息示例
{
"sender": "LangGraphSupervisorAgent",
"recipient": "CrewAIOrderingAgent",
"task": "PlaceOrder",
"parameters": {
"item_id": "SKU-12345",
"quantity": 2,
"user_id": "user-001"
}
}LangGraphSupervisorAgent 请求 CrewAIOrderingAgent 代表用户 user-001 下单购买 2 件 SKU-12345 商品:
响应消息示例:Ordering Agent 完成请求后,可以返回以下 JSON。
{
"sender": "CrewAIOrderingAgent",
"recipient": "LangGraphSupervisorAgent",
"task": "PlaceOrder",
"status": "success",
"result": {
"order_id": "ORDER-12345",
"status": "confirmed",
"estimated_delivery": "2025-08-01"
}
}响应说明发送方,并可选地标记接收者;在 HTTP 响应中,接收者通常由原请求确定。task 关联操作,status 表示成功或错误。成功时,result 包含订单号、确认状态和预计配送日期等信息。失败时可以返回 "status": "error",以及说明缺货等原因的 error_message。
这一教学格式体现以下概念。
- 智能体身份:标记消息的发送者和接收者,支持路由。
- 任务委派:
task明确需要另一智能体完成的工作,监督者可以将复杂请求分为多个任务。 - 结构化数据:JSON 支持嵌套参数和结果,便于解析与处理。正式协议也可以承载多模态内容及流式更新。
- 通用格式:双方约定新任务名称、参数和结果后,可以沿用相同消息结构。
生产环境设计中的核心挑战
生产环境中的通信还需要考虑状态、错误、监控和安全。
1. 无状态(Stateless)与有状态(Stateful)通信
无状态交互:每次请求都完整携带执行任务所需的全部上下文,接收方智能体无需在本地记住历史请求。这种模式天然契合常规 HTTP 负载均衡,任一实例故障均可由其他副本无缝接管,适合短平快的单次请求—响应任务。
有状态交互:在多条往返消息之间持续维护同一个任务的背景状态(例如耗时较长的深度调研、需要多轮补充澄清的任务或流式进度推送)。在 A2A v1.0.1 规范中,任务唯一标识 taskId 由服务端创建,客户端通过引用该 taskId 查询进度、接收增量更新或补充后续参数;而单条消息标识 messageId 则由消息创建方生成。架构设计时需明确界定状态由远端智能体持久化保存还是由调用方每次重传,也可采用“短任务走无状态、长任务分配 taskId 走有状态轮询/流式推送”的混合模式。
快速的一次请求与响应通常适合无状态设计;长时间研究、多轮澄清或流式结果则需要保存相关状态。例如,监督者提交任务后,可以查询进度、接收更新,或提供后续参数。
应根据需求明确状态保存者和生命周期:远程智能体保存上下文,还是调用者每次重新发送。也可以采用混合设计,多数任务一次完成,长任务先创建标识,再通过后续调用查询状态或获取结果。
2. 错误处理、超时与幂等重试
网络故障、服务不可用、输入不合法或内部错误都可能使调用失败。可靠设计需要以下机制。
- 结构化错误响应:调用方必须检查每次响应的状态码与业务错误原因(如收到
Ordering Agent返回的“缺货”错误后,由监督者向用户询问是否更换商品)。 - 超时:设置合理等待时间。超时表示调用者未及时收到结果;具有副作用的操作可能已经执行,因此不能直接推断订单没有创建。
- 重试与幂等:暂时网络问题可以重试,但重复
PlaceOrder不应创建多份订单。可以使用唯一业务请求标识或其他幂等机制,由接收者识别已处理请求,并核查不确定结果。 - 替代处理:主服务无法完成任务时,可以使用具备相同能力的其他智能体,但需要发现和路由逻辑,并确保不会重复执行已经成功的操作。
日志与监控
多智能体通信增加调试复杂度,因此需要清楚记录每次交互。
- 请求与响应:至少记录必要概要,调试模式可以记录适当的详细信息,以便还原消息往来。
- 关联 ID:双方日志使用共同请求、任务或订单标识,追踪任务经过的多个系统。
- 监控指标:记录委派数量、成功率、失败率和响应延迟,识别性能瓶颈,例如订单服务平均响应时间持续增加。
- 可观测性工具:网关或中间层可以捕获分布式追踪,利用传输头等机制关联不同服务,显示请求传播时间线。
- 审计:涉及敏感任务时,记录谁提出请求以及最终执行结果。
日志应便于人类阅读,也应支持机器筛选,例如使用 JSON 或键值记录,同时避免记录敏感内容。
其他考虑
- 安全:验证智能体身份并授权具体任务。Agent Card 可以声明所需认证方案,生产通信应使用适当的安全传输和凭据管理。Ordering Agent 必须检查调用者是否有权执行请求;消息中的
sender字符串不能代替认证。 - Schema 演进:修改消息格式或新增任务时,需要版本管理及兼容策略。例如,声明协议版本,并明确未知字段的处理方式。
- 性能:序列化与网络往返会增加开销。通信过于频繁时,可以结合任务或缓存结果。
- 测试:将智能体接口视为公共 API,测试给定请求能否返回预期结果,并检查监督者如何处理成功、失败和异常响应。测试替身可用于隔离接口测试,实际服务集成仍需独立验证。
A2A 协议的角色划分与 Agent Card 发现机制
在正式 A2A 协议中,智能体在不同交互中可灵活切换客户端或服务端角色:
- User(用户):发起原始目标或请求的人类用户(或上游外部系统)。
- A2A Client(客户端):代表用户或上游智能体构造任务请求、发现合适的远程智能体并按协议发送消息。
- A2A Server(服务端):暴露符合 A2A 规范的服务端点,接收任务并返还执行结果与状态更新。
Agent Card 与服务发现
在发起通信前,客户端需要先获知远程智能体具备哪些能力以及如何访问。A2A 协议通过机器可读的 JSON 元数据文档——Agent Card(智能体名片)来实现服务发现:
https://{agent_host}/.well-known/agent.json在 A2A v1.0.1 规范中,标准自动发现路径统一为 /.well-known/agent-card.json(此外也支持通过企业内部智能体注册目录、预先配置或 MCP 资源渠道分发 Agent Card)。在 v1.0.1 中,Agent Card 通过 supportedInterfaces 声明访问 url、protocolBinding(协议绑定)与 protocolVersion(协议版本),并通过 securitySchemes 与 securityRequirements 声明认证要求。
一份 Agent Card 通常包含以下核心元数据(具体字段名、是否必填及结构均以实际采用的协议版本 schema 为准):
name:便于人类理解的名称。name与description:人类可读的智能体名称及其职责、领域说明。url:早期格式中的服务地址;较新版本可以通过支持接口列表描述地址及协议绑定。version:智能体自身的实现版本号。capabilities:声明是否支持流式输出(streaming)、主动推送通知(pushNotifications)等特性(早期示例还包含stateTransitionHistory)。skills:该智能体可承接的高层技能列表,每项技能通常包含id、name、description、支持的输入/输出模态(inputModes/outputModes)及可选示例(examples)。defaultInputModes与defaultOutputModes:默认支持的输入与输出内容 MIME/模态类型。- 协议与端点:公开支持的协议版本和访问接口。应用扩展有时使用
supportedProtocols或endpoints等名称,这些名称不能直接视为所有 A2A 版本共有的字段;早期文档中的/tasks/send也应结合相应绑定理解。 - 认证要求与附加信息:早期教学示例使用
authentication字段,正式版本则按规范使用对应的安全方案字段声明所需的 API Key 或 OAuth 认证方式,并可附带服务提供方、组织名称与文档链接。 - 其他资料:服务提供者、组织、文档地址,以及协议允许的扩展信息。
早期 Agent Card 结构示例(历史教学格式)
以下 JSON 展示了一个订单智能体的早期教学版 Agent Card 结构,用于直观理解身份、能力与技能的组织方式(生产环境实现时需按所选规范版本转换字段并执行 schema 校验):
{
"name": "Example Order Agent",
"description": "An agent that manages warehouse inventory and performs Orders.",
"url": "https://order.swirlai.com/agent",
"version": "1.0.0",
"capabilities": {
"streaming": false,
"pushNotifications": false,
"stateTransitionHistory": true
},
"authentication": {
"schemes": []
},
"defaultInputModes": ["text"],
"defaultOutputModes": ["text"],
"skills": [
{
"id": "order_creation",
"name": "Order Creator",
"description": "Creates orders based on the item requests received.",
"inputModes": ["text"],
"outputModes": ["text"]
}
]
}在 A2A v1.0.1 中,JSON-RPC 绑定下的发送方法名为 SendMessage,HTTP/JSON 绑定下则使用 POST /message:send。详细字段与接口定义请参阅 A2A v1.0.1 规范,协议的后续演进可查阅 A2A 最新规范。
按协议交换知识查询任务
在课程企业知识系统中,将 A2A 作为跨智能体任务协作的开放通信协议,并在工程实现中明确固定所支持的规范版本号。跨智能体传递的任务消息需携带查询内容及当前用户获准访问的资料范围,接收端智能体在执行前必须重新校验调用方身份、任务时限与用户级资料访问权限。架构分工上,底层工具与数据源访问统一使用 MCP,跨智能体任务委派与协作使用 A2A;再次强调,无论是 MCP 还是 A2A,通信协议本身都不会自动赋予飞书等业务系统的资料访问权限。
练习:记录本课所用配置、输入、预期结果与失败分支,并用脱敏数据复现。