A2A 面向远程 Agent 间任务协作
A2A 解决“由不同语言、框架、团队或组织实现的 Agent 如何协作”。调用方只需知道对方公开的能力、接口和安全要求,不需要读取其内部 Prompt、工具清单或推理过程。这使跨组织委派比共享同一个 Runtime 更松耦合。
| 机制 | 主要对象 | 状态边界 | 适用范围 |
|---|---|---|---|
| A2A | Agent、Task、Message、Artifact | 远端任务生命周期 | 跨系统或跨组织委派 |
| MCP | Host、Client、Server、Primitive | 能力调用;当前核心无状态 | 模型应用连接 Tool/Resource/Prompt |
| 内部函数/队列 | 服务、命令、事件 | 团队自定义 | 边界可控的内部系统 |
三者可以组合:本地 Orchestrator 通过 A2A 委派“生成采购风险报告”,远端 Agent 再通过 MCP 读取供应商数据。不要用 A2A 替代进程内函数,也不要用 MCP Tool 模拟需要跨小时、反复补充输入的远程协作。
Agent Card 是能力广告,不是信任证明
Agent Card 描述名称、能力、Skills、输入输出模态、安全方案和接口。A2A v1.0 将 URL、绑定和协议版本放入 supportedInterfaces[],同一个 Agent 因而可以同时暴露 JSON-RPC、gRPC 或 HTTP+JSON/REST,并按接口声明版本。
公开 Card 适合最小发现;认证后的 Extended Agent Card 可以返回更详细能力。Card 中的描述由远端提供,不能作为组织准入或质量证明。v1.0 支持基于 RFC 8785 规范化和 JWS 的签名,签名证明完整性与签名者身份,仍不证明业务可信、数据合规或能力效果。
// A2A v1.0 的核心发现片段(简化)
type AgentInterface = {
url: string
protocolBinding: 'JSONRPC' | 'GRPC' | 'HTTP+JSON'
protocolVersion: '1.0'
}
type AgentCard = {
name: string
supportedInterfaces: AgentInterface[]
skills: Array<{ id: string; name: string; description: string }>
signatures?: unknown[]
}
客户端应从可信注册表或受控域发现 Card,验证 TLS、可用签名、允许的组织/区域和缓存版本,再选择自己支持的接口。静态凭据不应写入 Card。
Task 承载长时间协作状态
Task 由 Server 分配稳定 ID,包含当前 TaskStatus、Artifacts 和可选 History;contextId 可把多个 Task/Message 放入同一交互上下文。A2A v1.0 的状态使用带类型前缀的枚举,例如 TASK_STATE_WORKING、TASK_STATE_INPUT_REQUIRED、TASK_STATE_COMPLETED,不能继续按 v0.3 的小写字符串解析。
| 当前状态 | 合法方向示例 | 不能做的假设 |
|---|---|---|
| SUBMITTED | WORKING、REJECTED、CANCELED | 接收即代表已经开始执行 |
| WORKING | INPUT/AUTH REQUIRED 或任一终态 | 流中断即代表任务失败 |
| INPUT/AUTH REQUIRED | 补充后回到 WORKING,或失败/取消 | 等待状态是不可恢复终态 |
| 终态 | 保持不可逆;后续修正创建新 Task/Artifact 版本 | 重复通知可把终态改回 WORKING |
取消是请求,不是撤销历史副作用。Client 发出 CancelTask 后仍要读取服务端返回状态;任务可能已在取消前完成。消费者必须按状态机校验转移,遇到未知枚举保留原始值并进入兼容告警,而不是误判为成功。
Message 与 Artifact 分离对话和产物
Message 承载任务发起、澄清、进度或继续输入;Artifact 承载文档、文件、结构化数据等可交付结果。A2A 规范明确建议不要把任务输出仅作为 Message 返回,否则调用方难以判断哪些是过程话语、哪些是应保存和验收的成果。
两者都由 Part 组成,可包含文本、文件和结构化数据。大文件优先使用受鉴权引用,明确媒体类型、摘要、校验值、访问期限与删除责任。Task History 并不保证保存所有瞬时 Message,因此审计不能只依赖远端 History。
同步、流式和异步适配不同任务
v1.0 把语义层与绑定层分开:规范数据模型来自 Protocol Buffers,各绑定提供等价映射。短任务可 SendMessage 等待结果;需要增量体验时用 SendStreamingMessage;希望立即返回再轮询时设置执行模式;断线后通过 GetTask 或 SubscribeToTask 恢复,而不是重新创建 Task。
流式事件在 v1.0 取消旧 kind 字段,改用 taskStatusUpdate 或 taskArtifactUpdate 成员区分;流关闭表达终止。Push Notification 适合客户端离线的长任务,但 Webhook 必须验证服务端身份、签名/凭据、重放窗口,并用事件 ID/Task 版本实现幂等。
| 模式 | 客户端恢复点 | 主要风险 |
|---|---|---|
| 同步等待 | 响应或 Deadline | 长连接超时、未知结果 |
| 流式 | Task ID + 订阅 | 断线、重复、部分 Artifact |
| 立即返回/轮询 | Task ID + GetTask | 轮询风暴、新鲜度 |
| Push | 服务端持久 Task + Client Webhook | 伪造、重放、投递失败 |
跨 Agent 信任必须显式
A2A 把认证凭据放在绑定的 Header/Metadata 中,而不是 Message 正文。Server 对每次请求认证,再按调用者、Skill、任务动作和数据策略授权。生产 HTTP 使用 HTTPS,gRPC 使用 TLS;Agent Card 只声明支持的 Security Scheme,凭据通常通过协议外流程获得。
跨组织任务还需治理代表关系:调用 Agent 是以自身身份还是代表最终用户?远端可把输入用于多久、存在哪个地域、能否委派给第三方?只传完成任务所需的 Context,不转发本地 Memory、原始凭据或无关 PII。远端 Artifact 回来后仍按外部输入校验 Schema、恶意内容和数据政策。
互操作性不只看 Happy Path
A2A 当前最新发布版是 1.0.0。v0.3→v1.0 包含接口结构、枚举、流事件、错误模型和分页等破坏性变化;迁移应采用“兼容读取 → 双版本接口 → 停止旧写入 → 删除旧解析”的阶段路径,不能让 SDK 静默降级丢失新能力。
| 测试 | 关键断言 | 需要保留的证据 |
|---|---|---|
| 版本与绑定选择 | A2A-Version 和 AgentInterface 匹配;不支持则显式失败 | 协商 Trace |
| 状态/事件 | 重复、乱序、未知状态不产生错误终态 | Reducer 回放 |
| 输入与取消竞态 | 补充输入关联原 Task;取消不重复副作用 | Task 时间线 |
| Artifact 增量 | 按 index/ID 合并,不把部分结果当最终结果 | Artifact 快照 |
| Agent Card | 签名、缓存、扩展和 Extended Card 权限正确 | 发现审计 |
| 对端不可用 | 保留本地任务状态,按 Deadline 恢复或升级 | Runbook 演练 |
主动提取:为什么 Agent Card 不能直接作为动态路由的信任依据?
迁移判断:v0.3 客户端收到没有 A2A-Version 的响应,能否推断为 v1.0?
资料与事实边界
以下以官方文档、标准、论文和原始工程资料为主。厂商 API、价格、限额与模型能力会变化,落地时仍需按目标版本做能力探测和回归。
- A2A Protocol Specification 1.0.0 — 当前发布版的数据模型、操作、绑定、安全与兼容规范
- What’s New in A2A v1.0 — 从 v0.3 到 v1.0 的破坏性变化与迁移建议
- A2A Key Concepts — Agent Card、Task、Message 与 Artifact 的概念边界
- RFC 8785 JSON Canonicalization Scheme — Agent Card 签名前的确定性 JSON 规范化