news 2026/5/16 13:35:12

[A2A协议与实现-01]借助A2A协议打破智能体孤岛

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
[A2A协议与实现-01]借助A2A协议打破智能体孤岛

A2A协议是一个开放标准,它实现了Agent之间的无缝通信和协作。它为使用不同框架和由不同供应商构建的Agent提供了一种通用语言,从而促进了互操作性并打破了信息孤岛。A2A协议使得来自不同开发者、基于不同框架构建、并由不同组织拥有的Agent能够联合起来协同工作。Agent2Agent (A2A) Project提供了针对不同语言(Python、TypeScript、Java、Go、C#和Rust等)的SDK,我们不仅仅可以利用它们构建A2A Server,还能利用它们提供的客户端组件以A2A协议调用Agent。接下里的内容将以A2A Spec为核心,也会介绍Python SDK针对A2A协议的实现。

1. 为什么需要A2A协议?

A2A旨在解决Agent协作问题,并为Agent间的交互提供标准化的方法。假设用户请求Assistant帮忙规划一次国际旅行。这项任务需要协调多个专业Agent,例如:

  • 机票预订Agent
  • 酒店预订Agent
  • 当地旅游推荐Agent
  • 货币兑换Agent

如果没有A2A,整合这些不同的Agent将面临诸多挑战:

  • Agent暴露:对于两个A和B两个Agent,如果A需要调用B,需要将针对B的调用封装在一个工具中,采用类似于基于MCP的Multi-Agent解决方案。但是这种利用工具封装Agent的方式不仅繁琐还抵消,限制了Agent的复用。A2A允许Agent直接暴露,让Agent之间直接通信,无需封装;
  • 定制集成:每次交互都需要定制的点对点解决方案,造成巨大的工程开销;
  • 可扩展性问题:随着Agent和交互数量的增长,系统难以扩展和维护;
  • 互操作性:这种方法限制了互操作性,阻碍了复杂人工智能生态系统的自然形成;
  • 安全漏洞:临时通信往往缺乏一致的安全措施;

对于用户向Assistant发出的一条复杂的指令,比如“计划一次国际旅行”。Assistant接收到提示后,意识到需要多个Agent相互协作才能完成这个规划任务。这个应用场景的核心问题在于:由于每个Agent都有其独特的开发和部署方式,在缺乏标准化协议的前提下,它们根本无法协同工作。

A2A协议为Agent之间通信提供了标准方法和数据结构,无论其底层实现如何。A2A让这些Agent可以在一个互联系统中使用,它们之间采用标准化协议无缝通信。有了A2A的支持,这个Assistant可以作为协调者,直接向机票预订Agent、酒店预订Agent、当地旅游推荐Agent和货币兑换Agent发出请求。每个Agent根据自己的专业领域处理请求,并将结果返回给Assistant。Assistant最后将整合这些信息,向用户提供完整的旅行计划。

实施A2A协议可为整个AI生态系统带来显著优势:

  • 安全协作:如果没有统一的标准,就很难确保Agent之间的安全通信。A2A使用HTTPS进行安全通信,并保持操作的不透明性,因此Agent在协作过程中无法看到其他Agent的内部运作;
  • 互操作性:A2A打破了不同Agent生态系统之间的壁垒,使来自不同供应商和框架的Agent能够无缝协作;
  • Agent自主性:A2A允许多个Agent协同工作的同时,作为一个自主的实体独立运行;
  • 降低集成复杂性:该协议标准化了Agent通信,使团队能够专注于其Agent提供的独特价值;
  • 支持长耗时操作:该协议支持长时间运行操作 (LRO)、基于服务器发送事件 (SSE) 的流式传输以及异步执行;

2. A2A核心概念

A2A使用一系列核心构建块(Building Block)来定义Agent之间的交互方式,只有深刻地理解它们才能开发或集成符合A2A标准的系统。由于Google是A2A协议的主要推动者,所以整个A2A Spec采用自家的Protobuf来定义,这些构建块在协议中大都以Protobuf消息的形式定义。

2.1 核心参与者和交互方式

A2A协议定义了如下三个核心参与者:

  • 用户:可以是人工操作员,也可以是自动化服务。用户发起请求或定义目标,这些请求或目标需要一个或多个Agent的协作完成;
  • 客户端:作为消费者的Agent或者应用,代表发起请求的那一方;
  • 服务器:部署Agent的服务器,它采用基于A2A协议的Endpoint将Agent暴露出来,等待客户端的调用;

A2A协议支持多种交互模式,以满足不同的响应速度和持久性需求。这些机制确保Agent能够高效可靠地交换信息,无论任务的复杂性或持续时间如何:

  • 请求/响应(轮询):客户端发送请求,服务器做出响应。对于长时间运行的任务,客户端会定期轮询服务器以获取更新;
  • 使用SSE进行流式传输:客户端发起流式传输,通过打开的HTTP长连接从服务器接收实时、增量的结果或状态更新;
  • 推送通知:客户端暴露一个接收通知的Endpoint,并将对应的URL提供给服务器,服务器在任务完成或状态发生变化时向该URL推送通知;

2.2 多租户的设计

A2A采用多租户(Multi-Tenancy)设计解决企业级场景下多客户隔离、多环境托管以及复杂的资源路由问题。在多租户环境下,Agent往往需要代表特定的企业或用户行事。A2A协议通过JWT或类似的凭证机制,将租户上下文注入到Agent间的交互中。这就要求所有参与协作的Agent在处理和解析租户信息时必须保持一致性,并且每个Agent在接收任务时,必须能够通过该上下文识别出当前的租户身份,从而确保其调用的工具和访问的数据仅限于该租户范围内。由于Agent可能由不同的供应商构建并部署在不同的云环境中,租户设计遵循以下原则:

  • 独立解析:每个Agent独立负责解析收到的身份信息并授权访问,而不依赖于一个单一的中心化网关;
  • 凭证外置:A2A协议本身不强制规定某种特定的认证流程,而是允许客户端通过 OAuth 2.0、API密钥等外部机制获取所需的租户凭证;

租户被视为一等公民,所以你会发现A2A协议中的许多消息类型都包含一个可选的tenant字段。这些字段允许Agent在处理请求时识别和区分不同的租户,从而实现更细粒度的访问控制和资源管理。

2.2 AgentCard

AgentCard是一个 JSON文档,相当于Agent的数字名片。客户端解析这些信息,以确定Agent是否适合特定任务、如何构建请求以及如何进行安全通信。AgentCard通过如下这个Protobuf消息类型进行定义:

message AgentCard { string name = 1 [(google.api.field_behavior) = REQUIRED]; string description = 2 [(google.api.field_behavior) = REQUIRED]; repeated AgentInterface supported_interfaces = 3 [(google.api.field_behavior) = REQUIRED]; AgentProvider provider = 4; string version = 5 [(google.api.field_behavior) = REQUIRED]; optional string documentation_url = 6; AgentCapabilities capabilities = 7 [(google.api.field_behavior) = REQUIRED]; map<string, SecurityScheme> security_schemes = 8; repeated SecurityRequirement security_requirements = 9; repeated string default_input_modes = 10 [(google.api.field_behavior) = REQUIRED]; repeated string default_output_modes = 11 [(google.api.field_behavior) = REQUIRED]; repeated AgentSkill skills = 12 [(google.api.field_behavior) = REQUIRED]; repeated AgentCardSignature signatures = 13; optional string icon_url = 14; }

消息成员说明如下:

  • name/description:Agent的名字和功能描述。这是给人或AI阅读的,帮助理解这个Agent能干什么;
  • supported_interfaces:Agent支持的接口协议;
  • provider:Agent的提供者信息,包括名称、URL和联系信息;
  • version:版本号,用于管理升级和兼容性;
  • icon_url/documentation_url:提供视觉标识(图标)和更详尽的开发者文档链接;
  • capabilities:A2A协议定义的标准能力集,比如是否支持异步回调、流式传输等技术特性;
  • security_schemes/security_requirements:定义可选的加密或认证方案,以及实际连接时必须满足的安全要求;
  • default_input_modes/default_output_modes:默认输入输出数据的媒体类型, 比如文本、图片、音频和视频等;
  • skills:这是最核心的部分,描述了Agent擅长的具体业务领域。这通常比description更结构化,便于其他Agent动态发现并调用;
  • signatures:JSON Web Signatures (JWS),用于验证这份AgentCard确实是由声明的发布者签名的,防止身份伪造或元数据被篡改;
2.2.1 AgentInterface

AgentInterface是A2A协议中描述一个Agent如何被找到以及如何被调用的核心元数据结构:

message AgentInterface { string url = 1 ; string protocol_binding = 2 ; string tenant = 3; string protocol_version = 4 ; }

消息成员说明如下:

  • url:定义了Agent的物理接入点;
  • protocol_binding:指明共同语言。A2A是协议中立的,支持GRPCJSON-RPCHTTP + JSON/REST。这意味着不同技术栈的租户系统可以通过统一的接口定义进行对接;
  • tenant:可选字段,表示这个接口所属的租户,用于多租户环境下的隔离和访问控制;
  • protocol_version:可选字段,表示这个接口支持的协议版本,以便于兼容性管理;
2.2.2 AgentProvider

AgentProvider在A2A协议中负责标识Agent的服务提供商信息。这就像是给每个Agent贴上的一张名片,用于明确该Agent背后的主体身份:

message AgentProvider { string url = 1 ; string organization = 2 ; }

消息成员说明如下:

  • url:提供商的官方网站或技术文档地址(比如https://ai.google.dev),让其他Agent或开发者能够追溯到该AI服务的来源,获取更多的技术说明或服务协议;
  • organization:提供商的组织或公司名称(例如Google),建立信任基础。在Multi-Agent协作中,知道对方是谁开发的(如OpenAI,Anthropic,Google等)对于权限管理和合规性至关重要;
2.2.3 AgentCapabilities

AgentCapabilities定义了Agent的功能清单。在 A2A协议中,当两个Agent进行握手或初次接触时,通过交换这个消息来告知对方:“我能做什么,我支持哪些高级特性?”

message AgentCapabilities { optional bool streaming = 1; optional bool push_notifications = 2; repeated AgentExtension extensions = 3; optional bool extended_agent_card = 4; }

消息成员说明如下:

  • streaming:是否支持流式响应。如果设为True,当一个Agent回答很长的问题时,它可以像ChatGPT那样一个字一个字地吐出结果,而不是等全部生成完了再一起发过去。这能显著降低用户的感知延迟;
  • push_notifications:是否支持基于web-hook的通知推送。主要用于异步任务。例如,你让一个Agent去订一张下周的机票,这个过程可能需要几分钟。支持该功能的Agent可以在处理完成后主动“弹窗”提醒你,而不需要你一直挂着连接等待;
  • extensions:支持的协议扩展列表。这提供了一个插件系统。如果基础协议不能满足特定行业(如医疗、金融)的需求,Agent可以通过这个字段声明它支持哪些自定义的扩展子协议;
  • extended_agent_card:是否支持在身份验证后提供扩展AgentCard片。通常用于展示更详细的身份信息、专有工具集或品牌展示。为了隐私保护,这些丰富的信息只有在对方通过身份验证(Authenticated)后才会展示;
2.2.4 SecurityScheme & SecurityRequirement

SecurityScheme是A2A协议中负责安全与鉴权的核心定义。它的设计直接参考了OpenAPI 3.2规范,采用Protobuf的oneof结构来实现判别式联合类型。简单来说,这个消息决定了Agent之间如何确认身份

message SecurityScheme { oneof scheme { APIKeySecurityScheme api_key_security_scheme = 1; HTTPAuthSecurityScheme http_auth_security_scheme = 2; OAuth2SecurityScheme oauth2_security_scheme = 3; OpenIdConnectSecurityScheme open_id_connect_security_scheme = 4; MutualTlsSecurityScheme mtls_security_scheme = 5; } }

消息成员说明如下:

  • api_key_security_scheme:通过在Header、Query参数或Cookie中传递一个特定的字符串(如X-API-Key)。这是最简单直接的鉴权方式,常用于轻量级的工具调用;
  • http_auth_security_scheme:标准的HTTP认证,如 Basic Auth(用户名/密码)或Bearer Token(通常是JWT令牌)。这种方式广泛应用于Web API;
  • oauth2_security_scheme:复杂的OAuth 2.0授权流。当一个Agent需要代表用户访问第三方资源,通常需要这种流程;
  • open_id_connect_security_scheme:基于OAuth 2.0 的身份层(OIDC)。用于跨平台的单点登录(SSO)和更详细的用户身份信息获取;
  • mtls_security_scheme:双向TLS认证。这属于最高安全等级的鉴权,要求通信双方都持有受信任的数字证书,常用于金融或企业级核心通信;

SecurityRequirement定义了访问Agent服务时的具体安全要求。它规定了在调用某个接口时,必须提供哪些安全方案(Schemes)以及这些方案需要具备哪些权限范围(Scopes)。这一设计同样高度对齐了OpenAPI 3.2中的Security Requirement Object。

message SecurityRequirement { map<string, StringList> schemes = 1; }

SecurityRequirement的核心是一个map<string, StringList>,这种结构具有特殊的逻辑含义:

  • Key (string): 对应之前定义的SecurityScheme的名称。例如:api_key_authgoogle_oauth
  • Value (StringList): 一个字符串列表,代表该鉴权方式下所需的Scopes
    • OAuth2/OIDC:通常是具体的权限名,如["read:pets", "write:pets"];
    • API Key/Basic Auth:对于这些不支持Scopes的方案,该列表通常为空;
2.2.5 AgentSkill

AgentSkill定义了Agent的技能或能力单元。如果说AgentCapabilities是Agent的硬件参数,那么AgentSkill就是它安装的软件应用。通过AgentSkill,Agent可以向外宣告:“我能处理什么任务、需要什么输入、会产出什么结果”。

message AgentSkill { string id = 1 ; string name = 2 ; string description = 3 ; repeated string tags = 4 ; repeated string examples = 5; repeated string input_modes = 6;. repeated string output_modes = 7; repeated SecurityRequirement security_requirements = 8; }

消息成员说明如下:

  • id/name/description:技能的唯一标识、名称和功能描述。这些信息对于其他Agent或用户理解这个技能的用途至关重要;
  • tags:技能标签,便于分类和搜索。例如,一个提供天气信息的技能可能会被标记为["weather", "forecast", "temperature"]
  • examples:技能示例,提供一些输入输出的示例对,帮助其他Agent或用户理解如何调用这个技能以及预期的结果是什么;
  • input_modes/output_modes:技能支持的输入和输出媒体类型。例如,输入可能是文本(text/plain)或图像(image/png),输出也可能是文本、图像或结构化数据(application/json);
  • security_requirements:调用这个技能时需要满足的安全要求。这允许Agent在暴露技能时,指定访问控制策略,确保只有授权的Agent或用户才能调用这个技能;
2.2.6 AgentCardSignature

AgentCardSignature负责为Agent的AgentCard提供数字签名,确保其内容在传输过程中未被篡改,并验证其来源的真实性。这个定义严格遵循了RFC 7515 (JWS-JSON Web Signature) 标准。你可以将其理解为Agent名片上的防伪水印数字公章

message AgentCardSignature { string protected = 1 ; string signature = 2 ; google.protobuf.Struct header = 3; }

消息成员说明如下:

  • protected:这是一个Base64URL编码的字符串,包含了签名所使用的算法(如RS256)和其他相关信息。它告诉验证方应该使用什么方法来验证这个签名;
  • signature:这是对AgentCard内容进行签名后的结果,也是一个Base64URL编码的字符串。验证方会使用提供的protected信息来验证这个签名是否有效;

2.3 Message

一条消息代表Agent之间的一次通信。它包含角色(useragent)和唯一的消息ID。它包含一个或多个Part对象,这些对象是实际内容的细粒度容器。这种设计使得A2A可以独立于任何模态。消息通过如下这个同名Protobuf消息类型进行定义:

message Message { string message_id = 1 ; string context_id = 2; string task_id = 3; Role role = 4 ; repeated Part parts = 5 ; google.protobuf.Struct metadata = 6; repeated string extensions = 7; repeated string reference_task_ids = 8; }

消息成员说明如下:

  • message_id:每条消息的唯一标识符,通常由发送方生成。它对于跟踪对话历史、调试和日志记录非常重要;
  • context_id:可选字段,用于将消息关联到特定的上下文或会话中。这对于多轮对话或需要状态管理的交互非常有用;
  • task_id:可选字段,用于将消息关联到特定的任务或操作中。这对于长时间运行的任务或需要异步处理的场景非常有用;
  • role:消息的角色,指明这条消息是由用户还是Agent发送的。这有助于接收方理解消息的来源和意图;
  • parts:消息的内容部分。每个Part可以包含不同类型的数据(文本、图像、结构化数据等),使得消息能够支持多模态交互;
  • metadata:一个结构化的键值对集合,用于携带额外的上下文信息。这些信息可以用于路由、优先级设置、调试等目的;
  • extensions:一个字符串列表,指明这条消息使用了哪些协议扩展。这允许系统在不修改核心协议的情况下,添加新的功能或特性;
  • reference_task_ids:一个字符串列表,包含与这条消息相关的任务ID。这对于跟踪和管理复杂的工作流非常有用,尤其是在涉及多个Agent协作的场景中;

Part是A2A协议中实际对话内容的最小载体。它被设计成一个高度灵活的容器,能够处理从简单的文本对话到复杂的多模态数据(图片、视频、结构化数据)传输。你可以把它想象成电子邮件的一个附件正文片段,多个Part组合在一起就构成了一个完整的消息负载。

message Part { oneof content { string text = 1; bytes raw = 2; string url = 3; google.protobuf.Value data = 4; } google.protobuf.Struct metadata = 5; string filename = 6; string media_type = 7; }

消息成员说明如下:

  • content:这是一个oneof字段,表示Part的内容可以是以下四种类型
    • text:纯文本内容,适用于大多数对话场景;
    • raw:原始二进制数据,适用于图片、音频、视频等多模态内容的传输;
    • url:指向外部资源的URL,适用于大型文件或需要动态访问的数据;
    • data:结构化数据,可以是JSON对象或其他格式,适用于需要传递复杂信息的场景;
  • metadata:一个结构化的键值对集合,用于携带与这个Part相关的上下文信息。这些信息可以用于路由、优先级设置、调试等目的;
  • filename:当Part包含文件内容时,提供文件名以便接收方识别和处理;
  • media_type:指明Part内容的媒体类型(MIME type),如"text/plain""image/png""application/json"等。这有助于接收方正确解析和处理内容;

2.4 Artifact

Artifact在A2A 协议中代表Agent完成任务后生成的产出物中间结果。如果说Part是基础的通信碎片,那么Artifact就是一个完整的逻辑成果包。比如一个调研报告Artifact,可能包含一个PDF文档(Part1)和一份原始数据表格(Part2)。

message Artifact { string artifact_id = 1 ; string name = 2; string description = 3; repeated Part parts = 4 ; google.protobuf.Struct metadata = 5; repeated string extensions = 6; }

消息成员说明如下:

  • artifact_id:每个Artifact的唯一标识符,通常由生成它的Agent创建。它对于跟踪、引用和管理产出物非常重要;
  • name/description:Artifact的名称和功能描述。这些信息对于理解这个产出物的用途和内容至关重要;
  • parts:构成这个Artifact的内容部分。每个Part可以包含不同类型的数据(文本、图像、结构化数据等),使得Artifact能够支持多模态的结果展示;
  • metadata:一个结构化的键值对集合,用于携带与这个Artifact相关的上下文信息。这些信息可以用于分类、搜索、调试等目的;
  • extensions:一个字符串列表,指明这个Artifact使用了哪些协议扩展。这允许系统在不修改核心协议的情况下,添加新的功能或特性;
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/16 13:28:36

ARM Cortex-A72 GICv3中断处理机制与优化实践

1. ARM Cortex-A72 GIC CPU接口架构概述在ARMv8-A架构中&#xff0c;通用中断控制器(GIC)作为中断管理的核心组件&#xff0c;其CPU接口承担着处理器核心与中断源之间的桥梁作用。Cortex-A72处理器实现了GICv3架构规范&#xff0c;相较于前代GICv2&#xff0c;主要引入了以下关…

作者头像 李华
网站建设 2026/5/16 13:27:00

Zstandard技术深度解析:实时压缩算法在现代数据架构中的应用

Zstandard技术深度解析&#xff1a;实时压缩算法在现代数据架构中的应用 【免费下载链接】zstd Zstandard - Fast real-time compression algorithm 项目地址: https://gitcode.com/gh_mirrors/zs/zstd Zstandard&#xff08;zstd&#xff09;是一款由Meta开发的高性能实…

作者头像 李华
网站建设 2026/5/16 13:26:56

Arm Neoverse CMN-650 SLC内存系统架构与错误处理机制详解

1. Arm Neoverse CMN-650 SLC内存系统架构解析在现代多核处理器架构中&#xff0c;系统级缓存&#xff08;SLC&#xff09;作为关键的基础设施&#xff0c;其设计直接影响着整个系统的性能和可靠性。Arm Neoverse CMN-650采用的是一种创新的缓存一致性网状网络&#xff08;Cohe…

作者头像 李华
网站建设 2026/5/16 13:26:15

LiveDraw:Windows平台实时屏幕标注工具的完整使用指南

LiveDraw&#xff1a;Windows平台实时屏幕标注工具的完整使用指南 【免费下载链接】live-draw A tool allows you to draw on screen real-time. 项目地址: https://gitcode.com/gh_mirrors/li/live-draw LiveDraw是一款专为Windows平台设计的实时屏幕标注工具&#xff…

作者头像 李华