---
title: 养龙虾5天血泪史：我的AI Agent为什么总失忆？OpenClaw 记忆调试全记录
source:
author: shenwei
published:
created:
description:
tags: [AI, Agent, OpenClaw]
---

# 养龙虾5天血泪史：我的AI Agent为什么总失忆？OpenClaw 记忆调试全记录

![[IMG-20260402083219226.png]]
当你的AI助理像个金鱼一样只有7秒记忆，每次对话都要从头开始——这不是科幻，而是我花了5天时间解决的现实问题。从对话压缩到搜索失效，从系统臃肿到模型切换失忆，这是我用血泪换来的10条OpenClaw内存管理黄金法则。

# 5天血泪史：我的AI助理为什么总失忆？OpenClaw内存调试全记录

> 当你的AI助理像个金鱼一样只有7秒记忆，每次对话都要从头开始——这不是科幻，而是我花了5天时间解决的现实问题。

我叫比利哥，正在研究如何利用AI提高工作效率。我的OpenClaw AI助理名叫星辉，它运行在Telegram上，负责管理我的个人任务规划、日程安排、搜集资料、起草推文、文件整理。

从开始"雇佣"它，它就像我的初级员工——直到它开始频繁失忆。

不是那种微妙的遗忘。我花一个小时配置每日定时任务，切换模型后，星辉表现得像我们从未交谈过。我提到两天前的讨论决定，它一脸茫然。让它继续任务，它却从头开始。

于是我停止了我手头的其他工作，花了5天时间专门修复OpenClaw的记忆问题。以下是我发现的一切、我搞砸的一切，以及真正有效的一切。

## Day 1：长对话后的集体失忆

第一个问题描述简单，诊断痛苦。

长对话后，星辉开始丢失早期上下文。不是逐渐丢失，而是突然消失。20条消息前告诉它的事情，没了。会话开始时做的决定？从未发生。

**罪魁祸首是压缩机制。** 当对话填满Context Window时，OpenClaw会将旧消息压缩成摘要，为新消息腾出空间。摘要抓住了要点，但丢掉了细节——姓名、数字、具体决定，统统消失。

> “这是设计使然。上下文窗口是有限的。但默认行为对一切一视同仁，这意味着你精心设计的第三条消息指令，和第七条消息的闲聊得到了相同待遇。”

**我的解决方案：**
启用压缩前的内存刷新。这告诉代理在压缩器运行前将重要上下文写入磁盘。
```json
{
  "compaction": {
    "memoryFlush": {
      "enabled": true,
      "softThresholdTokens": 4000
    }
  }
}
```

当会话接近上下文限制时，OpenClaw触发一个静默回合，提醒Agent在压缩擦除前将持久事实保存到memory/YYYY-MM-DD.md。代理写入重要内容，压缩运行，即使上下文摘要丢失，重要内容仍保留在磁盘上。
不过这里要声明一下，4000这个数值要根据你使用的模型来考虑，如果你是使用Gemini/GTP-4.1/Claud等大模型通常上下文窗口可以达到32K/128K/200K tokens, 那么4000这个数值就太保守了，会导致频繁的summary, 上下文"碎片化"，reasoning质量下降。

**关键洞察：**
压缩不是敌人。压缩过程中丢失信息才是。修复方法是确保任何值得记住的内容在压缩器触及前写入文件。如果只在上下文窗口中，它是临时的。如果在磁盘上，它就能存活。

## Day 2：搜索返回垃圾结果

随着每日日志积累和MEMORY.md增长，我需要星辉开始真正找到东西。内置的内存搜索返回不相关结果或错过明显匹配。

**问题是搜索后端。** OpenClaw默认的基于SQLite的搜索使用向量嵌入（语义相似性）查找相关块。这对广泛查询有效，但在精确匹配上挣扎。我搜索特定内容，却得到关于完全不同主题的结果，只是因为使用了相似语言。

**我的解决方案：**
切换到QMD作为内存搜索后端。QMD结合了BM25（关键词匹配）、向量嵌入和重新排序器。所以当我搜索“n8n工作流执行结果”时，它找到包含这些确切词语的结果AND语义相关的结果，然后按相关性重新排序。

**关键洞察：**
纯语义搜索理论上听起来不错，但在专有名词、具体数字和确切短语上失败。混合搜索（关键词+向量+重新排序）对现实世界代理内存明显更好。如果你的代理找不到你知道在其文件中的内容，搜索后端可能是瓶颈，而不是文件本身。

