OpenClaw Context Compaction 避坑实战:你的 Agent 为什么突然「失忆」

🧠 社区最高频 bug 报告之一 —— Compaction 压缩了对话历史,却把 Agent 的"灵魂"也一起压没了。本文完整复现问题、解析根因、给出修复方案


📑 文章目录

  1. 现象:你的 Agent 突然变"蠢"了
  2. 30 秒理解 Context Window 和 Compaction
  3. OpenClaw 记忆架构全景:五层记忆模型
  4. 完整复现:Compaction 后 SOUL.md 丢失
  5. 根因分析:Compaction 到底做了什么
  6. 核心机制:Agentic Pre-Compaction Turn
  7. 修复方案一:memoryFlush 预压缩内存刷写
  8. 修复方案二:SOUL.md 安全规则的正确姿势
  9. 修复方案三:项目上下文的 Compaction-Safe 设计
  10. 修复方案四:手动控制 Compaction 行为
  11. 高级话题:MEMORY.md 与 Compaction 的交互
  12. 完整配置汇总

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 不是银弹。 它有自己的问题:

  1. 无限增长:Agent 每次 Pre-Compaction 都往 MEMORY.md 追加内容,文件可能越来越大
  2. 过时信息:旧的记忆条目可能不再准确,但 Agent 仍然会读取并遵循
  3. 被篡改风险: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"
  }
}

🎯 核心收获:五句话总结

  1. Compaction 是必要的恶 —— 没有它 Agent 跑不了长任务,但它会把"项目上下文"和"安全约束"一起压缩掉
  2. 关键安全规则永远放在 openclaw.json —— 这是唯一不受 Compaction 影响的配置级约束
  3. 启用 memoryFlush —— 让 Agent 在 Compaction 前自动保存关键信息到 MEMORY.md
  4. SOUL.md 写"恢复指令" —— 教 Agent 在感觉失忆时自主读取 MEMORY.md 恢复上下文
  5. 短会话优于长会话 —— 与其依赖 Compaction 的正确性,不如主动拆分会话、用 MEMORY.md 传递上下文

📚 参考资料

如果觉得有帮助,欢迎 点赞 👍 收藏 ⭐ 关注 🔔,有问题评论区见!


本文为原创内容,转载请注明出处。

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