文章类型技术长文 所属专栏Agent 前沿技术 预计阅读51 分钟 文档状态已发布
返回

A2A 1.0:面向生产环境的 Agent 协作协议

围绕 Agent Card、Discovery、Task、Async 与 Security,系统拆解 A2A 1.0 如何支撑跨 Agent 的生产级发现、任务委派、异步执行与可信交付。

开始阅读全文10148 字 · 51 分钟 查看系列目录Agent 前沿技术
关键词 A2AAgentMulti-AgentAgent Protocol异步任务
栏目 AI-Coding;专栏 Agent 前沿技术;标签 A2A、Agent、Multi-Agent、Agent Protocol、异步任务

A2A 1.0 真正标准化的,不是 Agent 内部如何思考,而是一项工作如何从一个 Agent 安全、可靠地流向另一个 Agent,并最终以可追踪的结果交付回来。

2026 年 3 月 12 日,A2A Protocol v1.0.0 正式发布。这是 A2A 首个稳定、面向生产环境的版本。它没有推翻早期版本的核心思想,而是把协议语义、任务模型、版本管理、安全机制和企业部署能力进一步钉牢,使跨框架、跨团队乃至跨组织的 Agent 协作有了一套更稳定的共同语言。12 截至本文发布,官方已经发布 v1.0.1 补丁版本;本文聚焦 v1.0 的稳定协议语义。

理解 A2A 1.0,可以抓住五个关键词:

关键词解决的问题
Agent Card一个 Agent 如何描述自己是谁、会什么、怎样被调用
Discovery主 Agent 如何找到合适的远端 Agent
Task一项复杂工作如何被创建、跟踪、暂停、继续和完成
Async长时间任务如何持续返回状态、进度和结果
SecurityAgent 身份、调用权限和任务数据如何得到保护

其中,Security 并不是调用链末尾的一个步骤。它更像包裹整个协作流程的外壳,从 Agent Card 的可信性,到任务调用时的身份认证,再到结果回传时的 Webhook 校验,都需要安全机制参与。

A2A 1.0 生产级 Agent 协作总览:主 Agent 围绕 Agent Card、Discovery、Task、Async 和 Security 调度专业 Agent


一、当系统里不再只有一个 Agent#

在简单场景中,一个 Agent 可以直接理解用户问题、调用内部能力并返回结果。但随着业务复杂度增加,一个 Agent 很难同时具备所有领域能力。

一个企业级系统可能包含:

用户
主 Agent
├── 医疗知识 Agent
├── 法律 Agent
├── 财务 Agent
├── 搜索 Agent
└── 数据分析 Agent

这些 Agent 可能由不同团队开发,使用不同编程语言、框架、模型和基础设施。它们甚至可能属于不同公司。

这时,真正棘手的问题不再是“一个 Agent 能不能回答问题”,而是:

  • 主 Agent 如何知道某个专业 Agent 存在?
  • 如何判断对方是否具备所需能力?
  • 如何确认对方支持文本、文件还是结构化数据?
  • 如何把一项任务交出去,而不是只发送一句孤零零的消息?
  • 对方执行十分钟甚至数小时,主 Agent如何跟踪进度?
  • 对方中途需要用户补充信息,任务怎么继续?
  • 最终结果是普通消息,还是一份正式产物?
  • 如何验证对方身份,并限制它能够访问的数据?

如果每个团队都自行定义接口、任务状态、错误码、回调格式和认证方式,系统很快会长成一团接口藤蔓。A2A 的作用,就是把跨 Agent 协作中最容易各自为政的部分标准化。

因此,可以先用一句话概括 A2A:

单个 Agent 解决“如何完成工作”,A2A 解决“工作如何在多个 Agent 之间流动”。


二、A2A 1.0 的整体协作模型#

A2A 交互中,通常存在三个角色。

1. 用户#

用户提出最终目标,例如:

“我发烧、咳嗽三天了,今天还有些胸闷,需要去医院吗?”

2. Client Agent#

也可以称为主 Agent。它面向用户,负责理解意图、拆分目标、选择专业能力、委派任务、处理补充信息,并把远端结果整理成最终答复。

3. Remote Agent#

也可以称为远端 Agent 或专业 Agent。它接收主 Agent 发来的消息,决定是直接回复还是创建任务,并在执行期间维护任务状态、请求额外输入、生成结果产物。

多 Agent 协作模型:主 Agent 拆解目标并协调医疗、法律、财务、搜索和数据分析 Agent

一次典型协作可以表示为:

用户提出目标
主 Agent 判断需要专业能力
查找并读取远端 Agent 的 Agent Card
确认能力、接口、版本和安全要求
完成认证
发送 Message
远端 Agent 创建或更新 Task
持续返回状态和进度
必要时请求额外输入或授权
生成 Artifact
主 Agent校验、解释并返回用户

这里有一个重要边界:

A2A 规范 Agent 之间如何协作,但不规定远端 Agent 内部如何推理、使用什么模型、如何存储记忆,或者如何组织自己的工作流。

对调用方而言,远端 Agent 可以保持“内部不透明”。双方只需要围绕公开能力、输入输出、任务状态和安全规则建立协作。


三、关键词一:Agent Card,让 Agent 成为可理解的网络节点#

3.1 Agent Card 是什么#

Agent Card 是一个机器可读的自描述清单。它相当于 Agent 对外公开的“电子名片加接口说明书”,用于回答以下问题:

