3.5 Sub-agent¶
本节摘要
从State Management角度看,OpenClaw Sub-agent 的核心特点是:基于 Session 树管理状态继承,Steer 机制允许运行时修改 Agent 状态,持久化注册表确保 Gateway 重启不丢失。本节按「继承/隔离什么 → 怎么交换和修改状态 → 状态持久化」展开。
一、Sub-agent 继承/隔离了哪些状态¶
Session 树模型¶
OpenClaw 通过 SessionEntry 字段构建父子 Session 树:
| 字段 | 含义 | 对State Management的影响 |
|---|---|---|
spawnedBy |
创建者 session key | 追踪状态来源 |
parentSessionKey |
父 session key | 确定继承关系 |
spawnDepth |
树深度(0=root) | 控制嵌套深度 |
subagentRole |
orchestrator / leaf |
决定工具集和职责 |
Session key 分层命名:agent:<agentId>:subagent:<uuid>。
状态隔离策略¶
| 状态 | Sub-agent 行为 |
|---|---|
| 对话历史 | ❌ 隔离——独立的 JSONL transcript |
| 工具集 | 部分继承——默认不自动获得父级全部工具,需配置 |
| 模型/thinking | 可独立配置——Sub-agent 可用不同的模型和推理档位 |
| 沙箱 | 可继承——配置控制是否继承父级的沙箱设置 |
| 会话状态 | 独立——独立的 SessionEntry |
与 Claude Code(Fork 模式共享 Prompt Cache 前缀)不同,OpenClaw 的 Sub-agent 完全基于独立 Session——不存在「缓存共享」的概念,因为 OpenClaw 不做 Prompt Cache 优化。
二、怎么交换和修改状态¶
创建 Sub-agent¶
通过 sessions_spawn 工具创建后台子运行,完成后 announce 回请求方通道。
Steer:运行时状态修改¶
Steer 是 OpenClaw 最独特的机制——允许在 Agent 正在 streaming 响应时注入新指令,直接修改正在进行的对话状态:
sequenceDiagram
participant User
participant Gateway
participant Agent as Agent (streaming)
Agent->>Gateway: 正在生成响应...
User->>Gateway: 发送新消息
Gateway->>Agent: steer("新指令")
Note over Agent: 中断当前生成<br/>处理新指令
Agent->>Gateway: 基于新指令的响应
对 Sub-agent 同样适用——orchestrator 可以通过 subagents 工具的 steer 操作向运行中的 leaf Agent 注入指令。
4 种队列策略¶
当多个消息同时到达时,resolveActiveRunQueueAction 决定如何影响当前状态:
| 策略 | 对状态的影响 |
|---|---|
| interrupt | 丢弃当前 run 状态,重新开始 |
| steer | 修改当前 run 状态(注入新指令) |
| followup | 保持当前状态,完成后追加新 run |
| collect | 合并多条消息为一个输入,延迟处理 |
三、状态持久化¶
与 Claude Code(进程内 Map,进程退出即丢失)不同,OpenClaw 的 Sub-agent 状态持久化到磁盘:
| 持久化内容 | 格式 | 原因 |
|---|---|---|
| Sub-agent 注册表 | 进程内 Map + 磁盘 | Gateway 可能重启 |
| 对话 transcript | JSONL | 多 Gateway 实例可能共享 workspace |
| SessionEntry 元数据 | JSON | 恢复树形关系和角色信息 |
关键文件索引¶
| 文件 | 职责 |
|---|---|
src/agents/subagent-registry.ts |
Sub-agent 注册表 |
src/agents/subagent-control.ts |
steer / kill 控制 |
src/sessions/session-key-utils.ts |
Session key 解析 |
src/config/sessions/types.ts |
SessionEntry 类型 |