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/searchRPC 方法来检索以往任务列表,相当于赋予智能体一项新的扩展技能。 - 状态机型扩展:为任务状态机新增状态或状态转换。
扩展示例
| 扩展 | 说明 |
|---|---|
| Secure Passport Extension | 增加一个可信的上下文层,实现即时个性化并降低开销(v1) |
| Hello World / Timestamp Extension | 一个简单的扩展,演示如何通过在 Message 和 Artifact 的 metadata 字段中添加时间戳来增强基础 A2A 类型(v1) |
| Traceability Extension | Traceability 扩展的 Python 实现与基本用法(v1) |
| Agent Gateway Protocol (AGP) Extension | 核心协议层/路由扩展,引入自治小队(ASq),并按声明的能力路由意图(Intent)载荷,增强可扩展性(v1) |
扩展治理
A2A 组织为扩展的提议、开发、晋升与维护建立了正式的治理框架。官方扩展使用 https://a2a-protocol.org/extensions/ URI 前缀,托管在 a2aproject 组织下,仓库名带 ext- 前缀(实验性扩展使用 experimental-ext-)。
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 包含以下字段:
| 字段 | 类型 | 说明 |
|---|---|---|
uri | string | 扩展的唯一标识 URI |
description | string | 扩展用途的说明 |
required | boolean | 客户端是否必须遵循该扩展 |
params | object | 扩展特定的配置参数 |
下面是带有扩展的 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;
- 新的请求-响应流程、额外的端点,或实现该扩展所需的任何其他逻辑的详细说明。
扩展依赖
扩展可能依赖其他扩展:可以是必需依赖(缺少被依赖扩展就无法工作),也可以是可选依赖(存在另一个扩展时才启用额外功能)。扩展规范应记录这些依赖关系。客户端负责按扩展规范列出的内容,激活该扩展及其所有必需依赖。
扩展的激活
扩展默认处于未激活状态,为不了解扩展的客户端提供基线体验。客户端与智能体通过协商确定针对某个请求激活哪些扩展:
- 客户端请求:客户端在发往智能体的 HTTP 请求中包含
A2A-Extensions头,请求激活扩展。其值是客户端打算激活的扩展 URI 的逗号分隔列表。 - 智能体处理:由智能体负责识别请求中它支持的扩展并执行激活;请求了但智能体不支持的扩展可以被忽略。
- 响应:智能体确定所有已激活的扩展后,响应应包含
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 上。
- 永久标识符:建议作者为扩展 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 。