你是谁?
你由谁提供?
你会做什么?
你支持哪些输入和输出格式?
你支持哪些协议接口?
你使用哪个 A2A 版本?
你支持流式更新或 Webhook 吗?
调用你需要哪种认证?

在 A2A 1.0 中,A2A Server 必须提供 Agent Card。卡片包含身份、能力、Skills、通信接口和安全要求等信息。3

3.2 Agent Card 的核心字段#

生产系统不需要一开始就背完所有字段,但应该理解下面几组信息。

身份信息#

name
description
provider
version
documentationUrl

它们描述 Agent 的名称、用途、提供方、Agent 自身版本和文档地址。

需要注意,version 表示 Agent 服务自身的版本,并不等同于 A2A 协议版本。

通信接口#

supportedInterfaces
├── url
├── protocolBinding
├── protocolVersion
└── tenant

一个 Agent 可以同时暴露多个接口。例如,同一项能力可以同时提供 HTTP+JSON、JSON-RPC 和 gRPC Binding。supportedInterfaces 是一个有序列表,排在前面的接口优先级更高。

能力与 Skills#

capabilities
skills
defaultInputModes
defaultOutputModes

capabilities 描述是否支持 Streaming、Push Notification、扩展卡片等协议能力。

skills 则描述 Agent 擅长完成的具体工作。每个 Skill 可以包含:

id
name
description
tags
examples
inputModes
outputModes
securityRequirements

安全要求#

securitySchemes
securityRequirements
signatures

securitySchemes 描述可用的认证方案,securityRequirements 描述调用时真正要求满足的方案,signatures 则可用于承载 Agent Card 的 JWS 签名。

A2A Agent Card 字段结构:身份、能力、输入输出、通信接口、安全方案和签名

图示校注: A2A 的 supportedInterfaces 应声明 A2A Protocol Binding;卡片签名字段以正文和规范中的复数 signatures 为准。

3.3 一个简化的 Agent Card#

下面是一个用于说明结构的简化示例,并非完整生产配置:

{
"name": "Medical Knowledge Agent",
"description": "提供健康知识解释、危险信号筛查和就医建议分层",
"provider": {
"organization": "Example Health AI",
"url": "https://health.example.com"
},
"version": "1.3.0",
"supportedInterfaces": [
{
"url": "https://health.example.com/a2a",
"protocolBinding": "HTTP+JSON",
"protocolVersion": "1.0"
}
],
"capabilities": {
"streaming": true,
"pushNotifications": true,
"extendedAgentCard": true
},
"securitySchemes": {
"oauth": {
"oauth2SecurityScheme": {
"description": "OAuth 2.0 client credentials",
"flows": {
"clientCredentials": {
"tokenUrl": "https://auth.example.com/oauth/token",
"scopes": {
"medical.read": "读取医疗知识能力",
"medical.triage": "调用风险分层能力"
}
}
}
}
}
},
"securityRequirements": [
{
"oauth": ["medical.read"]
}
],
"defaultInputModes": [
"text/plain",
"application/json"
],
"defaultOutputModes": [
"text/markdown",
"application/json"
],
"skills": [
{
"id": "symptom-education",
"name": "症状知识解释",
"description": "解释常见症状及其一般性健康含义",
"tags": ["health", "symptom", "education"]
},
{
"id": "risk-triage",
"name": "风险分层",
"description": "识别危险信号并给出就医紧迫性建议",
"tags": ["health", "triage", "risk"]
}
]
}

3.4 Agent Card 为什么是生产化基础#

没有 Agent Card 时,远端 Agent 的能力通常散落在接口文档、配置文件、团队约定和接入代码中。主 Agent 只能依靠硬编码知道“去哪里调用、怎么调用”。

有了 Agent Card,Agent 的信息开始具备以下属性:

可读取
可索引
可验证
可匹配
可协商
可缓存

这意味着一个 Agent 不再只是“某个团队知道怎么调用的服务”,而开始成为其他 Agent 可以理解和选择的网络节点。

3.5 公共卡片与扩展卡片#

企业环境中,公开 Agent Card 不一定适合暴露所有内部 Skill、租户信息或安全细节。A2A 1.0 因此支持经过认证后获取 Extended Agent Card。

常见做法是:

公开 Agent Card
├── 基础身份
├── 公共能力
├── 认证方式
└── extendedAgentCard: true
完成认证
Extended Agent Card
├── 受限 Skills
├── 更详细的接口
└── 针对当前调用方的能力信息

这让“可发现”和“最小披露”可以同时成立。


四、关键词二:Discovery,从找到地址到找到合适的能力#

Agent Card 负责描述 Agent,Discovery 负责找到 Agent Card。

4.1 三种标准发现方式#

A2A 1.0 规范列出了三类发现机制。3

方式一:Well-Known URI#

当主 Agent 已经知道服务域名时,可以从标准地址读取 Agent Card:

https://{server_domain}/.well-known/agent-card.json

这类似于一个固定门牌。调用方知道域名,就知道应该去哪里获取能力说明。

方式二:Registry 或 Catalog#

企业或平台可以维护 Agent 注册中心:

Agent Registry
├── Agent 身份
├── Skills
├── 所属组织
├── 接口与版本
├── 安全等级
├── 支持语言
├── 健康状态
└── 租户范围

主 Agent 可以按条件检索,例如:

能力:医疗风险分层
语言:中文
输出:结构化 JSON
更新方式:支持 Streaming
信任要求:通过企业安全审核

注册中心适合 Agent 数量较多、存在动态上下线、需要统一治理的环境。

方式三:Direct Configuration#

