A2A 扩展

A2A 协议为智能体之间的通信提供了坚实的基础。但特定领域或高级用例常常需要在通用方法之外增加结构、自定义数据或新的交互模式。扩展(Extensions)正是 A2A 在基础协议之上叠加新能力的强大机制。

扩展可以为 A2A 协议增加新的数据、要求、RPC 方法和状态机。智能体在 Agent Card 中声明支持哪些扩展,客户端则可以在向智能体发出的请求中选择启用扩展所提供的行为。扩展由 URI 标识,并由各自的规范定义,任何人都可以定义、发布和实现扩展。

扩展的灵活性使得在不割裂核心标准的前提下定制 A2A 成为可能,鼓励创新和面向特定领域的优化。

扩展的范围

扩展的使用方式有意设计得很宽泛,便于把 A2A 拓展到已知用例之外。可以预见的应用包括:

  • 数据型扩展:在 Agent Card 中公开新的结构化信息,不影响请求-响应流程。例如,某个扩展可以增加关于智能体 GDPR 合规性的结构化数据。
  • 配置文件(Profile)型扩展:在核心请求-响应消息之上叠加额外的结构和状态变化要求。这类扩展实际上相当于核心 A2A 协议的一个 profile,缩小允许取值的空间(例如要求所有消息使用遵循特定 schema 的 DataPart)。它也可以通过 metadata 增强任务状态机中的既有状态,例如当 TaskStatus.state 为 working 且 TaskStatus.message.metadata["generating-image"] 为 true 时,定义一个"generating-image"子状态。
  • 方法型扩展(扩展技能):在协议定义的核心方法之外新增 RPC 方法。扩展技能指智能体通过实现定义新 RPC 方法的扩展而获得或暴露的能力。例如,task-history 扩展可以新增一个 tasks/search RPC 方法来检索以往任务列表,相当于赋予智能体一项新的扩展技能。
  • 状态机型扩展:为任务状态机新增状态或状态转换。

扩展示例

扩展说明
Secure Passport Extension增加一个可信的上下文层,实现即时个性化并降低开销(v1)
Hello World / Timestamp Extension一个简单的扩展,演示如何通过在 Message 和 Artifact 的 metadata 字段中添加时间戳来增强基础 A2A 类型(v1)
Traceability ExtensionTraceability 扩展的 Python 实现与基本用法(v1)
Agent Gateway Protocol (AGP) Extension核心协议层/路由扩展,引入自治小队(ASq),并按声明的能力路由意图(Intent)载荷,增强可扩展性(v1)

扩展治理

A2A 组织为扩展的提议、开发、晋升与维护建立了正式的治理框架。官方扩展使用 https://a2a-protocol.org/extensions/ URI 前缀,托管在 a2aproject 组织下,仓库名带 ext- 前缀(实验性扩展使用 experimental-ext-)。

URI 命名空间:https://a2a-protocol.org/extensions/ 前缀是 Agent Card 和协议消息中使用的、全局唯一扩展标识符的规范命名空间。该前缀下的具体 URI,例如 https://a2a-protocol.org/extensions/{name}/v1,标识一个具体的扩展及其版本。这些 URI 只是标识符,并不要求能通过 HTTP 访问。

完整的治理流程,包括分级、生命周期、SDK 支持和法律要求,见扩展与协议绑定治理 。

限制

为避免破坏核心类型校验,有些协议层面的改动是扩展不允许的:

  • 改变核心数据结构的定义:例如为协议定义的数据结构新增字段或删除必填字段。扩展应把自定义属性放在核心数据结构已有的 metadata 映射中。
  • 为枚举类型新增取值:扩展应使用既有的枚举值,并在 metadata 字段中标注额外的语义。

扩展的声明

智能体通过在 AgentCapabilities 对象中包含 AgentExtension 对象,在 Agent Card 中声明对扩展的支持。AgentExtension 包含以下字段:

字段类型说明
uristring扩展的唯一标识 URI
descriptionstring扩展用途的说明
requiredboolean客户端是否必须遵循该扩展
paramsobject扩展特定的配置参数

下面是带有扩展的 Agent Card 示例:

{
  "name": "Magic 8-ball",
  "description": "An agent that can tell your future... maybe.",
  "version": "0.1.0",
  "supportedInterfaces": [
    {
      "url": "https://example.com/agents/eightball",
      "protocolBinding": "JSONRPC",
      "protocolVersion": "1.0"
    }
  ],
  "capabilities": {
    "streaming": true,
    "extensions": [
      {
        "uri": "https://example.com/ext/konami-code/v1",
        "description": "Provide cheat codes to unlock new fortunes",
        "required": false,
        "params": {
          "hints": [
            "When your sims need extra cash fast",
            "You might deny it, but we've seen the evidence of those cows."
          ]
        }
      }
    ]
  },
  "defaultInputModes": ["text/plain"],
  "defaultOutputModes": ["text/plain"],
  "skills": [
    {
      "id": "fortune",
      "name": "Fortune teller",
      "description": "Seek advice from the mystical magic 8-ball",
      "tags": ["mystical", "untrustworthy"]
    }
  ]
}

必需扩展

