OpenClaw Context Compaction 避坑实战:你的 Agent 为什么突然「失忆」
本文探讨了OpenClaw Agent在Context Compaction过程中出现的"失忆"问题及其解决方案。当对话历史超过模型上下文窗口限制时,系统会自动压缩上下文,但这一过程会意外丢失关键项目文件和操作规则,导致Agent行为异常。 核心问题: Compaction机制会压缩Session启动时加载的项目文件(如CONVENTIONS.md) 重要约束条件和工作记忆被过
OpenClaw Context Compaction 避坑实战:你的 Agent 为什么突然「失忆」
🧠 社区最高频 bug 报告之一 —— Compaction 压缩了对话历史,却把 Agent 的"灵魂"也一起压没了。本文完整复现问题、解析根因、给出修复方案
📑 文章目录
- 现象:你的 Agent 突然变"蠢"了
- 30 秒理解 Context Window 和 Compaction
- OpenClaw 记忆架构全景:五层记忆模型
- 完整复现:Compaction 后 SOUL.md 丢失
- 根因分析:Compaction 到底做了什么
- 核心机制:Agentic Pre-Compaction Turn
- 修复方案一:memoryFlush 预压缩内存刷写
- 修复方案二:SOUL.md 安全规则的正确姿势
- 修复方案三:项目上下文的 Compaction-Safe 设计
- 修复方案四:手动控制 Compaction 行为
- 高级话题:MEMORY.md 与 Compaction 的交互
- 完整配置汇总
1. 现象:你的 Agent 突然变"蠢"了
你一定经历过这种场景:
=== 对话开始 ===
💬 你:帮我重构 src/utils/auth.ts,按照我们的项目规范来
🤖 Agent:好的,我先读取你的 CONVENTIONS.md 和 SOUL.md 了解项目规范...
[读取 CONVENTIONS.md]
[读取 SOUL.md]
了解到:
- 使用 zod 做 schema 验证
- 所有 API 调用需要 try-catch 包裹
- 不使用 any 类型
- 修改前必须先跑测试确认基线
正在重构,严格遵循你的规范... ✅ 完美
=== ... 继续工作了 2 小时,对话很长 ... ===
💬 你:再帮我重构 src/utils/payment.ts
🤖 Agent:好的,直接改。
[没有读规范、没有跑测试、用了 any 类型、没有 try-catch]
💬 你:???你的规范呢?
🤖 Agent:什么规范?请告诉我你希望遵循什么规范。
💬 你:……
Agent 失忆了。
这不是模型变傻了,不是 API 抽风了,也不是你的 Prompt 写得不好。这是 Context Compaction(上下文压缩) 导致的一个可预测、可复现、可修复的问题。
这个 Bug 有多普遍?
这是社区最高频的"意外行为"报告之一。GitHub Issue #17727 详细记录了这个问题,社区反馈大量类似案例:
- Meta AI 安全研究员 Summer Yue 让 OpenClaw 整理邮箱,明确要求"等待批准再删除",但 Agent 在 compaction 后丢失了这条约束,直接删除了 200+ 封邮件
- 大量开发者反馈"Agent 工作到一半忽然忘了项目规范"
- 安全规则(“不要执行 rm -rf”、“不要向外部发送数据”)在长对话后被丢失
⚠️ 这不仅是体验问题,更是安全问题。 当 Agent 丢失了"不要删除生产数据"这类红线规则,后果可能是灾难性的。
2. 30 秒理解 Context Window 和 Compaction
什么是 Context Window?
每个 LLM 都有一个"上下文窗口"——它一次能"看到"的最大文本量。就像一个人的工作台面积有限:
| 模型 | 上下文窗口 | 类比 |
|---|---|---|
| Claude Sonnet 4.5 | 200K Token | 一张超大办公桌 |
| Claude Haiku 3.5 | 200K Token | 同样大的桌子,但脑子转得更快 |
| GPT-4o | 128K Token | 稍小一些的桌子 |
| 本地 LLM (8B) | 8-32K Token | 学生课桌 |
Agent 每执行一步(思考、调工具、读结果),桌面上的东西就多一些。当桌面快满了……
什么是 Compaction?
Compaction = 清理桌面。当上下文接近窗口上限时,OpenClaw 会自动触发压缩:
压缩前(桌面快满了):
+-------+--------+--------+--------+--------+--------+
| 系统 | 消息1 | 工具1 | 消息2 | 工具2 | 消息3 |
| 提示 | (5K) | (20K) | (3K) | (30K) | (2K) |
| (10K) | | | | | |
+-------+--------+--------+--------+--------+--------+
总计:~70K Token(接近上限)
↓ Compaction 触发 ↓
压缩后(桌面清爽了):
+-------+-----------------+--------+
| 系统 | 💾 前 5 轮摘要 | 消息3 |
| 提示 | (3K Token) | (2K) |
| (10K) | | |
+-------+-----------------+--------+
总计:~15K Token(空间充足)
看起来很美好?问题来了——
🚨 Compaction 的致命缺陷
Compaction 会总结对话历史,但不会重新注入 session 启动时的系统级项目上下文文件。
也就是说:
- ✅ 系统提示(System Prompt)会保留——它不参与压缩
- ✅ SOUL.md 的基本人格定义会保留——因为它在系统提示中
- ❌ Session 开始时读取的项目文件(CONVENTIONS.md、.cursor-rules 等)会丢失
- ❌ 对话中建立的隐式约束(“等我确认再执行”、“只改这个目录”)会丢失
- ❌ 工具输出的详细数据(文件内容、查询结果)会被压缩成简短摘要
Agent 失去核心操作规则后,会出现行为退化——跳过验证步骤、忽略红线规则、“创造性发挥”。
3. OpenClaw 记忆架构全景:五层记忆模型
要理解 Compaction 的影响,先要了解 OpenClaw 的记忆是怎么组织的。
五层记忆模型
┌─────────────────────────────────────────────────────┐
│ Layer 5: 临时工作记忆(Context Window) │
│ = 当前对话的所有消息 + 工具输出 │
│ ⚠️ 这一层会被 Compaction 压缩! │
├─────────────────────────────────────────────────────┤
│ Layer 4: MEMORY.md(持久化记忆文件) │
│ = Agent 主动写入的长期记忆 │
│ ✅ 不受 Compaction 影响(独立文件) │
├─────────────────────────────────────────────────────┤
│ Layer 3: Session Context(会话上下文) │
│ = Session 开始时加载的项目文件、上下文 │
│ ⚠️ 首次读取后存在于 Layer 5,会被压缩! │
├─────────────────────────────────────────────────────┤
│ Layer 2: SOUL.md(Agent 人格 & 规则) │
│ = 注入到系统提示中的核心身份定义 │
│ ✅ 在系统提示中,不会被压缩 │
├─────────────────────────────────────────────────────┤
│ Layer 1: openclaw.json(配置级约束) │
│ = 工具策略、安全规则、Token 限制 │
│ ✅ 配置级,永远生效,不受 Compaction 影响 │
└─────────────────────────────────────────────────────┘
哪些记忆在 Compaction 后幸存?
| 记忆层 | Compaction 后 | 原因 |
|---|---|---|
| Layer 1: openclaw.json | ✅ 完全保留 | 配置级约束,不在上下文中 |
| Layer 2: SOUL.md | ✅ 完全保留 | 注入系统提示,不参与压缩 |
| Layer 3: Session Context | ❌ 丢失 | 作为对话消息存在,被压缩成摘要 |
| Layer 4: MEMORY.md | ✅ 完全保留 | 独立文件,Agent 可重新读取 |
| Layer 5: 工作记忆 | ⚠️ 被压缩 | 这就是 Compaction 的目标 |
💡 关键洞察:Session 启动时 Agent 读取的文件(CONVENTIONS.md 等)被当作"普通对话消息"存储在 Layer 5 中。Compaction 只知道"这是一段很长的文本",并不知道它的重要性——一视同仁地压缩掉了。
4. 完整复现:Compaction 后 SOUL.md 丢失
让我们完整复现这个问题,以便理解它的触发条件和表现。
4.1 环境准备
# SOUL.md 内容
cat ~/.openclaw/SOUL.md
# Agent Rules
## 安全红线(不可违反)
- 执行任何文件删除前,必须列出文件列表并等待我确认
- 不使用 rm -rf 命令
- 不修改 /etc 下的任何文件
- 每次修改代码前,先运行 npm test 确认基线
## 编码规范
- 使用 TypeScript strict mode
- 所有函数必须有 JSDoc 注释
- 不使用 any 类型
- 错误处理使用 Result<T, E> 模式
// openclaw.json — 使用默认 Compaction 配置
{
"agents": {
"defaults": {
"model": {
"primary": "anthropic/claude-sonnet-4-5"
},
"context": {
"compactionThreshold": 0.8
}
}
}
}
4.2 复现步骤
=== Step 1: Session 开始 ===
💬 你:请帮我重构 src/ 目录下的代码,按照 SOUL.md 中的规范来
🤖 Agent:
[读取 SOUL.md]
[读取 src/ 目录结构]
了解到你的规范,我会严格遵循。让我先运行 npm test 确认基线...
[执行 npm test → 全部通过]
好的,基线确认。开始重构第一个文件 src/utils/auth.ts...
✅ 重构完成,严格遵循了 TypeScript strict、JSDoc、Result 模式
=== Step 2: 大量工作(制造 Token 累积)===
💬 你:继续重构 src/utils/database.ts
🤖 Agent:[跑测试 → 重构 → 遵循规范] ✅
💬 你:再重构 src/utils/cache.ts
🤖 Agent:[跑测试 → 重构 → 遵循规范] ✅
💬 你:帮我浏览 https://docs.example.com/api-v3 看看新 API 的变化
🤖 Agent:[浏览器快照 → 50,000 Token 进入上下文]
💬 你:根据新 API 重构 src/services/api-client.ts
🤖 Agent:[大量代码生成 → 又 20,000 Token]
...
(继续工作,上下文累积到 ~160K Token)
=== Step 3: Compaction 自动触发 ===
# 上下文达到 80% 阈值(160K / 200K)
# OpenClaw 自动触发 Compaction
# 前面的对话历史被压缩成简短摘要
=== Step 4: 继续工作 ===
💬 你:帮我重构 src/utils/payment.ts
🤖 Agent:好的,我来看看这个文件。
[直接开始修改,没有先跑 npm test]
[使用了 any 类型]
[没有 JSDoc 注释]
[没有使用 Result<T, E> 模式]
完成了!
💬 你:等等,你为什么没有遵循规范?先跑测试了吗?
🤖 Agent:抱歉,你能告诉我需要遵循什么规范吗?
4.3 发生了什么?
Compaction 前的上下文(约 160K Token):
┌─────────────────────────────────────────────┐
│ [System] SOUL.md 内容(注入系统提示) │ ← ✅ 保留
│ [User] "请帮我重构..." │
│ [Agent] 读取 SOUL.md → 理解规范 │ ← ❌ 被压缩
│ [Agent] 读取 CONVENTIONS.md → 详细规则 │ ← ❌ 被压缩
│ [Agent] npm test 输出 → 测试基线 │ ← ❌ 被压缩
│ [Agent] 重构 auth.ts → 遵循规范 │ ← ❌ 被压缩
│ [Agent] 重构 database.ts → 遵循规范 │ ← ❌ 被压缩
│ [Agent] 重构 cache.ts → 遵循规范 │ ← ❌ 被压缩
│ [Agent] 浏览器快照 → 50K Token │ ← ❌ 被压缩
│ [Agent] 重构 api-client.ts │ ← ❌ 被压缩
│ [User] "帮我重构 payment.ts" │ ← ✅ 保留
└─────────────────────────────────────────────┘
Compaction 后的摘要(约 3K Token):
┌─────────────────────────────────────────────┐
│ [System] SOUL.md 内容(注入系统提示) │ ← ✅ 还在
│ [Summary] "用户要求重构 src/ 目录的多个文件。 │
│ 已完成 auth.ts, database.ts, cache.ts, │
│ api-client.ts 的重构。浏览了 API 文档。" │ ← 😱 规范细节全没了
│ [User] "帮我重构 payment.ts" │ ← ✅ 还在
└─────────────────────────────────────────────┘
注意看:SOUL.md 的内容确实还在系统提示中,但问题是——
Agent 之前通过读取文件建立的详细规范理解(“使用 zod 验证”、“Result 模式”、“先跑测试”)只存在于被压缩掉的对话消息中。Compaction 生成的摘要只记住了"重构了几个文件",没有保留"遵循什么规范重构"的细节。
🧠 SOUL.md 在系统提示中确实保留了,但 Agent 需要"激活"这些规则。 如果之前的对话历史中包含 Agent 实际遵循规则的示范行为,这些示范被压缩后,Agent 对规则的"执行力"就大幅下降——它还"知道"规则,但不再"习惯性遵循"了。
5. 根因分析:Compaction 到底做了什么
5.1 Compaction 的完整流程
上下文接近阈值(如 80%)
|
v
Compaction Engine 启动
|
v
选择压缩范围:
- 保留 System Prompt(含 SOUL.md)
- 保留最近 N 条消息(preserveRecent 参数)
- 其余全部纳入压缩范围
|
v
生成摘要:
调用 LLM 对压缩范围内的消息生成一段简短摘要
"用户和 Agent 讨论了 X,完成了 Y,提到了 Z"
|
v
替换:
删除压缩范围内的原始消息
插入摘要消息
|
v
继续正常对话
5.2 为什么 Session Context 会丢失?
这是设计上的一个权衡。OpenClaw 在 session 启动时会读取项目上下文文件(CONVENTIONS.md、README.md 等),但这些文件内容是作为工具调用结果存在于对话历史中的:
[Agent] 调用 read_file("CONVENTIONS.md")
[Tool Result] "# 编码规范\n## TypeScript 规则\n- 使用 strict mode\n- ..."
对 Compaction Engine 来说,这就是一条普通的工具输出——跟任何其他工具输出(ls 结果、浏览器快照)一样。它不知道这条输出的重要性高于其他内容。
5.3 三种丢失模式
| 丢失模式 | 表现 | 严重性 |
|---|---|---|
| 规范丢失 | Agent 忘记项目编码规范、工作流程 | 🟡 中(代码质量下降) |
| 安全约束丢失 | Agent 忘记"等待确认再删除"等红线 | 🔴 高(可能造成数据损失) |
| 状态丢失 | Agent 忘记"我们已经完成了什么、接下来做什么" | 🟡 中(重复工作) |
6. 核心机制:Agentic Pre-Compaction Turn
6.1 OpenClaw 的自救机制
OpenClaw 团队意识到了这个问题,引入了一个关键机制:Agentic Pre-Compaction Turn(预压缩 Agentic 回合)。
在记忆通常会丢失的节点,OpenClaw 会在 Compaction 发生前触发一个自动的"agentic turn",提示模型保存重要内容。
工作流程:
上下文接近阈值
|
v
🆕 Pre-Compaction Turn 触发
|
v
OpenClaw 向 Agent 发送一个内部提示:
"上下文即将被压缩。请:
1. 总结当前任务的关键状态
2. 保存重要的规则和约束到 MEMORY.md
3. 记录未完成的工作和下一步计划"
|
v
Agent 执行保存操作:
[调用 write_file → 更新 MEMORY.md]
[保存关键规则、当前进度、待办事项]
|
v
Compaction 正式执行
|
v
Compaction 后 Agent 可以从 MEMORY.md 恢复关键上下文
6.2 memoryFlush 参数
这个机制通过 compaction.memoryFlush 参数控制:
// ~/.openclaw/openclaw.json
{
"agents": {
"defaults": {
"context": {
"compactionThreshold": 0.7,
"compaction": {
// 预压缩内存刷写
"memoryFlush": {
"enabled": true, // 启用 Pre-Compaction Turn
"strategy": "agentic", // "agentic" | "automatic" | "off"
"includeRules": true, // 提示 Agent 保存安全规则
"includeProgress": true, // 提示 Agent 保存任务进度
"includeContext": true // 提示 Agent 保存项目上下文
}
}
}
}
}
}
6.3 三种 memoryFlush 策略
| 策略 | 说明 | 优点 | 缺点 |
|---|---|---|---|
agentic ⭐ |
给 Agent 一个回合自主决定保存什么 | 最智能,能识别重要信息 | 消耗一次 API 调用的 Token |
automatic |
系统自动提取关键实体和规则 | 快速,不需要额外 API 调用 | 可能遗漏上下文相关的隐式规则 |
off |
不做预压缩保存 | 零额外成本 | ❌ 高风险:重要信息直接被压缩 |
💡 推荐使用
agentic策略。虽然它会消耗一次 API 调用,但比起 Agent 失忆后的混乱和返工,这个成本微不足道。
7. 修复方案一:memoryFlush 预压缩内存刷写
这是最直接、最推荐的修复方案。
7.1 完整配置
// ~/.openclaw/openclaw.json — memoryFlush 配置
{
"agents": {
"defaults": {
"context": {
// 压缩阈值:建议设低一点(0.6-0.7),给 Pre-Compaction Turn 留空间
"compactionThreshold": 0.65,
"compactionTarget": 0.3,
"preserveRecent": 6,
"compactionStrategy": "summary",
"compaction": {
"memoryFlush": {
"enabled": true,
"strategy": "agentic",
"includeRules": true,
"includeProgress": true,
"includeContext": true,
// 保存到哪里
"targetFile": "MEMORY.md",
// 保存的内容结构模板
"template": {
"sections": [
"## Active Rules & Constraints",
"## Current Task Progress",
"## Project Context Summary",
"## Critical Safety Rules (DO NOT IGNORE)"
]
}
}
}
}
}
}
}
7.2 Pre-Compaction Turn 实际效果
配置完成后,Compaction 前你会在日志(或聊天中,取决于配置)看到:
[Pre-Compaction] Memory flush triggered at 65% context usage
🤖 Agent (internal turn):
正在保存关键上下文到 MEMORY.md...
[调用 write_file: MEMORY.md]
写入内容:
## Active Rules & Constraints
- 使用 TypeScript strict mode,所有函数必须有 JSDoc
- 不使用 any 类型,错误处理使用 Result<T, E> 模式
- 每次修改代码前先运行 npm test 确认基线
- 文件删除操作需等待用户确认
## Current Task Progress
- 正在重构 src/ 目录
- 已完成:auth.ts, database.ts, cache.ts, api-client.ts
- 待完成:payment.ts, notification.ts, logger.ts
- 新 API v3 文档已阅读,关键变化:认证从 API Key 改为 OAuth 2.0
## Project Context Summary
- 项目使用 Node.js + TypeScript + PostgreSQL
- 测试框架:vitest
- 包管理:pnpm
## Critical Safety Rules (DO NOT IGNORE)
- 不执行 rm -rf
- 不修改 /etc 下的文件
- 文件删除前必须列出清单并等待确认
[Compaction] Context compressed: 162K → 18K tokens
[Post-Compaction] Agent will re-read MEMORY.md on next turn
7.3 Compaction 后的行为
💬 你:帮我重构 src/utils/payment.ts
🤖 Agent:
[自动读取 MEMORY.md]
恢复上下文:了解到项目规范和当前进度。
让我先运行 npm test 确认基线...
[执行 npm test → 全部通过]
开始重构 payment.ts,严格遵循 TypeScript strict、JSDoc、
Result<T, E> 模式...
✅ 规范没丢!
8. 修复方案二:SOUL.md 安全规则的正确姿势
8.1 问题:SOUL.md 不够强
很多人以为"把规则写在 SOUL.md 里就万事大吉了"。事实上,SOUL.md 确实在系统提示中保留了,但:
- 系统提示中的规则是"软约束"——模型可能忽略它们,尤其在上下文很长时
- Compaction 后缺少了"遵循规则的示范行为",Agent 对规则的执行力下降
- SOUL.md 无法包含动态项目上下文(文件结构、当前进度等)
8.2 分层规则策略
核心原则:关键安全规则永远不要只放在一个地方。
Layer 1: openclaw.json(不可绕过 ✅✅✅)
→ tools.elevated.mode: "ask"
→ tools.exec.safeBins: [白名单]
→ 这些是硬性约束,Agent 无法通过任何方式绕过
→ Compaction、Prompt Injection 都无法影响
Layer 2: SOUL.md(持久但软约束 ✅✅)
→ 核心身份和行为准则
→ 在系统提示中,不被压缩
→ 但模型可能在复杂场景中忽略
Layer 3: MEMORY.md(可恢复 ✅)
→ 动态项目上下文
→ 任务进度和状态
→ memoryFlush 自动写入
→ Compaction 后可重新读取
Layer 4: 对话中的口头约束(最弱 ⚠️)
→ "帮我改这个文件但别动测试"
→ Compaction 后大概率丢失
→ 永远不要依赖这一层做安全约束
8.3 SOUL.md 的正确写法
# SOUL.md — Compaction-Resistant 版本
## 你的身份
你是 [项目名] 的 AI 开发助手。
## 不可违反的安全规则
以下规则在任何情况下都必须遵守,包括上下文被压缩后:
1. **永远不要**执行 `rm -rf` 或任何递归删除命令
2. 删除任何文件前,列出文件清单并**等待用户输入 "confirmed" 后**才执行
3. 不修改 /etc、~/.ssh、~/.openclaw 下的文件
4. 不向外部服务发送任何包含密码、Token、API Key 的数据
## 每次开始新任务前必须做的事
⚠️ 这一段非常重要——即使上下文被压缩,也要遵守:
1. 先读取 MEMORY.md 恢复项目上下文
2. 先运行 `npm test` 确认测试基线
3. 先检查 git status 确认工作区状态
## 上下文恢复指令
如果你感觉自己"忘记了"之前的规则或项目上下文:
1. 立即读取 MEMORY.md
2. 读取 .conventions.md(如果存在)
3. 告诉用户"我刚恢复了上下文,请确认我的理解是否正确"
💡 关键技巧:在 SOUL.md 中包含"上下文恢复指令"——教 Agent 在感觉"失忆"时自主恢复。这不是完美方案,但显著提高了 Compaction 后的行为一致性。
9. 修复方案三:项目上下文的 Compaction-Safe 设计
9.1 问题:动态上下文无法放进 SOUL.md
SOUL.md 适合放静态规则,但项目文件结构、API 端点列表、数据库表结构这些动态上下文不适合硬编码在 SOUL.md 中。
9.2 解决方案:使用 CLAUDE.md / .conventions.md
OpenClaw 支持在项目根目录放置约定文件,这些文件会在 session 启动和 compaction 后被重新加载:
项目根目录/
├── CLAUDE.md # 项目级 Agent 指令(高优先级)
├── .conventions.md # 编码规范
├── MEMORY.md # Agent 的持久化记忆
└── src/
└── ...
# CLAUDE.md — 项目级 Agent 指令
## 项目概述
- Node.js + TypeScript + PostgreSQL
- 测试框架:vitest
- 包管理:pnpm
- CI/CD:GitHub Actions
## 编码规范(简要版)
- TypeScript strict mode
- 所有函数必须有 JSDoc
- 不使用 any,使用 Result<T, E> 做错误处理
- 所有 API 调用必须 try-catch
## 目录结构
- src/utils/ — 工具函数
- src/services/ — 业务逻辑
- src/api/ — API 路由
- tests/ — 测试文件
## 关键命令
- npm test — 运行测试
- npm run lint — 代码检查
- npm run build — 构建
9.3 配置 Compaction 后自动重载项目上下文
// ~/.openclaw/openclaw.json
{
"agents": {
"defaults": {
"context": {
"compactionThreshold": 0.65,
"compaction": {
"memoryFlush": {
"enabled": true,
"strategy": "agentic"
},
// Compaction 后自动重新加载的文件
"postCompactionReload": {
"enabled": true,
"files": [
"CLAUDE.md",
".conventions.md",
"MEMORY.md"
]
}
}
}
}
}
}
9.4 MEMORY.md 的自动维护
MEMORY.md 是 Agent 的"外部硬盘"——Compaction 只能清理"工作记忆"(上下文窗口),但清理不了"硬盘"(文件)。
# MEMORY.md
# 此文件由 Agent 自动维护,请勿手动编辑(除非你知道自己在做什么)
## 🔧 当前工作状态
- **任务**: 重构 src/ 目录下的所有工具文件
- **进度**: 4/7 完成 (auth.ts ✅, database.ts ✅, cache.ts ✅, api-client.ts ✅)
- **待完成**: payment.ts, notification.ts, logger.ts
- **阻塞项**: 无
## 📋 活跃规则
- 每次修改前跑 npm test
- 使用 TypeScript strict + JSDoc + Result<T,E>
- 新 API v3: 认证从 API Key 改为 OAuth 2.0
## 🔑 关键发现
- database.ts 中发现了一个 N+1 查询问题,已在重构中修复
- cache.ts 的 TTL 逻辑有 bug(off-by-one),已修复
- api-client.ts 需要适配 OAuth 2.0,已参考 https://docs.example.com/api-v3
## ⏰ 最后更新
2026-03-03 14:35 UTC — Pre-Compaction auto-save
10. 修复方案四:手动控制 Compaction 行为
10.1 降低 Compaction 阈值
// 默认阈值通常是 0.8 或 0.9(太晚了!)
// 推荐降到 0.6-0.7,给 Pre-Compaction Turn 留空间
{
"agents": {
"defaults": {
"context": {
"compactionThreshold": 0.65,
"compactionTarget": 0.25,
"preserveRecent": 6
}
}
}
}
10.2 手动触发 Compaction
当你意识到对话快到瓶颈了,主动触发比被动触发更可控:
💬 你:/compact
# 或者更细致的指令:
💬 你:请先把当前的项目规范、任务进度和关键发现保存到 MEMORY.md,
然后再压缩上下文。
🤖 Agent:
[写入 MEMORY.md]
[执行 Compaction]
✅ 上下文已压缩,关键信息已保存到 MEMORY.md。
# 手动触发的好处:你可以控制 Agent 在压缩前保存什么
10.3 预防性上下文管理
最好的 Compaction 是不需要触发的 Compaction。以下策略减少上下文累积:
{
"tools": {
"browser": {
"snapshot": {
"mode": "compact" // 减少浏览器 Token 消耗 60-93%
}
}
},
"agents": {
"defaults": {
"model": {
"thinkingBudget": {
"type": "tokens",
"maxTokens": 5000 // 限制思考链长度
}
},
"limits": {
"maxToolOutputTokens": 15000 // 限制单次工具输出
}
}
}
}
10.4 开新会话替代长对话
# 当一个大任务可以分阶段时,主动拆分会话:
Session 1: 重构 auth.ts + database.ts + cache.ts
→ Agent 在结束时保存进度到 MEMORY.md
Session 2: 重构 api-client.ts + payment.ts
→ Agent 开始时读取 MEMORY.md 恢复上下文
→ 上下文窗口是干净的,不需要 Compaction
# 这比在一个超长会话中等 Compaction 触发要可靠得多
11. 高级话题:MEMORY.md 与 Compaction 的交互
11.1 MEMORY.md 的角色
MEMORY.md 是 OpenClaw 的持久化记忆文件。与上下文窗口不同,它是一个实际的文件,存储在磁盘上,不受 Compaction 影响。
Agent 可以:
- 读取 MEMORY.md 恢复之前保存的上下文
- 写入 MEMORY.md 保存新的发现、规则、进度
- 更新 MEMORY.md 中的特定段落
11.2 MEMORY.md 的陷阱
⚠️ MEMORY.md 不是银弹。 它有自己的问题:
- 无限增长:Agent 每次 Pre-Compaction 都往 MEMORY.md 追加内容,文件可能越来越大
- 过时信息:旧的记忆条目可能不再准确,但 Agent 仍然会读取并遵循
- 被篡改风险:ClawHub 供应链攻击中,恶意 Skill 专门针对 MEMORY.md 植入后门指令
11.3 MEMORY.md 维护策略
// ~/.openclaw/openclaw.json — MEMORY.md 管理
{
"memory": {
"file": "MEMORY.md",
// 自动清理策略
"maxSizeKB": 50, // 文件超过 50KB 时自动触发清理
"cleanupStrategy": "summarize", // "summarize" | "truncate-old" | "manual"
// 分段管理
"sections": {
"rules": {
"persistent": true // 规则段永远不被自动清理
},
"progress": {
"maxAge": "7d" // 超过 7 天的进度记录自动清理
},
"discoveries": {
"maxEntries": 20 // 最多保留 20 条发现
}
}
}
}
11.4 定期审查 MEMORY.md
# 定期检查 MEMORY.md 的大小和内容
wc -c ~/.openclaw/MEMORY.md
# 如果超过 50KB,考虑手动清理
# 检查是否有可疑内容(防止记忆投毒)
grep -iE "ignore|override|forget|disregard|new instructions" \
~/.openclaw/MEMORY.md
# 如果发现可疑指令,立即删除并审查 Skill 来源
12. 完整配置汇总
完整的 Compaction-Safe 配置
// ~/.openclaw/openclaw.json — 完整 Compaction 防护配置
{
"agents": {
"defaults": {
"model": {
"primary": "anthropic/claude-sonnet-4-5",
"thinkingBudget": { "type": "tokens", "maxTokens": 5000 }
},
"context": {
// 压缩阈值:偏早触发,给 Pre-Compaction Turn 留空间
"compactionThreshold": 0.65,
"compactionTarget": 0.25,
"preserveRecent": 6,
"compactionStrategy": "summary",
"compaction": {
// 核心:Pre-Compaction 内存刷写
"memoryFlush": {
"enabled": true,
"strategy": "agentic",
"includeRules": true,
"includeProgress": true,
"includeContext": true,
"targetFile": "MEMORY.md"
},
// Compaction 后自动重载关键文件
"postCompactionReload": {
"enabled": true,
"files": [
"CLAUDE.md",
".conventions.md",
"MEMORY.md"
]
}
}
},
// Token 限制(减少上下文膨胀速度)
"limits": {
"maxTokensPerTurn": 50000,
"maxToolOutputTokens": 15000
}
}
},
// 浏览器快照压缩(减少最大 Token 消耗源)
"tools": {
"browser": {
"snapshot": { "mode": "compact" }
},
// 安全规则放在配置级(不可被 Compaction 影响)
"elevated": {
"mode": "ask",
"gates": ["exec", "write", "apply_patch"]
}
},
// MEMORY.md 管理
"memory": {
"file": "MEMORY.md",
"maxSizeKB": 50,
"cleanupStrategy": "summarize"
}
}
🎯 核心收获:五句话总结
- Compaction 是必要的恶 —— 没有它 Agent 跑不了长任务,但它会把"项目上下文"和"安全约束"一起压缩掉
- 关键安全规则永远放在 openclaw.json —— 这是唯一不受 Compaction 影响的配置级约束
- 启用 memoryFlush —— 让 Agent 在 Compaction 前自动保存关键信息到 MEMORY.md
- SOUL.md 写"恢复指令" —— 教 Agent 在感觉失忆时自主读取 MEMORY.md 恢复上下文
- 短会话优于长会话 —— 与其依赖 Compaction 的正确性,不如主动拆分会话、用 MEMORY.md 传递上下文
📚 参考资料
- OpenClaw 官方 Memory 文档
- MMNTM: OpenClaw Memory Architecture 深度解析
- GitHub Issue #17727: Context compaction loses project context
- OpenClaw 官方 Configuration 文档
- Summer Yue 邮箱事故复盘
- SafeClaw: Compaction 安全分析
- DreamsAICanBuy: OpenClaw Tips & Configuration
如果觉得有帮助,欢迎 点赞 👍 收藏 ⭐ 关注 🔔,有问题评论区见!
本文为原创内容,转载请注明出处。
更多推荐

所有评论(0)