欢迎光临
我们一直在努力

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

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)
    未经允许不得转载:171主机测评 » OpenClaw Context Compaction 避坑实战:你的 Agent 为什么突然「失忆」
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址