A2A 协议与 Agent 互操作 · Task 生命周期
🏠 返回 07-README | ⬅️ 13-跨语言混合栈 | ➡️ 15-MCP生产宿主
定位:Agent↔Agent 任务委托 的 Staff 专章——Task 生命周期、JSON-RPC/SSE、与 MCP/gRPC 分工。机制散见 04 §8、05 §A2A。
§0 面试前 30 分钟 Checklist
| 时间 | 动作 |
|---|
| 5 min | 背 三协议分工:A2A / MCP / gRPC |
| 5 min | 画 Task 状态机 submitted→working→completed/failed |
| 5 min | 口述 Artifact vs Tool 结果 |
| 5 min | 链 release_id 与 11 Registry |
| 5 min | 准备 §11 STAR 超时雪崩 |
| 5 min | 过 §12 Runbook + Q1–Q10 |
开场金句(90s):
「A2A 解决 Agent 之间派活:有状态 Task、可流式进度、可取消;MCP 解决 调工具——单步、无状态。我们 Java Supervisor 对内用 gRPC Task(13),对外联盟伙伴用 A2A;无论哪种,都绑 release_id,Worker 不信对方传来的订单金额。」
L1 · 是什么
1.1 一句话
A2A(Agent2Agent) = 开放 Agent 互操作 协议:用标准 Task 抽象把「请另一个 Agent 完成目标」变成可审计、可版本化、可跨厂商的 API——编排层,不替代 MCP。
1.2 三协议对照(必背)
| 协议 | 抽象 | 状态 | 典型传输 | 本库章节 |
|---|
| MCP | Tool / Resource | 无状态单步 | stdio / SSE | 15 |
| A2A | Task / Message / Artifact | 有状态多步 | HTTP JSON-RPC + SSE | 本篇 |
| gRPC Task | 内部 Protobuf | 有状态 | gRPC | 13 |
1.3 何时用 A2A
| 用 A2A | 不用 A2A |
|---|
| 跨团队 / 跨云 Agent 能力外包 | 同进程 Multi-Agent(内存总线) |
| 需要 任务进度流式推送 | 单次查库存(MCP) |
| 联盟生态互认 | 强同步低延迟内网(gRPC) |
1.4 与 Multi-Agent 拓扑的关系
| 拓扑 | A2A 角色 |
|---|
| Supervisor–Worker | Supervisor 对外发 A2A Task |
| 对等协商 | 双向 Task,需冲突解决 |
| 流水线 | 上游 Artifact 作下游 Task context |
对照:05-Multi-Agent、demo multi-agent-supervisor-springai。
L2 · Task 生命周期(深展)
2.1 状态机
| 状态 | 含义 | Supervisor 动作 |
|---|
submitted | 已创建未执行 | 可取消 |
working | 执行中 | 订阅 SSE / 轮询 get |
completed | 终态成功 | 取 Artifact |
failed | 终态失败 | 降级 / 转人工 |
cancelled | 用户或上游取消 | 清理副作用 |
rejected | 策略拒绝 | 记录 audit,不 retry send |
2.2 核心对象
| 对象 | 字段(示意) | 说明 |
|---|
| Task | id, goal, context, metadata.release_id | 委托请求 |
| Message | role, parts[] | 对话片段 |
| Artifact | parts[], structured_output | 交付物(非 Tool 日志) |
与 [13] gRPC 对齐:AgentTask / AgentArtifact 是内部实现;对外 A2A 用 JSON 字段名遵循开放规范。
2.3 JSON-RPC 方法矩阵
| 方法 | 幂等 | 用途 |
|---|
tasks/send | 是(同 task_id) | 创建并可选立即执行 |
tasks/get | 是 | 轮询状态 |
tasks/cancel | 是 | 取消 working |
tasks/subscribe | 只读流 | SSE 进度 |
Staff:send 必须客户端生成 全局唯一 task_id;服务端以 task_id 去重。
2.4 SSE 事件类型
| event | 含义 | 客户端处理 |
|---|
status-update | working 进度 | 更新 UI |
artifact-update | 部分交付 | 增量展示 |
error | 可恢复错误 | 退避重连 |
done | 流结束 | 再 get 确认终态 |
2.5 非法迁移 Golden
| case | 期望 |
|---|
| completed → working | reject |
| cancel 后 MCP 写 | 无写 |
| 重复 send 同 id | 返回同一 Task |
L3 · 生产落地
3.1 安全与信任
| 规则 | 原因 |
|---|
| Task 只带 case_id / 槽位 | 防 PII、防篡改金额 |
| Worker 重查权威服务 | 不信 Supervisor 转述 |
mTLS + tenant_id | 联盟多租户 |
release_id 在 metadata | 对齐 11 |
3.2 超时与背压
| 层 | 策略 |
|---|
| Client | 总 deadline(如 120s) |
| Server | 队列深度上限 → rejected |
| 重试 | 仅 get 幂等;不盲重发 send |
3.3 与 Registry / Eval
| 绑定 | 说明 |
|---|
metadata.release_id | 全链归因 |
| Golden | 测非法状态迁移、cancel 后无写 |
| Gate | task_failed_rate 阈值;非 Tool 层指标 |
3.4 Java 实现要点
| 组件 | 建议 |
|---|
| 入口 | Spring MVC /a2a + SseEmitter |
| 鉴权 | Gateway OAuth2 + scope a2a:invoke |
| 执行 | 线程池隔离;Worker 池 bulkhead |
| 审计 | 每个 Task 写 trace_id |
3.5 Python Worker 要点
| 组件 | 建议 |
|---|
| 框架 | FastAPI + Pydantic Task 模型 |
| 引擎 | LangGraph 子图作 Worker |
| 取消 | cooperative cancel token 传 Tool |
L7 · 失败模式目录(A2A)
| 现象 | 根因 | 止血 | 根治 |
|---|
| 重复 send 风暴 | 把 send 当非幂等 | 熔断+只重试 get | Golden 重复 send |
| SSE 断连丢终态 | 只靠 SSE | 断连后 get | 终态以 get 为准 |
| Artifact 含 PII | Tool 日志直出 | 结构化脱敏 | Schema 审查 |
| 跨租户 Task | metadata 未校验 | rejected | Gateway 强制 tenant |
| release 漂移 | 未 pin Worker | Registry 门禁 | 双组件 release_id |
L8 · 迁移路径(四阶段)
| 阶段 | 动作 | 验收 |
|---|
| P0 | 内网 gRPC Task 稳定 | [13] Golden 绿 |
| P1 | 只读 A2A 查询伙伴 | 无写 Tool |
| P2 | 写路径 MCP 白名单 | illegal_tool_rate=0 |
| P3 | 联盟 SSE + SLA | task_failed_rate 达标 |
L9 · 与 Browser / VIP 场景
| 场景 | A2A 用法 |
|---|
| Browser | 外包「复杂填表」给伙伴 Agent;本库主路径 05b |
| VIP | 外包「私人造型」Agent;金额承诺仍在 Java 控制面 |
L10 · Runnable 对照
L11 · Staff 答辩
STAR:A2A 重试风暴
| 要素 | 内容 |
|---|
| S | 联盟 Worker 429,Supervisor 重试 tasks/send 放大流量 |
| A | 改幂等 task_id;指数退避;熔断;只重试 get |
| M | 把 send 当非幂等导致重复副作用 |
| P | 限流恢复;Golden 增重复 send 负例 |
STAR:SSE 断连误判失败
| 要素 | 内容 |
|---|
| S | 移动端 SSE 断连,Supervisor 当 failed 触发补偿写 |
| A | 终态以 get 为准;补偿前再 get;写操作幂等 |
| M | 补偿写重复发货 |
| P | 关闭自动补偿;Runbook 强制 get 二次确认 |
Q1 · A2A 和 MCP?
标准答案:编排 vs Tool;Task 有状态 vs tools/call 单步。
追问:MCP 能否承载多步?→ 可以但不推荐,审计差。
Q2 · 为何不全用 A2A 替代 gRPC?
标准答案:内网延迟、Protobuf 演进、团队边界。
追问:联盟伙伴只支持 REST 怎么办?→ Gateway 翻译。
Q3 · Artifact 放什么?
标准答案:结构化结论+引用;不放全量 Tool 日志。
追问:需要中间推理链吗?→ 进 Trace,不进 Artifact。
Q4 · 如何版本化?
标准答案:metadata.release_id + capability 协商。
追问:伙伴未升级 schema?→ rejected + 降级路径。
Q5 · OpenClaw 能当 A2A Server?
标准答案:不适合生产;见 12。
追问:个人 Agent 数据驻留?→ 企业禁。
Q6 · cancel 后副作用?
标准答案:Worker cooperative cancel;MCP 写需幂等。
追问:已写一半怎么办?→ saga 补偿。
Q7 · 多 Task 并行?
标准答案:Supervisor 预算分配;每 Task 独立 task_id。
追问:共享上下文?→ context_slice 最小化。
Q8 · A2A 指标?
标准答案:task_failed_rate、P99 latency、cancel 成功率。
追问:与 Eval acc 关系?→ 正交,都过才发版。
Q9 · 谁生成 task_id?
标准答案:调用方 Supervisor,UUIDv7 推荐。
追问:服务端生成?→ 不利于幂等重试。
Q10 · 与 Temporal?
标准答案:Temporal 长流程;A2A 短委托;见 04-java/04。
追问:二选一?→ 组合。
L12 · Oncall Runbook(task_failed_rate 告警)
- 按 release_id 分组失败率
- 抽样 5 条 Task trace 看 failed 原因
- 若 429 → 降并发 + 退避
- 若 schema → 回滚 Registry tool_schema 或 Worker
- 恢复后跑 Golden illegal 迁移
§15 Checklist
§16 导航
L1
L2
L4 · 参数与容量(深展)
2.6 生产参数卡 #1
| 参数 | 推荐值 | 说明 |
|---|
task_timeout_sec | 65 | 单 Task 上限 |
sse_heartbeat_sec | 15 | 保活 |
max_concurrent_tasks | 21 | Worker 背压 |
retry_get_max | 3 | 仅 get 重试 |
2.7 生产参数卡 #2
| 参数 | 推荐值 | 说明 |
|---|
task_timeout_sec | 70 | 单 Task 上限 |
sse_heartbeat_sec | 15 | 保活 |
max_concurrent_tasks | 22 | Worker 背压 |
retry_get_max | 3 | 仅 get 重试 |
2.8 生产参数卡 #3
| 参数 | 推荐值 | 说明 |
|---|
task_timeout_sec | 75 | 单 Task 上限 |
sse_heartbeat_sec | 15 | 保活 |
max_concurrent_tasks | 23 | Worker 背压 |
retry_get_max | 3 | 仅 get 重试 |
2.9 生产参数卡 #4
| 参数 | 推荐值 | 说明 |
|---|
task_timeout_sec | 80 | 单 Task 上限 |
sse_heartbeat_sec | 15 | 保活 |
max_concurrent_tasks | 24 | Worker 背压 |
retry_get_max | 3 | 仅 get 重试 |
2.10 生产参数卡 #5
| 参数 | 推荐值 | 说明 |
|---|
task_timeout_sec | 85 | 单 Task 上限 |
sse_heartbeat_sec | 15 | 保活 |
max_concurrent_tasks | 25 | Worker 背压 |
retry_get_max | 3 | 仅 get 重试 |
2.11 生产参数卡 #6
| 参数 | 推荐值 | 说明 |
|---|
task_timeout_sec | 90 | 单 Task 上限 |
sse_heartbeat_sec | 15 | 保活 |
max_concurrent_tasks | 26 | Worker 背压 |
retry_get_max | 3 | 仅 get 重试 |
2.12 生产参数卡 #7
| 参数 | 推荐值 | 说明 |
|---|
task_timeout_sec | 95 | 单 Task 上限 |
sse_heartbeat_sec | 15 | 保活 |
max_concurrent_tasks | 27 | Worker 背压 |
retry_get_max | 3 | 仅 get 重试 |
2.13 生产参数卡 #8
| 参数 | 推荐值 | 说明 |
|---|
task_timeout_sec | 100 | 单 Task 上限 |
sse_heartbeat_sec | 15 | 保活 |
max_concurrent_tasks | 28 | Worker 背压 |
retry_get_max | 3 | 仅 get 重试 |
2.14 生产参数卡 #9
| 参数 | 推荐值 | 说明 |
|---|
task_timeout_sec | 105 | 单 Task 上限 |
sse_heartbeat_sec | 15 | 保活 |
max_concurrent_tasks | 29 | Worker 背压 |
retry_get_max | 3 | 仅 get 重试 |
2.15 生产参数卡 #10
| 参数 | 推荐值 | 说明 |
|---|
task_timeout_sec | 110 | 单 Task 上限 |
sse_heartbeat_sec | 15 | 保活 |
max_concurrent_tasks | 30 | Worker 背压 |
retry_get_max | 3 | 仅 get 重试 |
2.16 生产参数卡 #11
| 参数 | 推荐值 | 说明 |
|---|
task_timeout_sec | 115 | 单 Task 上限 |
sse_heartbeat_sec | 15 | 保活 |
max_concurrent_tasks | 31 | Worker 背压 |
retry_get_max | 3 | 仅 get 重试 |
2.17 生产参数卡 #12
| 参数 | 推荐值 | 说明 |
|---|
task_timeout_sec | 120 | 单 Task 上限 |
sse_heartbeat_sec | 15 | 保活 |
max_concurrent_tasks | 32 | Worker 背压 |
retry_get_max | 3 | 仅 get 重试 |
2.18 生产参数卡 #13
| 参数 | 推荐值 | 说明 |
|---|
task_timeout_sec | 125 | 单 Task 上限 |
sse_heartbeat_sec | 15 | 保活 |
max_concurrent_tasks | 33 | Worker 背压 |
retry_get_max | 3 | 仅 get 重试 |
2.19 生产参数卡 #14
| 参数 | 推荐值 | 说明 |
|---|
task_timeout_sec | 130 | 单 Task 上限 |
sse_heartbeat_sec | 15 | 保活 |
max_concurrent_tasks | 34 | Worker 背压 |
retry_get_max | 3 | 仅 get 重试 |
2.20 生产参数卡 #15
| 参数 | 推荐值 | 说明 |
|---|
task_timeout_sec | 135 | 单 Task 上限 |
sse_heartbeat_sec | 15 | 保活 |
max_concurrent_tasks | 35 | Worker 背压 |
retry_get_max | 3 | 仅 get 重试 |
所有评论(0)