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

[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 AgentCardAgentCard是一个 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]; mapstring, 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/descriptionAgent的名字和功能描述。这是给人或AI阅读的帮助理解这个Agent能干什么supported_interfacesAgent支持的接口协议providerAgent的提供者信息包括名称、URL和联系信息version版本号用于管理升级和兼容性icon_url/documentation_url提供视觉标识图标和更详尽的开发者文档链接capabilitiesA2A协议定义的标准能力集比如是否支持异步回调、流式传输等技术特性security_schemes/security_requirements定义可选的加密或认证方案以及实际连接时必须满足的安全要求default_input_modes/default_output_modes默认输入输出数据的媒体类型, 比如文本、图片、音频和视频等skills这是最核心的部分描述了Agent擅长的具体业务领域。这通常比description更结构化便于其他Agent动态发现并调用signaturesJSON Web Signatures (JWS)用于验证这份AgentCard确实是由声明的发布者签名的防止身份伪造或元数据被篡改2.2.1 AgentInterfaceAgentInterface是A2A协议中描述一个Agent如何被找到以及如何被调用的核心元数据结构message AgentInterface { string url 1 ; string protocol_binding 2 ; string tenant 3; string protocol_version 4 ; }消息成员说明如下url定义了Agent的物理接入点;protocol_binding指明共同语言。A2A是协议中立的支持GRPC、JSON-RPC和HTTP JSON/REST。这意味着不同技术栈的租户系统可以通过统一的接口定义进行对接tenant可选字段表示这个接口所属的租户用于多租户环境下的隔离和访问控制protocol_version可选字段表示这个接口支持的协议版本以便于兼容性管理2.2.2 AgentProviderAgentProvider在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 AgentCapabilitiesAgentCapabilities定义了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 SecurityRequirementSecurityScheme是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 APIoauth2_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 { mapstring, StringList schemes 1; }SecurityRequirement的核心是一个mapstring, StringList这种结构具有特殊的逻辑含义Key (string): 对应之前定义的SecurityScheme的名称。例如api_key_auth或google_oauthValue (StringList): 一个字符串列表代表该鉴权方式下所需的Scopes。OAuth2/OIDC通常是具体的权限名如[read:pets, write:pets];API Key/Basic Auth对于这些不支持Scopes的方案该列表通常为空;2.2.5 AgentSkillAgentSkill定义了Agent的技能或能力单元。如果说AgentCapabilities是Agent的硬件参数那么AgentSkill就是它安装的软件应用。通过AgentSkillAgent可以向外宣告“我能处理什么任务、需要什么输入、会产出什么结果”。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/jsonsecurity_requirements调用这个技能时需要满足的安全要求。这允许Agent在暴露技能时指定访问控制策略确保只有授权的Agent或用户才能调用这个技能2.2.6 AgentCardSignatureAgentCardSignature负责为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之间的一次通信。它包含角色user或agent和唯一的消息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 ArtifactArtifact在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/descriptionArtifact的名称和功能描述。这些信息对于理解这个产出物的用途和内容至关重要parts构成这个Artifact的内容部分。每个Part可以包含不同类型的数据文本、图像、结构化数据等使得Artifact能够支持多模态的结果展示metadata一个结构化的键值对集合用于携带与这个Artifact相关的上下文信息。这些信息可以用于分类、搜索、调试等目的extensions一个字符串列表指明这个Artifact使用了哪些协议扩展。这允许系统在不修改核心协议的情况下添加新的功能或特性