对于调用关系固定的小型系统,可以直接配置 Agent Card 内容或地址。

这种方式最简单,但当 Agent 数量、版本和租户逐渐增加时,静态配置会迅速变成维护负担。

4.2 Discovery 不等于最终选择#

A2A 提供的是可发现、可比较的信息,但并不替主 Agent 决定应该调用谁。

生产系统通常还会在协议之上建立选择策略:

选择维度示例
能力匹配是否具备目标 Skill
输入输出兼容是否支持当前数据类型
协议兼容是否存在双方都支持的 Binding 和版本
信任等级是否来自可信提供方,卡片签名是否有效
权限当前用户或租户能否使用该 Skill
地区与合规数据能否发送到该部署区域
质量历史成功率、评估结果、人工审核级别
性能当前可用性、响应时间、并发容量
成本单次调用价格或资源预算

因此,完整过程不是“发现一个 URL 就调用”,而是:

发现候选 Agent
读取 Agent Card
验证身份与完整性
筛选能力和协议兼容性
应用业务、合规和成本策略
选择具体 Agent 与接口

A2A Discovery 从多种来源发现候选 Agent,并按能力、协议和策略完成筛选选择

图示校注: Well-Known Agent Card 的标准路径是 /.well-known/agent-card.json

4.3 发现结果也需要缓存和更新#

Agent Card 会随 Agent 版本、接口和能力变化。生产系统应当设计:

  • 缓存有效期
  • 重新验证策略
  • 签名与密钥轮换
  • 版本变化检测
  • 注册中心失效处理
  • 回退到已知稳定版本的策略

Discovery 不是一次性安装动作,而是一个持续的运行时治理过程。


五、关键词三:Task,A2A 的核心工作单元#

Task 是理解 A2A 的核心。

A2A 1.0 明确定义:Task 是协议中的核心行动单元。它拥有当前状态,执行结果存放在 Artifact 中,多轮交互则可以记录在 History 中。3

A2A Task 核心对象关系与生命周期:Message、Task、Part、Artifact 及任务状态流转

5.1 为什么不能只用普通请求和响应#

传统接口经常采用:

Request
立即处理
Response

但一个 Agent 任务可能经历:

理解目标
检查输入
执行多步分析
等待外部系统
请求用户补充信息
继续执行
生成多个结果

如果仍把它压缩成一次同步响应,就会出现一系列问题:

  • 请求超时后,不知道任务是否还在执行
  • 中间状态无法表达
  • 无法继续同一项工作
  • 结果与过程消息混在一起
  • 断线后难以恢复
  • 取消、重试和审计没有稳定对象

Task 给这项工作提供了一个独立身份和生命周期。

5.2 四个核心对象#

A2A 的任务模型中,最容易混淆的是 Message、Task、Part 和 Artifact。

Message:一次通信#

Message 是 Client Agent 和 Remote Agent 之间的一次通信。

例如:

“用户持续发热三天,并伴有胸闷,请进行危险信号筛查。”

Message 可以用于:

  • 发起新工作
  • 补充任务输入
  • 追问缺失信息
  • 返回过程说明
  • 修改或澄清目标

每个 Message 都有唯一的 messageId,并包含发送方角色和一个或多个 Part。

Task:持续存在的工作对象#

Task 表示一项可被跟踪的工作,例如:

用户症状风险分层任务

Task 至少包含:

id
status

还可以包含:

contextId
artifacts
history
metadata

Task 的 id 由服务端为新任务生成。只要任务仍然存在,主 Agent 就可以使用这个 ID 查询、继续或取消任务。

Part:内容的基本载体#

Part 是 Message 和 Artifact 的内容容器。A2A 1.0 统一使用一个 Part 模型,并要求每个 Part 在以下内容中恰好选择一种:

text
raw
url
data

这使同一条消息既可以承载自然语言,也可以承载结构化 JSON、文件地址或二进制数据。

Artifact:正式任务产物#

Artifact 表示 Task 的输出,例如:

风险分层结果
分析报告
结构化数据
生成的文档

它拥有独立的 artifactId,并包含一个或多个 Part。

最重要的区别是:

Message 用于交流,Artifact 用于交付任务产物。

例如,远端 Agent 可以通过 Message 告诉主 Agent“正在分析”,但最终的结构化评估报告应该作为 Artifact 返回。

5.3 Task 生命周期#

A2A 1.0 定义了以下 Task State:

状态含义类型
TASK_STATE_UNSPECIFIED状态未知或未明确非业务正常状态
TASK_STATE_SUBMITTED任务已提交并被确认进行中
TASK_STATE_WORKINGAgent 正在处理任务进行中
TASK_STATE_INPUT_REQUIRED需要调用方或用户补充输入中断态
TASK_STATE_AUTH_REQUIRED需要补充认证、授权或人工批准中断态
TASK_STATE_COMPLETED任务成功完成终态
TASK_STATE_FAILED任务执行失败终态
TASK_STATE_CANCELED任务被取消终态
TASK_STATE_REJECTEDAgent 决定不执行该任务终态

一条常见路径是:

TASK_STATE_SUBMITTED
TASK_STATE_WORKING
TASK_STATE_INPUT_REQUIRED
TASK_STATE_WORKING
TASK_STATE_COMPLETED

失败路径可能是:

TASK_STATE_WORKING
├── TASK_STATE_FAILED
├── TASK_STATE_CANCELED
└── TASK_STATE_REJECTED

这些状态把“还在排队”“正在执行”“需要更多输入”“已失败”“已完成”等语义统一起来。调用方不再需要适配每个 Agent 自创的 pendingrunningwait_userdoneerror_42

