A2A 是什么,不是什么
A2A 是 Agent-to-Agent 的缩写,为一个 Agent 服务请求另一个 Agent 服务完成工作提供互操作词汇。Google 在 2025 年公开宣布了这一协议,之后它在开放生态中持续演进。应将规范版本、Transport Binding、SDK 和治理位置视为部署依赖,而不是永恒事实。
A2A 可以帮助实现:
- 通过 Agent Card 发现能力;
- 结构化 Message 和 Artifact;
- 短任务或长任务的生命周期;
- 状态更新,以及版本支持时的 Streaming 或 Push Delivery;
- 在独立运营的 Agent 服务间进行委派。
它不能提供业务授权、Tenant 隔离、可信目录、安全 Tool 执行、准确模型输出或只发生一次的副作用。这些仍是应用职责。
先确定边界,再选择协议
如果工作由同一服务拥有且契约很窄、可确定,优先使用 Local Function。只有远程服务具有独立生命周期、Policy 或能力边界时,才考虑 A2A。
| 问题 | 合理答案 |
|---|---|
| 谁拥有 Task State? | 一个有持久存储和 Retention Policy 的明确服务。 |
| 谁认证 Caller? | 远程服务,使用可信身份机制。 |
| 谁授权数据和副作用? | 拥有对象和动作的服务。 |
| Retry Identity 是什么? | 应用生成的 Idempotency Key,而不是模型语句。 |
| 断连时发生什么? | 明确 Polling、Callback、Resume 或 Cancellation 契约。 |
| 保留什么证据? | 脱敏的生命周期 Event、Policy Decision、Artifact Reference 和 Error Class。 |
不要只是为了让线性 Workflow 看起来“自治”而引入 Agent 协议。
A2A 与 MCP
两个协议面对不同边界,但“A2A 是 Agent-to-Agent、MCP 是 Agent-to-Tool”的口号并不完整。
| 边界 | 常见目的 | 协议外仍需完成 |
|---|---|---|
| A2A | 向远程 Agent 服务委派 Task | 服务身份、Task/Object 授权、Budget |
| MCP | 为 AI 应用暴露 Tool、Resource、Prompt | User 身份、Object 授权、副作用 Policy |
| Application Workflow | 协调本地与远程工作 | Approval、补偿、Audit、业务 Invariant |
A2A Delegate 可以在内部使用 MCP;MCP Host 也可以不使用 A2A 而调用远程服务。两种安排都不会授予模型读取对象或执行外部写入的权限。
固定规范表面
实现前记录已测试的精确输入:
{
"a2a_specification": "pinned-release-or-commit",
"transport_binding": "pinned-profile",
"agent_card_location": "deployment-defined",
"sdk": "package-and-version",
"authentication": "deployment-specific",
"task_retention": "policy-reference",
"artifact_store": "approved-store",
"checked_at": "recorded-time"
}
Agent Card Schema、发现位置、Transport、Streaming 行为和 SDK API 都可能变化。应根据固定规范和运行中的 Endpoint 核对,不能直接把博客里的 Package Name 复制到生产环境。
Agent Card 是发现 Metadata
Agent Card 可能描述服务名称、Endpoint、Skill、输入输出 Mode 和 Capability。它适合 Routing,但在系统验证来源前均不可信。
需要验证:
- Transport Endpoint 是否来自 Allowlist 或可信 Registry;
- 使用 Token 时的服务身份、Issuer、Audience、Expiry 和 Key Rotation;
- Card Schema 与 Version;
- Requested Skill 是否被本地 Policy 允许;
- 每个 Task 的 Caller、Tenant 和 Target Object;
- Result Size、Artifact Type 与 Callback Destination。
Description、Skill Name、URL 和 Example 都可能包含 Prompt Injection 或误导声明。不能将 Card Text 变成可执行 Policy、自动安装或 Tool Permission。
Task 生命周期是状态机
规范使用 Task 和 Status 概念。具体状态名称和合法迁移依赖版本;生产服务应在固定协议外定义自己的持久化状态机。
accepted -> running -> waiting_for_input -> running -> terminal
| |
+-> canceled +-> succeeded | failed | rejected
同时记录 Protocol-facing Status 与 Application Status。Terminal Response 应区分:被 Policy 拒绝、作用前失败、作用结果不确定,或带证据完成。
幂等与取消
Retry、重复 Message、Timeout 和 Callback 都是分布式系统的常见行为。对于会产生副作用的 Task:
- 将 Idempotency Key 绑定 Principal、Tenant、Action 与规范化参数;
- 执行副作用前持久化 Decision;
- 让 Cancellation 可协作且感知 State;
- 无法证明副作用时返回“结果不确定”;
- 仅在业务操作支持时使用 Compensation。
不能将模型拒答或 completed 标签视为付款、删除或通知只执行一次的证据。
Message、Artifact 与不可信内容
Message Part 和 Artifact 可以承载 Text、Structured Data、File、Reference 或 URL。包括其他 Agent 输出的内容在内,都应视为不可信输入。
限制:
- Byte、Item Count、Nesting Depth 和 Decompression;
- MIME Allowlist 与 Parser 行为;
- Artifact Storage Location、Expiry、Access Scope 和 Deletion;
- Outbound Fetch Destination 与 Redirect Count;
- Telemetry Field 与原始 Payload 留存。
比起将大量敏感内容嵌入 Task Message,更适合使用经过认证访问的 Reference Artifact。File Reference 不是访问许可,Retrieval 时仍须验证。
Streaming 与 Push Delivery
Streaming 和异步通知是传递选择,并不代替 Task Durability。无论版本/Binding 使用 Server-Sent Events、Callback、Polling 或其他机制,都应定义:
- Reconnect 与 Resume;
- Event Ordering 与 Deduplication;
- Token Expiry 与重新认证;
- Callback 注册与 Destination Allowlist;
- Timeout、Backpressure 与 Result Size Budget;
- 谁可以观察或取消 Task。
Callback URL 是 SSRF 边界。验证 Destination Ownership,不能让模型或远程 Agent 选择无限制 Callback Target。
授权逐 Task、逐对象执行
OAuth、Bearer Token、mTLS、Workload Identity、RBAC 和 ABAC 都是可能的部署控制。它们并不都是 A2A 的必选功能;已经认证的 Caller 也不自动拥有全部 Skill 权限。
from dataclasses import dataclass
from enum import Enum
from typing import Callable
class Verdict(str, Enum):
ALLOW = "allow"
DENY = "deny"
CONFIRM = "confirm"
@dataclass(frozen=True)
class TaskRequest:
skill: str
object_id: str | None
@dataclass(frozen=True)
class AuthenticatedContext:
tenant_id: str
principal_id: str
def authorize(
context: AuthenticatedContext,
request: TaskRequest,
*,
allowed_skills: set[str],
can_access_object: Callable[[str, str, str], bool],
effect_class: str,
) -> Verdict:
if request.skill not in allowed_skills:
return Verdict.DENY
if request.object_id and not can_access_object(
context.tenant_id, context.principal_id, request.object_id
):
return Verdict.DENY
if effect_class in {"external_write", "destructive"}:
return Verdict.CONFIRM
return Verdict.ALLOW
这是应用层 Policy 片段,不是 A2A SDK 实现。可信 Caller Context 必须来自 Authentication Middleware,不能来自模型生成的 Task Field。effect_class 应来自服务端 Skill Registry,而不是请求体;真实的 CONFIRM 结果还需要明确的审批和审计流程。
最小生产架构
caller
-> authenticate and authorize
-> validate task shape and budget
-> persist idempotency + lifecycle event
-> remote A2A service
-> independently authenticate, authorize, and validate
-> use bounded local tools and data access
-> store artifacts in an approved scoped store
-> collect redacted result evidence
-> apply local approval / compensation / user response
每个服务都应重新检查 Policy,不能只相信上游执行。跨 Tenant Test 必须证明:Tenant A 的有效 Token 和 Task ID 无法读取或修改 Tenant B 数据。
测试失败路径
| 测试 | 应证明什么 |
|---|---|
| Card Validation | Unknown Issuer、Endpoint、Schema Revision、Skill 被拒绝 |
| Task Contract | Malformed Part、Oversized Artifact、Unsupported Mode 安全失败 |
| Authorization | Tenant、Object、Action Policy 独立于 Description 执行 |
| Lifecycle | 重复投递、Restart、Timeout、Cancellation、Late Callback 可确定处理 |
| Side Effects | Retry 不重复执行;不确定性会暴露 |
| Streaming | Reconnect、Replay、Ordering、Expiry、Backpressure 有边界 |
| Abuse | 阻止注入、投毒 Artifact、SSRF Callback、Artifact Exfiltration |
| Operations | 可观察延迟、Queue Depth、Task Cost、Retention 与 Deletion |
Policy 和副作用优先用确定性 Oracle。语言模型 Judge 可以审查答案质量,但不能证明授权、来源或财务正确性。
常见失败模式
- 将 Agent Card、Registry Listing、Badge 或 SDK Adapter 当作信任决策;
- 假设所有 A2A 实现共享同一个发现路径或 Streaming Transport;
- 接受 Task Content 中提供的 Caller Identity;
- 将 Task Completion 当作副作用只执行一次的证据;
- 未验证地转发远程 Artifact 或 Callback URL;
- 将远程 Agent 输出当作指令或授权;
- 无期限保留原始 Task Payload;
- 未测试固定 Version/Transport 就宣传 Framework 支持;
- 本地确定性 Workflow 更清晰时仍调用远程 Agent。
实现清单
- [ ] 固定 Protocol、Binding、SDK 与 Agent Card Schema Revision。
- [ ] 获取或信任 Card 前验证远程 Endpoint 来源。
- [ ] 在部署需要时双向认证。
- [ ] 在拥有服务处授权每个 Skill、Tenant、Object 和副作用。
- [ ] 持久化 Idempotency、生命周期迁移和不确定状态。
- [ ] 限制 Message、Artifact、Callback、Streaming、Retry 与 Telemetry。
- [ ] 将远程 Message、Artifact 与 Card Content 视为不可信。
- [ ] 测试 Restart、重复投递、Cancellation、Expiry、跨 Tenant 与 SSRF。
- [ ] 定义 Task、Artifact、Index、Cache、Export 的 Retention 与 Deletion。
- [ ] 使用明确 Scope、Budget 与 Rollback Control 逐步发布。
总结
A2A 可以使独立 Agent 服务实现互操作,但它不是自治的信任网络。固定运行的版本,将发现视为不可信 Metadata,使 Task State 可持久化,并在模型外执行身份、对象访问和副作用控制。最安全的引入方式是从一个窄小、只读的委派 Task 开始,只有生命周期、授权和失败证据充分时再扩展。