## Day 3：Agent找到了但不使用

这是最令人沮丧的一天。我确认搜索是有效，可以手动查询并获得正确结果。但在实际对话中，即使相关上下文明显存在于内存中，星辉也不会检索。

**问题是检索不是自动的。** Agent必须决定搜索。如果对话没有触发正确线索，它就不会查找。

**我的解决方案：**
在启动序列中添加明确的检索指令。不是希望代理在需要时搜索，而是告诉它何时搜索：

> 开始任何任务前：
> - 搜索每日日志(memory/YYYY-MM-DD.md)获取相关上下文
> - 检查LEARNINGS.md获取此类任务的规则
> - 如果提到客户，搜索其历史记录

我还建立了检索测试。我在每日日志中植入特定标记——类似“标记：2026-02-20 — 在笔记更新后自动运行笔记同步到git”然后等待，开始新会话，测试问：“昨天的标记是什么？”如果Agent找到它，检索有效。如果没有，某些地方出错了。

**关键洞察：**
“信息存在”和“Agent使用信息”之间有区别。你需要两者。搜索基础设施处理第一部分。启动指令和检索习惯处理第二部分。分别测试两者。

## Day 4：让它对压缩安全

此时我有了内存刷新、混合搜索和检索指令。但在特定场景中我仍然丢失上下文：非常长的会话，压缩运行多次。

**问题是内存刷新每个压缩周期只触发一次。** 如果会话足够长，有两三次压缩，只有第一次得到刷新处理。之后的一切都处于风险中。

**我的解决方案：**

配置上下文修剪与压缩协同工作：

```json
{
  "contextPruning": {
    "mode": "cache-ttl",
    "ttl": "6h",
    "keepLastAssistants": 3
  }
}
```

这会在6小时后积极修剪旧上下文，同时保留最后3个Assistants响应。结合内存刷新，这意味着Agent早期将重要内容写入磁盘，旧上下文在导致溢出前被清理。

**关键洞察：**
长会话是内存系统真正接受测试的地方。短对话很少触及压缩。是2小时的深度工作会话中你会丢失上下文且无法找出原因。在负载下测试你的内存系统，而不仅仅是在快速聊天中。

## Day 5：系统提示词臃肿了28%

这是所有事情都清晰的一天。我运行了/context detail并盯着数字。

我的代理在读取我的消息前加载了20,9652个令牌的系统提示词。54个技能，其中20个我从未使用。我有两个竞争的启动序列——一个在BOOT.md中（OpenClaw甚至不识别），一个埋在AGENTS.md的200行深处。

最糟糕的是，每次切换模型，星辉忘记一切。没有交接协议。没有当前上下文的写回。直接消失。

**根本原因：**

OpenClaw在每个新会话上自动读取这些文件：AGENTS.md、SOUL.md、TOOLS.md、IDENTITY.md、HEARTBEAT.md、MEMORY.md。

其他一切——LEARNINGS.md、每日日志、文档、参考文件——代理必须自己使用工具读取它们。如果读取这些文件的指令不在自动加载的文件中（特别是AGENTS.md），代理永远不会看到它们。

我的BOOT.md有整个启动序列。但OpenClaw不自动加载BOOT.md。所以指令就坐在那里，未读，什么都不做。

**我的解决方案：**

我进行了全面审计和清理：

- 将启动序列移到AGENTS.md顶部（启动指令唯一可靠的位置）
- 删除BOOT.md（OpenClaw不识别）
- 删除BOOTSTRAP.md（一次性入职文件，已完成，每个会话浪费361个令牌）
- 通过将参考文档移到docs/文件夹，将MEMORY.md从200行精简到90行
- 移除20个未使用的营销技能，每个会话消耗3,000个令牌
- 添加写入纪律：每个任务记录其结果，每个错误变成规则
- 添加交接协议：在任何模型切换或会话结束前，代理将当前上下文写入每日日志

**结果：**

- 系统提示词：20,9652 → 9,349个令牌
- 技能：51 → 31
- 会话令牌：18,280 → 14,627
- 轻了28%。相同的代理。相同的模型。只是更少噪音。