5.4 taskIdcontextId#

这两个 ID 分别解决不同层级的问题。

taskId#

标识一项具体工作:

taskId: symptom-assessment-1001

主 Agent 使用它查询、继续、订阅或取消这项任务。

contextId#

标识一组相关交互:

contextId: health-session-88

同一个 Context 中可以包含多个 Task:

health-session-88
├── symptom-assessment-1001
├── medicine-explanation-1002
└── follow-up-guidance-1003

可以把 contextId 理解为一条业务会话的“文件夹”,而 taskId 是文件夹中的一张具体工单。

5.5 多轮协作与 INPUT_REQUIRED#

远端 Agent 不一定能靠第一条 Message 完成任务。

例如,主 Agent只告诉医疗 Agent:

用户发热、咳嗽并有胸闷

医疗 Agent可能还需要:

年龄
是否呼吸困难
是否存在基础疾病
症状是否突然加重
是否有血氧数据

此时,它不应该凭空补全信息,而应把 Task 更新为:

TASK_STATE_INPUT_REQUIRED

并在 Task Status 中附带一条 Message,说明需要什么。

主 Agent 获取用户回答后,再携带相同的 taskIdcontextId 发送新 Message,任务便可以继续进入 TASK_STATE_WORKING

这让“追问用户”不再是协议之外的特殊分支,而成为 Task 生命周期中的标准行为。

5.6 执行中的授权与 AUTH_REQUIRED#

有些任务不是缺少业务输入,而是缺少权限。

例如,远端 Agent执行到中途需要:

  • 访问受保护的健康档案
  • 获得用户授权
  • 获取一个新的 OAuth Token
  • 请求人工批准高风险操作

这时可以进入:

TASK_STATE_AUTH_REQUIRED

该状态把“任务逻辑还可以继续,但当前权限不足”与普通失败区分开来。主 Agent可以引导用户授权、联系其他系统,或者拒绝这一授权请求。

凭据默认应通过既有身份系统等带外渠道交付。除非双方预先通过 Extension 协商了安全的带内机制,否则不要把 OAuth Token 直接塞进普通 Message。

5.7 Task 相关核心操作#

A2A 1.0 为 Task 管理定义了明确操作:

SendMessage
SendStreamingMessage
GetTask
ListTasks
CancelTask
SubscribeToTask

以及 Push Notification 配置相关操作。

其中:

  • GetTask 用于获取单个任务当前状态
  • ListTasks 用于按 Context、状态等条件检索任务
  • CancelTask 用于请求取消
  • SubscribeToTask 用于为已有任务建立新的更新流;它不保证补发断线期间遗漏的事件

这使 Task 不只是响应体里的一个 JSON 对象,而是一个可以被独立管理的协议资源。

断线恢复时,应先通过 GetTask 读取当前持久状态,再根据需要调用 SubscribeToTask 接收后续更新。

5.8 幂等性仍然是生产系统的必修课#

A2A 1.0 规定:

  • 查询类操作天然幂等
  • 取消操作具有幂等语义
  • SendMessage 可以利用 messageId 检测重复消息

但协议不会替业务自动完成所有去重和事务处理。生产实现仍应设计:

messageId 唯一约束
重复请求检测
任务创建幂等键
状态迁移并发控制
Artifact 去重
失败重试策略

例如,网络超时后主 Agent重发同一个 Message,远端 Agent不应该创建两份相同医疗评估任务。

5.9 协议之外仍需建设的任务基础设施#

A2A 定义的是协作语义,不是完整的任务执行引擎。真正落地时,系统仍需要自行实现:

  • Task 状态持久化
  • Worker 故障恢复
  • 超时与重试
  • 乐观锁或状态机校验
  • 任务取消传播
  • Artifact 存储
  • History 保留策略
  • 数据过期与清理
  • 监控、Tracing 与审计

还要注意,规范并不保证所有过程 Message 都会永久写入 Task History。关键业务结果不应只藏在一条短暂的进度消息里,而应沉淀为 Task 状态、Artifact 或业务侧持久化记录。


六、关键词四:Async,让任务摆脱单次连接的束缚#

Agent 任务的耗时差异非常大:

500 毫秒:简单知识解释
20 秒:检索并归纳资料
5 分钟:生成完整分析报告
1 小时:执行跨系统流程
数天:等待人工审批

如果所有任务都要求在一次同步连接中完成,系统会被超时、断线和资源占用拖住。

A2A 1.0 提供三种互补的任务更新机制:Polling、Streaming 和 Push Notification。4

A2A 长任务的轮询、流式与 Webhook 三种异步交付流程对比

6.1 Polling:轮询任务状态#

调用链如下:

主 Agent → SendMessage
主 Agent ← Task: SUBMITTED
主 Agent → GetTask
主 Agent ← Task: WORKING
主 Agent → GetTask
主 Agent ← Task: COMPLETED + Artifacts

适合:

  • 集成简单
  • 更新频率较低
  • 客户端不支持持久连接
  • 网络环境限制较多

它的代价是状态延迟和额外请求。轮询间隔过短会制造流量,过长又会让用户感觉系统像在沉思中失联。

6.2 Streaming:实时接收事件#

Streaming 适合交互式产品和需要实时进度的任务。

Streaming 有两种互斥结果模式:

Message-only:恰好返回一个 Message,然后关闭连接
Task lifecycle:
先返回 Task
再持续返回 TaskStatusUpdateEvent / TaskArtifactUpdateEvent

