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 |
#mermaid-svg-I7YOfZcY6yoM1qQW{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-I7YOfZcY6yoM1qQW .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-I7YOfZcY6yoM1qQW .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-I7YOfZcY6yoM1qQW .error-icon{fill:#552222;}#mermaid-svg-I7YOfZcY6yoM1qQW .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-I7YOfZcY6yoM1qQW .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-I7YOfZcY6yoM1qQW .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-I7YOfZcY6yoM1qQW .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-I7YOfZcY6yoM1qQW .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-I7YOfZcY6yoM1qQW .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-I7YOfZcY6yoM1qQW .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-I7YOfZcY6yoM1qQW .marker{fill:#333333;stroke:#333333;}#mermaid-svg-I7YOfZcY6yoM1qQW .marker.cross{stroke:#333333;}#mermaid-svg-I7YOfZcY6yoM1qQW svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-I7YOfZcY6yoM1qQW p{margin:0;}#mermaid-svg-I7YOfZcY6yoM1qQW .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-I7YOfZcY6yoM1qQW .cluster-label text{fill:#333;}#mermaid-svg-I7YOfZcY6yoM1qQW .cluster-label span{color:#333;}#mermaid-svg-I7YOfZcY6yoM1qQW .cluster-label span p{background-color:transparent;}#mermaid-svg-I7YOfZcY6yoM1qQW .label text,#mermaid-svg-I7YOfZcY6yoM1qQW span{fill:#333;color:#333;}#mermaid-svg-I7YOfZcY6yoM1qQW .node rect,#mermaid-svg-I7YOfZcY6yoM1qQW .node circle,#mermaid-svg-I7YOfZcY6yoM1qQW .node ellipse,#mermaid-svg-I7YOfZcY6yoM1qQW .node polygon,#mermaid-svg-I7YOfZcY6yoM1qQW .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-I7YOfZcY6yoM1qQW .rough-node .label text,#mermaid-svg-I7YOfZcY6yoM1qQW .node .label text,#mermaid-svg-I7YOfZcY6yoM1qQW .image-shape .label,#mermaid-svg-I7YOfZcY6yoM1qQW .icon-shape .label{text-anchor:middle;}#mermaid-svg-I7YOfZcY6yoM1qQW .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-I7YOfZcY6yoM1qQW .rough-node .label,#mermaid-svg-I7YOfZcY6yoM1qQW .node .label,#mermaid-svg-I7YOfZcY6yoM1qQW .image-shape .label,#mermaid-svg-I7YOfZcY6yoM1qQW .icon-shape .label{text-align:center;}#mermaid-svg-I7YOfZcY6yoM1qQW .node.clickable{cursor:pointer;}#mermaid-svg-I7YOfZcY6yoM1qQW .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-I7YOfZcY6yoM1qQW .arrowheadPath{fill:#333333;}#mermaid-svg-I7YOfZcY6yoM1qQW .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-I7YOfZcY6yoM1qQW .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-I7YOfZcY6yoM1qQW .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-I7YOfZcY6yoM1qQW .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-I7YOfZcY6yoM1qQW .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-I7YOfZcY6yoM1qQW .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-I7YOfZcY6yoM1qQW .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-I7YOfZcY6yoM1qQW .cluster text{fill:#333;}#mermaid-svg-I7YOfZcY6yoM1qQW .cluster span{color:#333;}#mermaid-svg-I7YOfZcY6yoM1qQW div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-I7YOfZcY6yoM1qQW .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-I7YOfZcY6yoM1qQW rect.text{fill:none;stroke-width:0;}#mermaid-svg-I7YOfZcY6yoM1qQW .icon-shape,#mermaid-svg-I7YOfZcY6yoM1qQW .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-I7YOfZcY6yoM1qQW .icon-shape p,#mermaid-svg-I7YOfZcY6yoM1qQW .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-I7YOfZcY6yoM1qQW .icon-shape .label rect,#mermaid-svg-I7YOfZcY6yoM1qQW .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-I7YOfZcY6yoM1qQW .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-I7YOfZcY6yoM1qQW .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-I7YOfZcY6yoM1qQW :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} A2A Task
gRPC
MCP tools/call
Supervisor Agent
Partner Agent
Python Worker
Order MCP Server
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 状态机
#mermaid-svg-5gVCOgyZ7lidsDgm{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5gVCOgyZ7lidsDgm .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5gVCOgyZ7lidsDgm .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5gVCOgyZ7lidsDgm .error-icon{fill:#552222;}#mermaid-svg-5gVCOgyZ7lidsDgm .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5gVCOgyZ7lidsDgm .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5gVCOgyZ7lidsDgm .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5gVCOgyZ7lidsDgm .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5gVCOgyZ7lidsDgm .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5gVCOgyZ7lidsDgm .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5gVCOgyZ7lidsDgm .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5gVCOgyZ7lidsDgm .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5gVCOgyZ7lidsDgm .marker.cross{stroke:#333333;}#mermaid-svg-5gVCOgyZ7lidsDgm svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5gVCOgyZ7lidsDgm p{margin:0;}#mermaid-svg-5gVCOgyZ7lidsDgm defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-5gVCOgyZ7lidsDgm g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-5gVCOgyZ7lidsDgm g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-5gVCOgyZ7lidsDgm g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-5gVCOgyZ7lidsDgm g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-5gVCOgyZ7lidsDgm g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-5gVCOgyZ7lidsDgm .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-5gVCOgyZ7lidsDgm .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-5gVCOgyZ7lidsDgm .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-5gVCOgyZ7lidsDgm .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-5gVCOgyZ7lidsDgm .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-5gVCOgyZ7lidsDgm .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-5gVCOgyZ7lidsDgm .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-5gVCOgyZ7lidsDgm .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5gVCOgyZ7lidsDgm .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5gVCOgyZ7lidsDgm .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5gVCOgyZ7lidsDgm .edgeLabel .label text{fill:#333;}#mermaid-svg-5gVCOgyZ7lidsDgm .label div .edgeLabel{color:#333;}#mermaid-svg-5gVCOgyZ7lidsDgm .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-5gVCOgyZ7lidsDgm .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-5gVCOgyZ7lidsDgm .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-5gVCOgyZ7lidsDgm .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-5gVCOgyZ7lidsDgm .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-5gVCOgyZ7lidsDgm .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5gVCOgyZ7lidsDgm .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5gVCOgyZ7lidsDgm #statediagram-barbEnd{fill:#333333;}#mermaid-svg-5gVCOgyZ7lidsDgm .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5gVCOgyZ7lidsDgm .cluster-label,#mermaid-svg-5gVCOgyZ7lidsDgm .nodeLabel{color:#131300;}#mermaid-svg-5gVCOgyZ7lidsDgm .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-5gVCOgyZ7lidsDgm .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-5gVCOgyZ7lidsDgm .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-5gVCOgyZ7lidsDgm .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-5gVCOgyZ7lidsDgm .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-5gVCOgyZ7lidsDgm .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-5gVCOgyZ7lidsDgm .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-5gVCOgyZ7lidsDgm .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-5gVCOgyZ7lidsDgm .note-edge{stroke-dasharray:5;}#mermaid-svg-5gVCOgyZ7lidsDgm .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-5gVCOgyZ7lidsDgm .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-5gVCOgyZ7lidsDgm .statediagram-note text{fill:black;}#mermaid-svg-5gVCOgyZ7lidsDgm .statediagram-note .nodeLabel{color:black;}#mermaid-svg-5gVCOgyZ7lidsDgm .statediagram .edgeLabel{color:red;}#mermaid-svg-5gVCOgyZ7lidsDgm #dependencyStart,#mermaid-svg-5gVCOgyZ7lidsDgm #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-5gVCOgyZ7lidsDgm .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5gVCOgyZ7lidsDgm :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} worker accepts
artifact ready
error
cancel RPC
policy deny
submitted
working
completed
failed
cancelled
rejected
| 状态 |
含义 |
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 |
Worker Agent A2A Server Supervisor Worker Agent A2A Server Supervisor #mermaid-svg-5oShGJLEUNSovtoS{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5oShGJLEUNSovtoS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5oShGJLEUNSovtoS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5oShGJLEUNSovtoS .error-icon{fill:#552222;}#mermaid-svg-5oShGJLEUNSovtoS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5oShGJLEUNSovtoS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5oShGJLEUNSovtoS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5oShGJLEUNSovtoS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5oShGJLEUNSovtoS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5oShGJLEUNSovtoS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5oShGJLEUNSovtoS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5oShGJLEUNSovtoS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5oShGJLEUNSovtoS .marker.cross{stroke:#333333;}#mermaid-svg-5oShGJLEUNSovtoS svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5oShGJLEUNSovtoS p{margin:0;}#mermaid-svg-5oShGJLEUNSovtoS .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-5oShGJLEUNSovtoS text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-5oShGJLEUNSovtoS .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-5oShGJLEUNSovtoS .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-5oShGJLEUNSovtoS .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-5oShGJLEUNSovtoS .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-5oShGJLEUNSovtoS #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-5oShGJLEUNSovtoS .sequenceNumber{fill:white;}#mermaid-svg-5oShGJLEUNSovtoS #sequencenumber{fill:#333;}#mermaid-svg-5oShGJLEUNSovtoS #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-5oShGJLEUNSovtoS .messageText{fill:#333;stroke:none;}#mermaid-svg-5oShGJLEUNSovtoS .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-5oShGJLEUNSovtoS .labelText,#mermaid-svg-5oShGJLEUNSovtoS .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-5oShGJLEUNSovtoS .loopText,#mermaid-svg-5oShGJLEUNSovtoS .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-5oShGJLEUNSovtoS .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-5oShGJLEUNSovtoS .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-5oShGJLEUNSovtoS .noteText,#mermaid-svg-5oShGJLEUNSovtoS .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-5oShGJLEUNSovtoS .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-5oShGJLEUNSovtoS .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-5oShGJLEUNSovtoS .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-5oShGJLEUNSovtoS .actorPopupMenu{position:absolute;}#mermaid-svg-5oShGJLEUNSovtoS .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-5oShGJLEUNSovtoS .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-5oShGJLEUNSovtoS .actor-man circle,#mermaid-svg-5oShGJLEUNSovtoS line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-5oShGJLEUNSovtoS :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} tasks/send task_id dispatch SSE status-update SSE forward artifact tasks/get completed
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 重试 |