**关键洞察：**
真正的修复不是添加更多文件。而是移除那些什么都不做的文件。系统提示词中的每个令牌都是代理在每个消息上携带的开销。未使用的技能、臃肿的内存文件、系统甚至不读取的文件——它们都在默默累积。

## 我希望在第1天就知道的10条规则

### 1. 只有这些文件自动加载：AGENTS.md、SOUL.md、TOOLS.md、IDENTITY.md、USER.md、HEARTBEAT.md、MEMORY.md

其他一切都需要AGENTS.md中的明确读取指令。如果不在启动序列中，代理不会看到它。BOOT.md在OpenClaw中不是真实存在。我用了好几周。它什么都没做。

### 2. 启动序列放在AGENTS.md顶部

不要在中间。不要在底部。最顶部。自动加载的文件被注入系统提示词，所以启动指令需要是代理处理的第一件事。

### 3. 写入纪律比读取纪律更重要

大多数人设置文件供代理读取，但从不强制执行写回。如果代理不将决定、结果和错误记录到磁盘，这些东西只存在于上下文窗口中。而上下文窗口会被压缩。写回是临时上下文变成永久记忆的方式。

### 4. 任务期间永远不要直接写入MEMORY.md

每日日志是原始且仅追加的。MEMORY.md是策划的长期记忆。如果你让代理向MEMORY.md转储任何内容，几周内它就会膨胀成200行的混乱。在定期审查期间（心跳或定时任务），通过从最近的每日日志中提炼见解来策划MEMORY.md。

### 5. LEARNINGS.md是最被低估的文件

代理犯的每个错误都应该变成一行规则。“在声称代码已推送前永远不要不检查git状态。”“不要在群聊中读取完整的MEMORY.md。”“在安排前始终确认用户的时区。”这些规则会复合。几周后，你的代理就有了从自己失败中构建的个人操作手册。

### 6. 测试检索，不仅仅是存储

存储信息和检索信息是不同的问題。我有文件被索引且可搜索但从未被访问，因为代理不知道查找它们。植入标记，跨会话测试，跨模型切换测试。如果代理找不到你昨天存储的内容，存储就不重要。

### 7. 交接协议是模型切换的修复

OpenClaw代理在切换模型时丢失所有上下文。新模型以新鲜上下文窗口开始——它只看到自动加载的文件。没有在切换前将当前状态转储到每日日志的交接协议，新模型不知道发生了什么。这是我几周来最大的痛点。

### 8. 定期运行/context detail

这个命令准确显示什么在消耗你的令牌。你忘记安装的技能，你未注意到的增长的文件，你从未使用的工具。我找到了20个未使用的技能，每个会话燃烧3,000个令牌。这是每个消息上3,000个令牌的开销，用于我从未碰过的功能。

### 9. 混合搜索击败纯语义搜索

BM25（关键词）+ 向量（含义）+ 重新排序比单独向量给出明显更好的结果。客户名、具体数字、确切短语——语义搜索会错过这些。关键词搜索抓住它们。两者都用。

### 10. 压缩不是敌人。未写入的上下文才是

我在意识到修复更简单之前花了几天时间对抗压缩：确保任何重要内容在压缩运行前写入文件。内存刷新自动处理这个。如果在磁盘上，它能在压缩中存活。如果只在对话中，它就有风险。

## 我的当前设置

```
workspace/
├── AGENTS.md (启动序列 + 写入纪律 + 交接协议)
├── SOUL.md (个性和行为)
├── IDENTITY.md (名称、角色)
├── USER.md (所有者信息)
├── TOOLS.md (工具使用指南)
├── HEARTBEAT.md (自主检查行为)
├── MEMORY.md (策划的长期记忆，~90行)
├── PROTOCOL_COST_EFFICIENCY.md
├── learnings/
│   └── LEARNINGS.md (错误中的规则)
├── memory/ (每日日志：YYYY-MM-DD.md)
├── docs/ (参考文档移出MEMORY.md)
│   ├── knowledge-transfer.md
│   ├── infrastructure.md
│   └── group-chat-rules.md
└── skills/ (32个技能，从51个减少)
```

系统提示词：8,529个令牌。会话令牌：14,627个，占200,000上下文窗口的7.3%。Agent启动，读取所需内容，写入所学内容，在模型切换前交接上下文。

我花了5天时间到达这里。大部分是忘记“更多文件等于更好内存”的假设。不是这样。纪律才是。我的实验仍在继续。