其中:

  • TaskStatusUpdateEvent 表示任务状态发生变化
  • TaskArtifactUpdateEvent 表示生成或更新了 Artifact
  • 任务执行中的说明消息应放在 TaskStatusUpdateEvent.status.message 中,而不是作为独立 Message 混入 Task 事件流

例如:

已接收任务
正在进行危险信号筛查
需要补充用户年龄
正在生成风险分层结果
已生成结构化 Artifact
任务完成

A2A 1.0 要求事件按照生成顺序交付,不得在传输过程中重排。它还允许同一 Task 存在多个并发订阅流。

一个关键设计是:

Streaming 连接是 Task 更新的交付渠道,不是 Task 本身。

连接断开不等于任务消失。主 Agent应先重新查询 Task 的当前状态,再使用 SubscribeToTask 订阅后续事件;不能假设断线期间的流式事件会被自动重放。

6.3 Push Notification:通过 Webhook 回调#

对于服务端之间的长时间任务,主 Agent不必一直保持连接:

主 Agent → 提交任务
连接结束
远端 Agent继续执行
远端 Agent → Webhook
通知状态变化或 Artifact 更新

适合:

  • 长时间执行
  • 服务端到服务端集成
  • 事件驱动架构
  • 调用方不适合保持长连接

6.4 Webhook 是“至少一次”,不是“恰好一次”#

A2A 1.0 要求 Agent 至少尝试向已配置的 Webhook 交付一次,失败时还可以重试。因此重复通知可能发生。

客户端应该:

  • 根据 taskId 验证通知属于预期任务
  • 根据 taskIdartifactId 和业务侧去重键进行幂等处理
  • 验证通知来源和认证信息
  • 对乱序以外的重复事件保持容忍
  • 接收成功后返回正确的 2xx 状态
  • 在内部消费失败时采用可靠队列或补偿机制

Webhook 回调不是“一次送达的魔法信鸽”,而是一条可能重投的生产消息通道。

6.5 三种方式如何选#

场景推荐方式
简单集成,任务很快完成同步响应或 Polling
对话界面,需要实时进度Streaming
长时间后台任务Push Notification
客户端断线后恢复GetTask + SubscribeToTask
关键系统需要双重保障Streaming 或 Push,同时保留 GetTask 查询

协议提供机制,真正的选择取决于任务时长、客户端能力、网络环境和可靠性要求。


七、关键词五:Security,贯穿整条协作链的信任框架#

当 Agent 只负责生成一段无害文本时,错误通常停留在答案层面。但生产 Agent 可能读取隐私数据、操作企业系统、生成合同、修改订单,甚至给出医疗风险提示。

因此,系统必须回答:

调用方是谁?
远端 Agent 是谁?
Agent Card 是否被篡改?
当前身份可以调用哪些 Skills?
哪些数据可以发送给远端 Agent?
任务和 Artifact 对谁可见?
Webhook 是否真的来自目标 Agent?

A2A 全链路安全框架:认证授权、传输保护、Agent Card 签名、数据最小化与审计

7.1 复用成熟的 Web 安全机制#

A2A 把 Agent 视为标准企业应用,复用成熟的 Web 安全模式。生产部署中,HTTP 类 Binding 必须使用 HTTPS,gRPC 必须使用 TLS。3

Agent Card 可以声明:

API Key
HTTP Basic / Bearer
OAuth 2.0
OpenID Connect
mTLS

这意味着企业已有的网关、身份平台、证书体系、WAF、Service Mesh 和审计系统仍然可以继续发挥作用。

7.2 认证与授权不是一回事#

Authentication:你是谁?
Authorization:你被允许做什么?

主 Agent完成身份认证,并不代表它可以调用远端 Agent 的全部能力。

例如,一个医疗 Agent可以允许某个调用方使用:

健康知识解释
一般性危险信号筛查

但不允许它:

读取完整病历
修改处方
访问其他租户的健康数据
触发高风险医疗操作

授权可以根据以下因素判断:

  • 当前调用方身份
  • OAuth Scope
  • 具体 Skill
  • Task 中尝试执行的动作
  • 数据访问策略
  • 用户或租户
  • 地区与合规要求

7.3 Signed Agent Card#

A2A 1.0 支持使用 JWS 对 Agent Card 进行数字签名,并要求签名前使用 JSON Canonicalization Scheme 对 JSON 进行规范化。35

签名可以帮助调用方验证:

卡片内容是否被修改
卡片是否由持有对应私钥的一方签发

但要注意,签名本身不是凭空生长的信任。客户端仍然需要可信公钥、证书链、注册中心或其他信任锚点,才能判断签名者是否确实是自己认可的 Agent 提供方。

因此,生产验证链更接近:

获取 Agent Card
规范化待验证内容
验证 JWS 签名
检查签名密钥是否可信
检查卡片是否过期或已撤销
确认接口域名与提供方策略一致

7.4 Task 可见性必须按调用方隔离#

A2A 1.0 明确要求服务端只返回当前调用方有权看到的 Task。

这意味着:

  • GetTask 不能泄露其他用户任务
  • ListTasks 必须按身份和租户过滤
  • 不应通过不同错误信息暴露资源是否存在
  • Artifact 下载也必须重新做权限校验
  • Task History 不能成为跨租户信息漏斗

仅仅猜不到 taskId 并不构成安全边界。

7.5 Push Notification 也需要独立防护#

Webhook 接收端应当验证:

  • HTTPS
  • 服务端认证凭据
  • 任务 ID
  • 回调 Token
  • 时间戳或重放保护
  • 来源允许列表
  • Payload 大小和内容类型
  • 幂等键

