用 A2A 把工单分析交给专长 Agent:一次完整的任务交接

用 A2A 把工单分析交给专长 Agent:一次完整的任务交接

一个客服系统里有两个 Agent:协调 Agent 面向用户,会判断"这张工单该给谁";工单分析 Agent 是专长 Agent,擅长定位根因并给出处理建议。它们之间用 A2A 交接任务。工单数据在哪里、工具怎么调、权限怎么批,发生在专长 Agent 内部(那里用的是 MCP,见文末边界)——A2A 管的是两个 Agent 之间的事:发现、任务状态、消息、产出物和恢复。

前置阅读:状态与消息语义见Task 运行时指南 ,幂等与恢复模式见任务幂等与恢复 。这里把它们放进同一个场景走一遍。

走查总览

  sequenceDiagram
    participant U as 用户
    participant C as 协调 Agent(A2A 客户端)
    participant S as 工单分析 Agent(A2A 服务端)

    U->>C: "这张工单什么问题?"
    C->>S: 读取 /.well-known/agent-card.json(发现)
    C->>S: message/send(分析请求,messageId=m1)
    S-->>C: Task(SUBMITTED)
    S-->>C: Task(WORKING)
    S-->>C: Task(INPUT_REQUIRED):缺复现步骤
    C->>S: message/send(补充信息,messageId=m2,同 contextId)
    S-->>C: Task(WORKING)
    S-->>C: Artifact:结构化分析报告(分块,lastChunk)
    S-->>C: Task(COMPLETED) + 结论 Message
    C-->>U: 根因与建议

1. 发现:按技能选,不只看名字

协调 Agent 从 /.well-known/agent-card.json 读取卡片,用三条信息做决定:

看什么本场景的判定
skills有没有"工单 / 根因分析"相关技能;技能的 tags 比名字更可靠
capabilitiesstreaming 或 pushNotifications 至少一个为 true,长时间分析才不会盲等
securitySchemes / securityRequirements自己有没有对应的凭据去调用

发现机制与卡片字段见智能体发现 与Agent Card 实现指南 。协调 Agent 应当缓存卡片并尊重其缓存窗口,而不是每次交接都重新发现。

2. 发起:把幂等键放进第一条消息

{
  "jsonrpc": "2.0",
  "id": "req-101",
  "method": "message/send",
  "params": {
    "message": {
      "role": "role_user",
      "parts": [{ "kind": "text", "text": "分析工单 TCK-4821:客户报告结账后订单状态未更新" }],
      "messageId": "coord-4f21-m1",
      "contextId": "ctx-tck4821"
    }
  }
}

两个决定此时做出,之后不再改:

  • messageId 含上游标识(工单号):超时重发时原样重发同一个值,服务端用它与 (contextId) 一起识别重复,不会重新分析一遍;
  • contextId 用工单号命名:这张工单后续所有任务(重新分析、补充材料、升级处理)都在同一上下文里,对话历史与归属可查。

服务端返回 Task(SUBMITTED 或 WORKING),记下 taskId——它是后续所有操作的对象。

3. 跟踪:每个状态对应协调 Agent 的一个动作

任务状态协调 Agent 做什么
SUBMITTED / WORKING等待;已订阅事件流或推送则被动接收,否则按退避 GetTask
INPUT_REQUIRED向用户要信息,拿到后作为新 messageId 的消息发回同一任务
AUTH_REQUIRED按任务状态消息说明的授权去完成(联系审批人或带外授权),见安全实现 第 4 节
COMPLETED读取 Artifact 与最终 Message,交给用户
FAILED / CANCELED / REJECTED按原因决定:重试(新任务同 contextId)、换 Agent 或上报

本场景在 INPUT_REQUIRED 停了一次:分析 Agent 要复现步骤。协调 Agent 向用户取回后在同一个任务上继续:

{
  "jsonrpc": "2.0",
  "id": "req-102",
  "method": "message/send",
  "params": {
    "message": {
      "role": "role_user",
      "parts": [{ "kind": "text", "text": "复现步骤:下单后 30 秒内刷新两次订单页" }],
      "messageId": "coord-4f21-m2",
      "taskId": "task-9c31",
      "contextId": "ctx-tck4821"
    }
  }
}

messageId 是新的(这是新输入,不是重发),taskId 与 contextId 保持不变。

4. 接收:报告是 Artifact,结论是 Message

分析结果分两层到达:

  • Artifact(结构化报告):根因、置信度、受影响订单清单、建议动作。流式交付时分块到达,以 lastChunk: true 结束;协调 Agent 按 artifactId 聚合,不假设块数;
  • Message(最终说明):一段给协调 Agent 转述给用户的自然语言结论。
{
  "jsonrpc": "2.0",
  "id": "req-103",
  "method": "tasks/get",
  "params": { "taskId": "task-9c31" }
}

Task.artifacts 里的报告与 Task.status.message 里的结论一起构成完整交付。字段细节见 Artifact 对象页 与Message 对象页 。

5. 恢复:协调 Agent 的核对清单

走查中任何一步都可能断,逐项核对:

观察动作
message/send 超时,不知是否送达原样重发(同 messageId);服务端幂等返回首次结果
事件流中途断开SubscribeToTask 重连;不支持续传时对重复事件按序号去重
只能轮询GetTask 退避轮询直到终态;不把流断开当任务失败
WORKING 超过工单时限CancelTask,然后在同 contextId 下发新任务(终态任务不可重启)
交接链上还要授权把自己的任务转 AUTH_REQUIRED 向上委托,凭据绑定发起方
分析 Agent 不可用用缓存卡片里的其他接口重试一次,仍失败则按发现机制换 Agent,并在新 contextId 记录交接原因

恢复的完整决策树与探针见任务幂等与恢复 ;推送通道的加固见推送接收方加固 。

边界:MCP 那一侧

工单分析 Agent 内部用 MCP 读取工单系统的数据、调用受控工具(退款查询、订单状态 API),并把权限失败映射为 A2A 的 AUTH_REQUIRED 或 FAILED。这些属于 MCP 的职责边界:MCP Server / Client、工具与资源、最小权限、调用失败与可观察结果,见 MCP 中文站的对应实践 。两个协议分工的总览见A2A 与 MCP 。

相关页面

版本与验证说明

对齐 A2A v1.0.1。消息、任务与产出物字段以数据结构 为准;序列图与核对清单由本场景的消息流组成,可直接作为验收清单逐项核对。messageId、contextId 的取值模式是本站建议,协议只要求由发送方生成。

来源:A2A 数据结构 、任务的生命周期 。