扩展通常提供的是可选功能,但有些智能体的要求更严格。当 Agent Card 把某个扩展声明为 required: true 时,就是在告诉客户端:扩展的某些方面会影响请求的构造或处理方式,客户端必须遵守。智能体不应把数据型扩展标记为必需。如果客户端没有请求激活必需扩展,或没有遵循其协议,智能体应以适当的错误拒绝该请求。

扩展规范

扩展的详细行为和结构由它的规范定义。格式没有强制要求,但至少应包含:

  • 标识该扩展的具体 URI;
  • AgentExtension 对象 params 字段中所指定对象的 schema 和含义;
  • 客户端与智能体之间传输的任何额外数据结构的 schema;
  • 新的请求-响应流程、额外的端点,或实现该扩展所需的任何其他逻辑的详细说明。

扩展依赖

扩展可能依赖其他扩展:可以是必需依赖(缺少被依赖扩展就无法工作),也可以是可选依赖(存在另一个扩展时才启用额外功能)。扩展规范应记录这些依赖关系。客户端负责按扩展规范列出的内容,激活该扩展及其所有必需依赖。

扩展的激活

扩展默认处于未激活状态,为不了解扩展的客户端提供基线体验。客户端与智能体通过协商确定针对某个请求激活哪些扩展:

  1. 客户端请求:客户端在发往智能体的 HTTP 请求中包含 A2A-Extensions 头,请求激活扩展。其值是客户端打算激活的扩展 URI 的逗号分隔列表。
  2. 智能体处理:由智能体负责识别请求中它支持的扩展并执行激活;请求了但智能体不支持的扩展可以被忽略。
  3. 响应:智能体确定所有已激活的扩展后,响应应包含 A2A-Extensions 头,列出本次请求中成功激活的所有扩展。

协商顺序概括为:客户端先读取 Agent Card 中声明的扩展,再在请求头里发送所选扩展 URI,服务器检查哪些已注册并激活,最后在响应中返回已激活的扩展信息。

请求示例(激活扩展):

POST /agents/eightball HTTP/1.1
Host: example.com
Content-Type: application/json
A2A-Extensions: https://example.com/ext/konami-code/v1
Content-Length: 519

{
  "jsonrpc": "2.0",
  "method": "SendMessage",
  "id": "1",
  "params": {
    "message": {
      "messageId": "1",
      "role": "ROLE_USER",
      "parts": [{"text": "Oh magic 8-ball, will it rain today?"}]
    },
    "metadata": {
      "https://example.com/ext/konami-code/v1/code": "motherlode"
    }
  }
}

对应的响应(回显已激活的扩展):

HTTP/1.1 200 OK
Content-Type: application/json
A2A-Extensions: https://example.com/ext/konami-code/v1
Content-Length: 338

{
  "jsonrpc": "2.0",
  "id": "1",
  "result": {
    "message": {
      "messageId": "2",
      "role": "ROLE_AGENT",
      "parts": [{"text": "That's a bingo!"}]
    }
  }
}

实现注意事项

A2A 协议定义了扩展的功能,本节提供实现层面的指导:扩展实现的编写、版本管理与分发的最佳实践。

  • 版本管理:扩展规范会演进,需要清晰的版本策略,确保客户端和智能体能够协商出兼容的实现。
    • 建议:以扩展的 URI 作为主要版本标识,最好包含版本号(例如 https://example.com/ext/my-extension/v1)。
    • 破坏性变更:对扩展的逻辑、数据结构或必需参数引入破坏性变更时,必须使用新的 URI。
    • 处理不匹配:如果客户端请求的版本智能体不支持,智能体应忽略对该扩展的激活请求,不得回退到其他版本。
  • 可发现性与发布:
    • 规范托管:扩展规范文档应托管在扩展的 URI 上。
    • 永久标识符:建议作者为扩展 URI 使用 w3id.org 之类的永久标识符服务,避免链接失效。
    • 社区注册:A2A 的扩展治理 框架为托管在 a2aproject 组织下的官方和实验性扩展定义了分级体系,以及提议和晋升扩展的生命周期。
  • 打包与复用(A2A SDK 与库):为促进采用,扩展逻辑应打包成可复用的库,集成到现有的 A2A 客户端和服务端应用中。扩展实现应以所在语言生态的标准包形式分发(例如 Python 的 PyPI 包、TypeScript/JavaScript 的 npm 包),目标是为开发者提供顺畅的集成体验:设计良好的扩展包应让开发者用最少的代码把它加入服务器。
  • 安全:扩展会修改 A2A 协议的核心行为,因此会带来新的安全考虑:
    • 输入校验:扩展引入的任何新数据字段、参数或方法,必须经过严格校验,来自外部的所有扩展相关数据都应视为不受信任的输入。
    • 必需扩展的范围:把扩展在 Agent Card 中标记为 required: true 时要谨慎,这会对所有客户端形成硬依赖,只应用于对智能体核心功能和安全至关重要的扩展(例如消息签名扩展)。
    • 认证与授权:如果扩展新增了方法,实现必须确保这些方法与核心 A2A 方法受到同样的认证和授权检查,扩展不得提供绕过智能体主要安全控制的途径。

更多信息见 Google 开发者博客文章 A2A Extensions: Empowering Custom Agent Functionality 。

来源:A2A 官方文档 · Extensions