因为一条伪造的“任务已完成”通知,可能诱导主 Agent接受错误 Artifact,甚至触发后续业务动作。

7.6 数据最小化与审计#

A2A 解决的是 Agent 协作,不会自动替企业完成隐私合规。

调用方应遵循:

只发送完成任务所需的数据
敏感字段尽可能脱敏
明确用户授权和使用目的
限制 Task、History 和 Artifact 的保留时间
记录谁在什么时间调用了哪个 Skill
对高风险结果保留人工复核

在医疗场景中,用户姓名、身份证号、地址和完整历史对话通常不是做一次一般性风险分层所必需的,就不应该顺手打包给远端 Agent。


八、为什么 A2A 1.0 可以被称为生产协议#

五个关键词构成了 A2A 的主干,但 v1.0 之所以能从实验性协议走向生产,还依赖一组更底层的工程改进。官方将其概括为协议成熟度、类型安全、开发体验和企业级能力四个主题。5

A2A 1.0 八项生产能力及其解决的工程问题总览

图示校注: A2A 1.0 的三个核心 Binding 以正文中的 JSON-RPC、gRPC 与 HTTP+JSON 为准;tenant 提供路由标识,鉴权、数据隔离和配额仍由服务端实现。

8.1 统一的规范数据模型#

A2A 1.0 将 Protocol Buffers 定义提升为规范数据模型的权威来源。不同 Binding 必须对同一套对象提供功能等价的表达。

核心对象包括:

AgentCard
Message
Part
Task
TaskStatus
Artifact
TaskStatusUpdateEvent
TaskArtifactUpdateEvent
SecurityScheme

这能减少“同一个字段在不同传输方式下语义漂移”的问题。

8.2 多种 Protocol Binding#

A2A 1.0 正式支持三个核心 Binding:

JSONRPC
GRPC
HTTP+JSON

它们的底层传输和编码方式可以不同,但应该保持相同的任务语义、状态模型和错误含义。

这对企业很重要,因为不同系统可以保留合适的技术栈,而不必为了协作全部重写为同一种通信方式。

8.3 版本声明与渐进迁移#

每个 AgentInterface 都声明自己的:

protocolBinding
protocolVersion
url

主 Agent可以从有序接口列表中选择自己支持的组合。

在 v1.0 中,Client 必须在每次请求中发送:

A2A-Version: 1.0

版本协商值使用 Major.Minor,不携带补丁号。服务端不支持该版本时,应返回版本不支持错误。

一个 Agent可以同时暴露旧版本和 1.0 接口,使调用方逐步迁移,而不必在某个凌晨让整个系统集体跳崖式升级。

8.4 多租户路由#

A2A 1.0 在接口和请求模型中加入 tenant 字段,使同一个 Endpoint 可以根据 Tenant 路由到不同 Agent 或租户上下文。

但这个字段只提供标准化的路由标识,不会自动完成:

租户鉴权
数据隔离
密钥隔离
配额限制
审计隔离

这些仍然属于服务端实现责任。

8.5 标准化错误模型#

生产协议不能只规定成功路径。A2A 1.0 对错误类别和跨 Binding 映射做了更明确的规定,包括:

认证错误
授权错误
参数校验错误
资源不存在或不可见
系统内部错误
A2A 专属错误

专属错误包括:

TaskNotFoundError
TaskNotCancelableError
PushNotificationNotSupportedError
ContentTypeNotSupportedError
VersionNotSupportedError

错误响应不仅要给人类可读信息,也应该提供机器可识别的错误码和结构化详情,方便自动恢复或给出明确提示。

8.6 可扩展但不破坏基础兼容#

特定行业可能需要更严格的结构和状态规则。A2A 允许 Agent 在 Agent Card 中声明扩展 URI,并说明扩展是否为必需。

客户端可以选择支持某个扩展,同时仍然保持基础协议兼容。这样可以避免每出现一个行业需求,就把核心协议再拧出一个新分叉。

8.7 生产能力总览#

生产问题A2A 1.0 对应机制
Agent 身份和能力不透明Agent Card
找不到合适的专业 AgentDiscovery
任务没有统一生命周期Task 与 Task State
中途缺少用户信息TASK_STATE_INPUT_REQUIRED
中途缺少权限TASK_STATE_AUTH_REQUIRED
过程消息与正式结果混杂Message 与 Artifact 分离
长连接容易中断Polling、Streaming、Push Notification
回调可能重复taskId 校验与幂等消费
不同技术栈难以互通多 Protocol Binding 与等价语义
协议升级困难接口级版本声明与版本协商
对方身份和卡片不可信HTTPS、认证机制、Signed Agent Card
多客户共用一个 EndpointTenant 路由字段与服务端隔离策略
错误无法自动处理标准错误分类和结构化详情

A2A 1.0 的生产价值,不在于多发明了一种 JSON,而在于把 Agent 协作中最难统一的身份、能力、任务、异步和信任问题,整理成了一套稳定语义。


九、完整案例:主 Agent 调用医疗 Agent 解答用户问题#

下面用一个完整案例,把五个关键词串成一条调用链。

说明:示例中的医疗 Agent 只用于一般性健康知识解释、危险信号筛查和就医紧迫性建议,不替代医生诊断,不应自动修改处方或指导高风险用药。

9.1 用户提出问题#

用户:
“我已经咳嗽三天了,体温 38.5℃,
今天走动时感觉胸口有点闷,需要去医院吗?”

