3.1 Context Management¶
本节摘要
从State Management角度看,OpenClaw Context Management的核心特点是:每次 run 从磁盘恢复状态(而非驻留内存)。这决定了它需要显式的 sanitizeSessionHistory、压缩前 Memory Flush 防丢信息、压缩后补注入关键约束。本节按「组成 → 恢复 → 丢弃 → 恢复关键信息」展开。
一、Context 由什么组成¶
每次 API 调用时,LLM 收到的Context 由以下部分构成:
| 组成部分 | 变化频率 | 来源 |
|---|---|---|
| System Prompt | 会话级 | buildEmbeddedSystemPrompt:身份(SOUL.md) + Skills XML + Bootstrap 文件(AGENTS/TOOLS.md 等) + 环境 |
| 对话历史 | 每 turn 增长 | JSONL transcript 文件,每次 run 从磁盘加载 |
| 工具定义 | 会话级 | createOpenClawCodingTools 多源合并(详见 3.3 Tool Management) |
Bootstrap 引导文件¶
System prompt 中注入的引导文件,构成 Agent 的运行时知识库:
| 文件 | 内容 | 特殊性 |
|---|---|---|
AGENTS.md |
行为规则、Red Lines 约束 | 压缩后重注入 |
SOUL.md |
Agent 人格定义 | |
MEMORY.md |
长期 Memory | |
TOOLS.md |
工具使用指南 | |
IDENTITY.md / USER.md |
身份标识 / 用户偏好 |
二、每次 run 怎么恢复状态¶
与 Claude Code(对话历史驻内存)不同,OpenClaw 的每次 run 都从磁盘恢复——消息可能来自不同渠道(Slack/Discord/Web),间隔可能很长。
恢复流程(attempt.ts):
SessionManager.open → 从 JSONL 加载 transcript
→ sanitizeSessionHistory // 校验、修复损坏的消息
→ limitHistoryTurns // 按配置截断旧轮次
→ 组装工具 + 构建 system prompt
→ API 调用
sanitizeSessionHistory 是 Claude Code 不需要的——因为 Claude Code 的对话历史始终驻留内存,不存在反序列化损坏的问题。OpenClaw 从磁盘恢复,必须处理格式错误、不完整消息等异常。
运行时介入:Steer¶
在 Agent 执行过程中,用户可以通过 activeSession.steer(text) 向正在 streaming 的响应中注入新指令——这直接修改了 Agent 的当前状态。
三、怎么丢弃:可插拔压缩 + 安全网¶
当Context 接近窗口上限时,OpenClaw 通过五步流程丢弃旧状态。核心原则:先保存再丢弃,丢弃后补关键信息。
| 步骤 | 做了什么 | 丢弃/保护了什么 |
|---|---|---|
| S1: Memory Flush | 压缩前将重要信息写入磁盘 | ⬆️ 保护:未持久化的 Memory��盘防丢 |
| S2: CompactionProvider | 可插拔的摘要生成(默认 LLM 摘要) | ⬇️ 丢弃:旧消息被摘要替代 |
| S3: Transcript 替换 | 用摘要替换 JSONL 中的旧消息 | ⬇️ 丢弃:磁盘上的旧 transcript |
| S4: 补注入 | 从 AGENTS.md 重注入 Session Startup + Red Lines | ⬆️ 恢复:关键行为约束 |
| S5: 检查点 | 保存压缩前状态,支持 list / restore | ⬆️ 保护:可回滚到压缩前 |
触发条件(三选一):Context 接近窗口上限 / 模型返回 overflow error / 用户手动 /compact。
与 Claude Code 的关键差异¶
| 维度 | Claude Code | OpenClaw |
|---|---|---|
| 压缩前保护 | 无 | Memory Flush(先保存再丢弃) |
| 压缩后恢复 | 文件 50K + Skill 25K + CLAUDE.md | AGENTS.md 的 Session Startup + Red Lines |
| 回滚能力 | 无 | 检查点 list / restore |
| 可插拔 | 固定 6 层实现 | CompactionProvider 接口,策略可替换 |
四、丢弃后怎么恢复关键信息¶
压缩后通过 readPostCompactionContext 重新注入 AGENTS.md 中的两个关键段落:
| 段落 | 内容 | 为什么必须恢复 |
|---|---|---|
| Session Startup | 每次压缩后必须重新告知的初始化指令 | 确保 Agent 行为正确 |
| Red Lines | 绝对不可违反的安全约束 | 确保 Agent 不越界 |
此外,压缩完成后通过 sessions.compact RPC 同步 Gateway 侧的 compactionCount 和 totalTokens 元数据。
五、5 层嵌套重试¶
OpenClaw 的 Agent 运行时有 5 层嵌套重试,每层负责不同粒度的状态恢复:
| 层级 | 文件 | 状态恢复能力 |
|---|---|---|
| L1 入口 | get-reply-run.ts |
队列策略(interrupt/steer/followup/collect) |
| L2 回复管理 | agent-runner.ts |
触发压缩 |
| L3 模型回退 | agent-runner-execution.ts |
主模型不可用时切换 fallback 模型 |
| L4 循环重试 | run.ts |
Compaction 重试 + Planning-only 重试 |
| L5 原子执行 | attempt.ts |
单次 LLM 调用的完整状态组装 |
关键文件索引¶
| 文件 | 职责 |
|---|---|
src/agents/system-prompt.ts |
System prompt 构建 |
src/agents/workspace.ts |
Bootstrap 引导文件加载 |
src/agents/pi-embedded-runner/attempt.ts |
L5 原子执行(状态组装入口) |
src/agents/pi-embedded-runner/run.ts |
L4 循环重试 + 压缩重试 |
src/auto-reply/agent-runner.ts |
L2 压缩触发 |