协作约 12 分钟

A2A 服务

智能体之间用 A2A 协议对话:两条入口共用一个执行器和任务存储,路由配置决定请求交给本地智能体、远端智能体还是回给请求方。

依据 agent-runtime develop@0a47a523(2026-11-12)核实

A2A 是什么

A2A(Agent-to-Agent)是一种智能体之间互相调用的开放协议:每个智能体用一张 Agent Card 描述自己能干什么,别人按标准的 JSON-RPC 发消息,对话以 Task 为单位推进,Task 有提交、处理中、需要输入、完成、失败等状态。

agent-runtime 的 applications/a2a_service 就是一个 A2A 服务的实现。

三个端点

端点用途
GET /a2a/.well-known/agent-card.json标准 Agent Card
POST /a2a/标准 A2A JSON-RPC 入口
POST /v1/{project_id}/agents/{agent_id}/conversations/{conv_id}定制入口,兼容某个已有平台的请求格式,支持 SSE 流式返回
源码A2A 服务入口agent-runtime/applications/a2a_service/app.py@0a47a523

两条路径共用同一个执行器和同一个 Redis 任务存储,所以不管从哪个入口进来,Task 状态都是一致的。

定制入口怎么接上多轮对话:首轮在 Redis 里按会话 ID 查不到任务,就新建一个 task_id 写进去;续轮从 Redis 取回 task_id,再从任务存储读出 Task。执行器看 Task 当前状态是不是 INPUT_REQUIRED,判断这是不是续轮。

执行器只做一件事

Executor.execute 的原则写在注释里:只做"构建事件 → 分发",不判断路由目标。

  1. 如果是被别的智能体调用的,从请求里取出上游的 traceparent 接上链路
  2. 解析出用户问题、原始请求头和请求体
  3. 拿到这个会话的心跳管理器(长任务期间保持连接)
  4. 包成一个标准化事件,交给 RouteDispatcher
源码Executoragent-runtime/applications/a2a_service/orchestrator/executor.py:94@0a47a523

路由由配置决定

RouteDispatcher 读一份路由配置,把事件交给三类处理器之一:

处理器负责
requester面向请求方:哪些状态算"挂起等用户"
local_agent本进程里的智能体:哪些事件类型算"委托出去"
remote_agent远端智能体:远端返回的状态怎么映射成内部帧类型,哪些算终止

默认配置的关键内容:

max_cascade_depth: 10            # 委托链最多 10 层
default_profile:
  requester:
    suspended_states: [INPUT_REQUIRED, AUTH_REQUIRED]
  local_agent:
    delegate_types: [delegate, sub_agent_dispatch, multi_delegate]
  remote_agent:
    terminal_frame_types: [CONTROL_COMPLETED, CONTROL_FAILED]
源码route_config.yamlagent-runtime/applications/a2a_service/orchestrator/config/route_config.yaml@0a47a523

处理器类名也写在配置里、运行时加载,所以换一个远端协议或加一种处理方式,不用改执行器。max_cascade_depth 防止智能体之间无限互相委托。

渠道适配

不同的前端渠道请求格式各不一样。Channel 抽象定义三件事:解析请求、构建 A2A 消息、把事件格式化成渠道要的样子。新接一个渠道就是再写一个 Channel。

源码Channelagent-runtime/applications/a2a_service/channels/base.py:22@0a47a523

小结

  • A2A 服务对外同时提供标准入口和定制入口,共用执行器和任务存储。
  • 执行器只构建事件、分发;路由规则、挂起状态、终止状态都在配置里。
  • 委托链有深度上限,跨智能体的链路追踪靠 traceparent 串联。
  • 任务状态机的细节,在 agent-solution 的"A2A Task 状态机"一关里动手体验。

源码出处

链接指向固定提交,仓库后续更新不影响这里的行号。

过关测验

  1. 1. A2A 服务的标准入口和定制入口,Task 状态是否一致?

  2. 2. 按默认路由配置,远端智能体回了 INPUT_REQUIRED,请求方会怎样?

  3. 3. 主智能体调用子智能体时,链路追踪怎么串起来?

通关条件

  • ○ 测验全部答对