主 Agent能够理解用户语言,但自身没有经过医疗领域审核。它决定寻找一个可信的医疗专业 Agent,获取风险分层结果,再用用户易懂的方式组织回答。

9.2 Discovery:寻找合适的医疗 Agent#

主 Agent向可信 Registry 查询:

需要的 Skills:
symptom-education
risk-triage
其他要求:
支持中文
支持结构化 JSON 输出
支持多轮补充信息
支持 Streaming
通过组织安全审核

Registry 返回一个候选项:

Medical Knowledge Agent
Agent Card:
https://health.example.com/.well-known/agent-card.json

9.3 Agent Card:确认能力和接口#

主 Agent读取并检查 Agent Card:

Agent 名称:Medical Knowledge Agent
Skills:symptom-education、risk-triage
输入:text/plain、application/json
输出:text/markdown、application/json
Binding:HTTP+JSON
A2A 版本:1.0
Streaming:支持
认证:OAuth 2.0

随后,它验证 Agent Card 的 JWS 签名,并检查签名密钥是否来自组织信任的医疗服务提供方。

这里已经完成了三个判断:

它是谁?
它会什么?
我能否安全调用它?

9.4 Security:取得最小权限凭据#

主 Agent通过既有身份系统获得一个仅包含必要 Scope 的访问令牌:

medical.read
medical.triage

令牌不包含读取完整电子病历或修改医疗记录的权限。

9.5 SendMessage:发起医疗风险分层请求#

主 Agent只发送完成任务所需的信息:

POST /message:send HTTP/1.1
Host: health.example.com
Content-Type: application/a2a+json
Authorization: Bearer <access-token>
A2A-Version: 1.0
{
"message": {
"messageId": "msg-001",
"role": "ROLE_USER",
"parts": [
{
"data": {
"symptoms": [
"咳嗽三天",
"体温 38.5 摄氏度",
"走动时胸闷"
],
"language": "zh-CN",
"request": "请进行危险信号筛查,并给出就医紧迫性建议"
},
"mediaType": "application/json"
}
]
},
"configuration": {
"returnImmediately": true
}
}

它没有发送:

用户姓名
身份证号
家庭地址
与任务无关的完整聊天记录

9.6 医疗 Agent 创建 Task#

医疗 Agent接收 Message 后创建 Task。由于请求显式设置了 returnImmediately: true,服务端可以立即返回仍处于执行中的 Task:

{
"task": {
"id": "medical-task-1001",
"contextId": "health-context-88",
"status": {
"state": "TASK_STATE_WORKING",
"timestamp": "2026-08-28T12:30:00.000Z"
}
}
}

此时主 Agent获得了两个关键 ID:

taskId: medical-task-1001
contextId: health-context-88

即使当前连接断开,它也可以继续查询这项任务。

9.7 Task 进入 INPUT_REQUIRED#

医疗 Agent判断现有信息不足,返回状态更新:

{
"statusUpdate": {
"taskId": "medical-task-1001",
"contextId": "health-context-88",
"status": {
"state": "TASK_STATE_INPUT_REQUIRED",
"message": {
"messageId": "msg-medical-question-001",
"contextId": "health-context-88",
"taskId": "medical-task-1001",
"role": "ROLE_AGENT",
"parts": [
{
"data": {
"questions": [
"用户年龄是多少?",
"是否存在明显呼吸困难?",
"是否有哮喘、心脏病等基础疾病?",
"是否出现嘴唇发紫、意识模糊或持续胸痛?",
"是否测量过血氧?"
]
},
"mediaType": "application/json"
}
]
}
}
}
}

主 Agent把这些字段转换成自然语言:

“为了更准确地判断紧迫程度,我还需要确认:
你今年多大?现在是否明显呼吸困难?
有没有哮喘或心脏病?是否有持续胸痛?
家里有血氧仪吗?”

9.8 用户补充信息,继续同一个 Task#

用户回答:

“我 27 岁,没有基础病。
没有明显呼吸困难,但走动时胸闷更明显。
没有持续胸痛,也没有血氧仪。”

主 Agent继续发送 Message,并携带原来的 Task 和 Context:

{
"message": {
"messageId": "msg-002",
"contextId": "health-context-88",
"taskId": "medical-task-1001",
"role": "ROLE_USER",
"parts": [
{
"data": {
"age": 27,
"underlyingConditions": [],
"breathingDifficulty": false,
"chestTightnessOnActivity": true,
"persistentChestPain": false,
"oxygenSaturation": null
},
"mediaType": "application/json"
}
]
}
}

医疗 Agent将任务重新更新为:

TASK_STATE_WORKING

9.9 Async:主 Agent接收处理进度#

主 Agent拿到进行中的 Task 后调用 SubscribeToTask,通过 Streaming 获得连续更新;若连接中断,则先 GetTask 获取当前状态,再订阅后续事件:

TaskStatusUpdateEvent:
正在进行危险信号筛查
TaskStatusUpdateEvent:
正在评估线下就医紧迫性
TaskArtifactUpdateEvent:
已生成结构化风险分层结果

这些更新改善用户体验,但主 Agent不应把普通进度 Message 当作关键业务结果。正式结果仍应以 Artifact 为准。

9.10 医疗 Agent 返回 Artifact#

任务最终进入:

TASK_STATE_COMPLETED

并返回结构化 Artifact:

