多智能体模式
Awaken 支持多种 agent 组合方式,包括本地委托、远程 A2A agent、sub-agent 执行以及 handoff。
通过 AgentSpec.delegates 进行 agent 委托
Section titled “通过 AgentSpec.delegates 进行 agent 委托”agent 可以通过 delegates 声明它允许委托的子 agent:
{ "id": "orchestrator", "model_id": "gpt-4o", "system_prompt": "You coordinate tasks across specialized agents.", "delegates": ["researcher", "writer", "reviewer"]}解析时,运行时会为每个 delegate 生成一个 AgentTool,LLM 看见的是普通工具,例如 agent_run_researcher。
AgentTool 持有 Arc<dyn AgentResolver>,不预选 backend。LLM 调用该工具时,execute() 在 call time 调 resolver.resolve_execution(&agent_id),resolver 按每次调用决定:
- 本地 agent(无
endpoint)解析为本地ResolvedAgent,在同一 runtime 内联执行。 - 远程 agent(有
endpoint)解析为ResolvedBackendAgent,经配置的ExecutionBackend(当前是 A2A)执行 —— 发message:send,然后轮询返回的 task 直到完成。
因为解析推迟到 call time,通过配置 API 改 delegate 的 AgentSpec(例如翻转其 endpoint)在下一次工具调用立刻生效,无需重建父 agent。
通过 A2A 使用远程 agent
Section titled “通过 A2A 使用远程 agent”如果 AgentSpec.endpoint 存在,该 delegate 会被当作远程 A2A agent:
{ "id": "remote-analyst", "model_id": "unused-for-remote", "system_prompt": "", "endpoint": { "backend": "a2a", "base_url": "https://analyst.example.com/v1/a2a", "auth": { "type": "bearer", "token": "token-abc" }, "target": "analyst", "timeout_ms": 300000, "options": { "poll_interval_ms": 1000 } }}A2aBackend 会发送 message:send,读取返回的 task.id 并轮询任务状态,再把最终结果包装成 BackendRunResult / ToolResult 返回给父 agent。远端超时、失败、等待输入、等待认证和取消会保留在 BackendRunStatus 中。
在工具里以代码方式调用 Sub-Agent
Section titled “在工具里以代码方式调用 Sub-Agent”当你写一个自定义 Tool 需要委托给另一个 agent,特别是需要严格控制父 ↔ 子 state 流动时,使用 awaken_runtime::child_agent 的 run_child_agent。它是 AgentTool 与 run_streaming_subagent 共同依赖的底层辅助函数。
run_child_agent 通过 initial_state_seed: Option<PersistedState> 接受父→子的初始状态注入,并通过 BackendRunResult.state(一个 PersistedState)把子的终态返回给父工具去解码并以 StateCommand 形式塞进 ToolOutput。子→父 state 走的是普通工具就在用的 ToolOutput.command 通路,没有单独的”sub-agent 导出”机制。
state seeding 只对 Local backend 生效。它不是 BackendProfile 里的一个
capability flag:只要解析出的 ExecutionPlan 不是本地执行,
validate_delegate_execution_request 就会拒绝
BackendDelegateRunRequest.state_seed。A2A 和自定义远程 backend 没有统一的
seed wire 协议,因此带 seed 的 delegate 请求会以 ExecutionBackendError 失败,
而不是静默丢弃 seed。只要 backend 返回了结果,子的 BackendRunResult.state
仍然可读,用于回写父侧。
Backend 实现者应使用 BackendProfile 表达 continuation、persistence、waits、
transcript shape 和 output shape 等 typed capabilities。父→子 state seed 是这个
profile 之外的本地执行规则。
Sub-Agent 模式
Section titled “Sub-Agent 模式”Orchestrator -> researcher -> result -> writer -> result -> reviewer -> result父 agent 按顺序调用子 agent,并根据前一步结果决定下一步。
如果 LLM 在同一轮推理里一次返回多个 delegate tool call,它们会使用和普通工具相同的 ToolExecutor。内置 resolver 默认安装 SequentialToolExecutor,因此委托默认逐个执行。如果这些 delegate call 相互独立,并且需要并发执行,可以通过自定义 resolver 或 ResolvedAgent::with_tool_executor(...) 安装 ParallelToolExecutor。
orchestrator -> team_lead (delegates: [dev_a, dev_b]) -> dev_a -> dev_b每一层都独立通过 AgentResolver 解析。理论上没有硬深度限制,但每层都会增加 token 和延迟成本。
Agent Handoff
Section titled “Agent Handoff”handoff 会在同一 run 内把控制权切换给另一个 agent,而不是把它当成子任务调用。
机制:
- 插件或 handoff 扩展把新 agent ID 写入活动 agent 状态键
- loop runner 在下一个步骤边界检测到变化
- 重新通过
AgentResolver解析 agent - 在同一个 thread、同一条消息历史上继续执行
Handoff 与 Delegation 的区别
Section titled “Handoff 与 Delegation 的区别”| 方面 | Delegation | Handoff |
|---|---|---|
| 控制流 | 父 agent 调子 agent,拿回结果 | 控制权直接切到新 agent |
| Thread 连续性 | 子 agent 可以有独立上下文 | 同一 thread、同一消息历史 |
| 返回路径 | 结果回到父 agent | 不返回,后续由新 agent 接管 |
| 适用场景 | 任务拆解、专长子任务 | 角色切换、升级处理、路由 |
ExecutionBackend Trait
Section titled “ExecutionBackend Trait”root execution 和 delegation 都基于 canonical ExecutionBackend:
pub trait ExecutionBackend: Send + Sync { fn capabilities(&self) -> BackendProfile;
async fn abort(&self, request: BackendAbortRequest<'_>) -> Result<(), ExecutionBackendError>;
async fn execute_root( &self, request: BackendRootRunRequest<'_>, ) -> Result<BackendRunResult, ExecutionBackendError>;
async fn execute_delegate( &self, request: BackendDelegateRunRequest<'_>, ) -> Result<BackendRunResult, ExecutionBackendError>;}BackendRunResult 保留 agent ID、状态、终止原因、可选响应文本、结构化输出、run ID、inbox、run-scoped 持久化状态,以及可选的 thread-scoped 持久化状态。BackendRunStatus 包含 Completed、WaitingInput、WaitingAuth、Suspended、Failed、Cancelled 和 Timeout。
这也是实现自定义本地或远程执行后端的扩展点。awaken_runtime::extensions::a2a 仍然重新导出 AgentBackend、AgentBackendFactory 和 DelegateRunResult 作为兼容别名,但新代码应使用 ExecutionBackend 命名。
- 在工具里调用 Sub-Agent ——
run_child_agent操作指南 - A2A 协议
- 架构
- Tool 与 Plugin 的边界