{
"task": {
"id": "medical-task-1001",
"contextId": "health-context-88",
"status": {
"state": "TASK_STATE_COMPLETED",
"timestamp": "2026-08-28T12:30:08.000Z"
},
"artifacts": [
{
"artifactId": "risk-assessment-001",
"name": "症状风险分层结果",
"description": "基于用户提供信息生成的一般性风险提示",
"parts": [
{
"data": {
"riskLevel": "needs-timely-in-person-evaluation",
"reasons": [
"发热持续三天",
"咳嗽持续三天",
"活动时胸闷"
],
"recommendedAction": "建议尽快接受线下医疗评估",
"emergencyTriggers": [
"明显或快速加重的呼吸困难",
"嘴唇发紫",
"意识模糊",
"持续或加重的胸痛"
],
"limitations": [
"该结果不是医疗诊断",
"无法替代体格检查、血氧测量和必要的医学检查"
]
},
"mediaType": "application/json"
}
]
},
{
"artifactId": "patient-explanation-001",
"name": "面向用户的健康说明",
"parts": [
{
"text": "根据你描述的持续发热、咳嗽和活动时胸闷,建议尽快接受线下医疗评估。若出现明显呼吸困难、嘴唇发紫、意识异常,或持续加重的胸痛,请立即联系当地急救服务。",
"mediaType": "text/markdown"
}
]
}
]
}
}

9.11 主 Agent进行最终交付#

主 Agent不能把远端结果不加判断地原样抛给用户。它还需要:

  • 验证 Task 和 Artifact 属于当前用户与 Context
  • 检查任务是否确实处于完成状态
  • 保留危险信号和能力边界
  • 避免把“风险分层”表述成“已经确诊”
  • 使用用户容易理解的语言
  • 根据用户所在地区提供适当的急救提示
  • 对高风险结论启用人工或专业服务升级策略

最终回答可以是:

你描述的持续发热、咳嗽,以及走动时胸闷,
建议尽快接受线下医疗评估,以便测量血氧并做必要检查。
仅凭聊天无法判断具体原因,也不能替代医生诊断。
若出现明显呼吸困难、嘴唇发紫、意识模糊,
或者胸痛持续加重,请立即联系当地急救服务。

9.12 五个关键词如何在案例中落地#

Agent Card
解决医疗 Agent 是谁、会什么、支持怎样的接口和认证。
Discovery
解决主 Agent 如何找到并选择可信的医疗能力。
Task
解决医疗评估如何被创建、追问、继续和完成。
Async
解决主 Agent 如何持续获得状态、进度和 Artifact。
Security
解决身份、权限、卡片完整性、健康数据和回调如何被保护。

完整调用链如下:

用户
│ 提出医疗问题
主 Agent
│ 1. Discovery:查找可信医疗 Agent
Agent Registry / Well-Known URI
│ 2. 获取并验证 Agent Card
主 Agent
│ 3. 取得最小权限凭据
│ 4. SendMessage
医疗 Agent
│ 5. 创建 Task
│ 6. TASK_STATE_WORKING
│ 7. TASK_STATE_INPUT_REQUIRED
主 Agent
│ 8. 向用户追问
│ 9. 携带相同 taskId/contextId 补充信息
医疗 Agent
│ 10. Streaming 状态更新
│ 11. 生成 Artifacts
│ 12. TASK_STATE_COMPLETED
主 Agent
│ 13. 校验、解释和安全呈现
用户

医疗咨询完整调用链:主 Agent 发现并验证医疗 Agent,委派任务、补充输入、跟踪状态并接收 Artifact

图示校注: 图中的 INPUT_REQUIRED 回路包含用户补充信息并继续同一 taskId / contextId 的步骤;上方文字调用链给出了完整编号。

这个案例也说明了一件事:

A2A 并不替主 Agent做医疗判断,也不替医疗 Agent决定内部如何分析。它负责让专业能力的发现、委派、追问、异步执行和结果交付,沿着一条可识别、可管理、可审计的协议链流动。


十、结语:标准化工作,而不是标准化思考#

A2A 1.0 的五个关键词可以这样收束:

Agent Card 让 Agent 可以被机器理解。
Discovery 让专业能力可以被动态找到。
Task 让复杂工作拥有统一生命周期。
Async 让长时间任务摆脱单次连接限制。
Security 让跨 Agent 委派具备进入真实业务的基础。

A2A 1.0 没有试图统一所有 Agent 的内部实现。它选择了更务实的边界:不干涉每个 Agent 如何思考,而是标准化它们如何公开能力、接收任务、表达状态、索取输入、交付结果和建立信任。

当系统中只有一两个 Agent 时,这些机制看起来可能略显厚重。但当 Agent 开始跨部门、跨平台和跨组织协作时,没有统一协议,系统会迅速被硬编码接口、私有状态机和安全补丁淹没。

因此,A2A 1.0 的真正价值可以归结为一句话:

它把一次偶然成功的 Agent 调用,变成了一条可以重复运行、持续跟踪、发生故障后仍能恢复的生产协作链。


参考资料#

Footnotes#

  1. A2A Protocol Ships v1.0: Production-Ready Standard for Agent-to-Agent Communication

  2. A2A Protocol GitHub Releases

  3. Agent2Agent Protocol v1.0.0 Specification 2 3 4 5

  4. Streaming & Asynchronous Operations in A2A

  5. What’s New in A2A Protocol v1.0 2

A2A 1.0:面向生产环境的 Agent 协作协议
https://jupiter-ws.cn/posts/ai-coding/a2a-1-0-production-protocol/
作者
Jupiter
发布于
2026-08-29
许可协议
CC BY-NC-SA 4.0