为什么 OpenClaw 总是忘记你(以及为什么这不是一个错误)
遗忘体验是 OpenClaw 记忆系统设计的直接结果: 内存作为磁盘上的纯 Markdown 文件存在,不在数据库中,不在 RAM 中,不在模型内部。文件是真相的来源。
当这些文件在压缩过程中丢失、配置错误或无提示地被覆盖时,代理会丢失上下文 - 并且它无法告诉您发生了什么事。
修复不是你翻转的设置。它对三层架构有足够的了解,可以对什么去哪里做出深思熟虑的决定。
完整的 OpenClaw 内存架构(3 层解释)
OpenClaw 内存跨三个不同的层运行,每个层都有不同的持久性特征和故障模式。
完整的内存生命周期:
Write → Embed/Index → Search → Compact → Recover
↓ ↓ ↓ ↓ ↓
.md file sqlite-vec semantic summary MEMORY.md
created indexes it query replaces re-read at
on save returns context session start
chunks window
该链中的每个阶段都可能独立失败。大多数遗忘问题都可以追溯到一个破碎的阶段。
第 1 层 — 活动上下文窗口
这是模型的工作记忆:当前加载到活动对话上下文窗口中的所有内容。它包括您的系统提示、对话历史记录以及搜索工具检索到的任何内存块。
里面装的是什么:
- 系统提示符(通常很大)
- 检索记忆摘录
- 工具调用历史记录
- 话锋一转
溢出时会发生什么: 当上下文窗口接近其令牌限制时,OpenClaw 会触发压缩 - 它将现有上下文汇总为压缩表示并继续。对话中内联的指令(而不是固定在持久内存文件中)在此摘要期间经常被删除。
实际限制:假设在系统提示和内存开销之后,您有大约 60-70% 的模型广告上下文窗口可用于实际对话。
第 2 层 — 每日笔记(滚动两天窗口)
每日笔记是以 YYYY-MM-DD 格式命名的仅附加 Markdown 文件,存储在 memory/ 目录中。 OpenClaw 负载 今天和昨天的 在每个会话开始时自动生成文件。
- 有关今天工作、做出的决定和活动任务的事实附加在此处
- 它们不应该被编辑——将它们视为日志
- 两天后,它们超出了自动加载窗口,只能通过语义搜索进行搜索
关键问题: OpenClaw 不会为您创建 memory/ 目录。如果该目录不存在,则每日笔记将被静默删除,不会引发任何错误,并且代理会忘记会话之间的所有内容。这个单一的遗漏导致了大多数“为什么它总是忘记我”的报道。
第 3 层 — 持久内存(MEMORY.md 和 memory-wiki)
跨会话应保留的长期事实(您的姓名、项目上下文、编码偏好、架构决策)属于 MEMORY.md 或结构化 memory-wiki 插件库。
内存.md
自由格式的 Markdown 文件。代理在会话开始时读取它。在这里写下您总是想要加载的事实。简单,零配置。
记忆维基
一个结构化插件,具有页面级组织、声明和证据跟踪、矛盾检测和新鲜度元数据。最适合拥有庞大且不断发展的知识库的生产代理商。
压缩问题——为什么你的指令在任务中消失
压缩是 OpenClaw 中记录最多的故障模式。大多数文章都涉及会话后遗忘。几乎没有地址 长时间运行的自主工作流程中的中期任务压缩 — 当代理执行多步骤任务时,压缩会在 12 步中的第 7 步静默触发,并且第 1 步中的行为指令消失。
压缩的作用是什么:
- 检测上下文窗口接近容量
- 将当前对话总结为一个压缩块
- 用摘要替换原始上下文
- 继续执行
问题:摘要针对事实和任务状态进行优化,而不是针对行为指令。 A system instruction like "always write tests before implementation" or "never overwrite files without confirmation" can survive the first compaction cycle and be gone by the second.
当它触发时: 默认 memory-core 插件中没有可配置的阈值。它根据令牌计数而不是任务阶段触发。在 2 小时的自主运行中,您预计会有 3-5 个压实周期。
如何构建抗压缩文件架构
将行为指令固定在 MEMORY.md 中,而不是对话中。 任何必须在多个压缩周期中生存的内容都需要保存在持久文件中,该文件在每次压缩后都会重新读取。
推荐的固定模式:
## Agent Behavioral Rules (always active) - Never overwrite files without showing a diff first - Write tests before implementation (TDD mode: on) - Use TypeScript strict mode in all new files ## Project Context - Stack: Node.js 22, Fastify, PostgreSQL 16 - Repo root: /home/user/project - Active sprint goal: migrate auth to Clerk
压缩后的命名约定:
- 使用
## [PINNED]为关键部分添加前缀 - 摘要器将大写标头视为高优先级 - 尽可能将每个固定事实保留在一行中 - 总结密集的段落,单行事实往往会逐字保留
- 在
MEMORY.md和今天的每日笔记中重复 3-5 个最关键的行为规则 - 冗余是你的压缩对冲
10 分钟内从零到内存设置(完整文件支架)
这是其他地方不存在的设置指南。复制这个结构,填写你的上下文,然后你就可以运行了。
目录树:
memory/
├── MEMORY.md
├── 2026-04-27.md ← today's daily note (create manually)
└── wiki/ ← only if using memory-wiki plugin
├── index.md
├── project-context.md
└── decisions.md
启动器MEMORY.md:
# Persistent Memory ## Identity & Preferences - Name: [your name] - Role: [your role] - Preferred response style: concise, no preamble ## Project: [Project Name] - Stack: [your stack] - Key constraints: [e.g., no external APIs, TypeScript only] - Current focus: [active task or sprint goal] ## Behavioral Rules - [Rule 1] - [Rule 2] ## Decisions Made - [YYYY-MM-DD] Decided to use X because Y
入门每日笔记 (2026-04-27.md):
# 2026-04-27 ## Session Goals - [ ] Task 1 - [ ] Task 2 ## Notes
插件槽配置(2026语法):
{
"plugins": {
"slots": {
"memory": "memory-core"
}
}
}
要完全禁用内存:
{
"plugins": {
"slots": {
"memory": false
}
}
}
验证步骤:
- 运行一次会话并要求客服人员回忆您在上一次会话中告诉过的内容
- 检查
memory/YYYY-MM-DD.md是否已写入(它应该有新内容) - 直接问经纪人:“你对我了解多少?” — 它应该从
MEMORY.md中提取
为生产知识库配置内存维基
通过交换插件插槽来启用它:
{
"plugins": {
"slots": {
"memory": "memory-wiki"
}
}
}
memory-wiki 在 memory/wiki/ 下生成一个结构化保管库。每个主题都有自己的页面。该插件编译一个 digest.md ,它聚合了高可信度、无矛盾的事实,以便代理在会话开始时加载。
生产代理的实用保险库结构:
memory/wiki/ ├── index.md ← vault table of contents ├── digest.md ← auto-generated; agent reads this ├── project-context.md ← stack, goals, constraints ├── decisions.md ← architectural decisions log ├── team.md ← stakeholders, contacts └── domain-knowledge.md ← business rules, glossary
在以下情况下使用内存维基:
- 您的知识库超过约 50 个事实
- 你需要矛盾检测
- 多个代理写入同一个保管库
在以下情况下坚持使用原始 MEMORY.md:
- 您是一名独立开发者
- 你的背景很稳定
- 您想要零维护费用
语义搜索和嵌入——SQLite、sqlite-vec 和 JS Fallback
OpenClaw 使用以下方式索引您的内存文件 带有 sqlite-vec 扩展的 SQLite 用于向量相似性搜索。当您或代理发出内存搜索时,它会嵌入查询并检索语义上最相关的块。
验证您的矢量存储是否正常:
# Check that the memory index exists ls memory/.index/ # Reset a corrupted index (safe to run — it rebuilds from .md files) rm -rf memory/.index/ && OpenClaw reindex
如果 sqlite-vec 不可用(在 ARM Linux 和某些 Windows 配置上常见),OpenClaw 会回退到纯 JS 向量扩展。显式强制回退:
{
"memory": {
"vectorBackend": "js"
}
}
特定于段的内存策略
独立开发人员 - 最小的开销,最大的召回率
推荐设置:memory-core 插件、MEMORY.md + 仅每日笔记,无 wiki 库。
- 将
MEMORY.md保持在 200 行以下 - 较长的文件会减慢会话启动速度 - 积极地添加日常笔记;不要试图保持它们干净
- 每周审查和修剪
MEMORY.md— 过时的事实会降低搜索质量
多代理管道——跨代理共享内存
当多个代理读取和写入同一 memory/ 目录时,您需要明确的所有权规则。
- 一个代理拥有对每个文件的写入 — 并发写入同一个
.md文件会产生冲突 - 每个代理使用子目录:
memory/agent-a/、memory/agent-b/,以及共享的memory/shared/MEMORY.md - 使用内存维基作为共享库 - 它的摘要编译比原始文件更好地处理多个编写者之间的新鲜度
长时间运行的自主任务——存活执行时间
对于运行以小时为单位的任务的代理:
- 在检查点强制写入内存 — 在每个主要任务阶段之后,指示代理将其当前状态附加到今天的每日笔记中
- 预载抗压实环境 — 在运行开始之前将完整的任务规范放入
MEMORY.md中,而不仅仅是在初始消息中 - 设置显式连续标记 在日常笔记中:
<!-- RESUME POINT: completed steps 1-4, next: step 5 -->,以便代理可以在压实周期后自我定向
为什么 EasyClaw 在长时间运行的内存任务中获胜
EasyClaw 是桌面原生的,这意味着您的内存文件、矢量索引和日常笔记与本地磁盘上的项目一起保存,而不是在超时时驱逐上下文的云会话中。默认情况下,您会获得抗压缩内存,而不是通过配置。
- ✅ 重新启动后仍然存在的持久内存 - 无云会话限制
- ✅ 零网络延迟的本地 sqlite-vec 索引
- ✅ 内置结构化内存维基 - 无需配置额外的插件
- ✅ 在每个主要任务阶段自动检查点写入
- ✅ 压缩感知固定——行为规则永远不会被总结掉
OpenClaw 内存故障排除 — 在 2 分钟内诊断任何遗忘问题
按顺序完成这些步骤:
步骤 1 — memory/ 目录是否存在?
- 不 → 创建它。这修复了约 40% 的遗忘报告。
- 是的 → 继续步骤 2。
第 2 步 — 是否写了每日笔记?
- 检查
memory/中名为今天日期的文件 - 没有文件 → 插件插槽可能配置错误。验证
plugins.slots.memory已设置,而不是false。 - 文件存在但为空 → 代理正在加载内存但未写入。检查目录的写入权限。
第 3 步 — 压缩是否触发并剥夺了您的指令?
- 症状: 代理记住事实,但在会话中忽略行为规则
- 使固定: 将所有行为规则移至
## [PINNED]部分下的MEMORY.md
步骤 4 — 压缩前上下文窗口是否溢出?
- 症状: 代理开始忽略长对话的早期部分
- 使固定: 减少系统提示大小、修剪
MEMORY.md或将任务拆分为带有明确检查点注释的较短会话
第 5 步 — SQLite 向量索引是否已损坏?
- 症状: 内存搜索未返回结果或明显不相关的结果
- 使固定:
rm -rf memory/.index/ && OpenClaw reindex - 如果日志中出现sqlite-vec错误:通过
"vectorBackend": "js"切换到JS后端
常见问题解答
问:为什么关闭终端后 OpenClaw 会忘记所有内容?
答:最常见的原因是 memory/ 目录不存在。当目录丢失时,OpenClaw 会默默地删除每日笔记 - 没有错误,没有警告。在项目根目录中创建目录,并验证下一个会话后是否会出现一个带日期的文件。
问:我的代理在开始时遵循指示,但后来在长期任务中忽略它们。为什么?
答:这就是压实。当上下文窗口填满时,OpenClaw 会总结之前的内容以腾出空间。摘要保留事实,而不是行为指示。将您的规则移至 ## [PINNED] 部分下的 MEMORY.md 中,以便在每个压缩周期后重新读取它们。
问:我应该使用内存核心还是内存维基?
答:从 memory-core 开始。它是零配置的,可以很好地处理大多数独立开发人员的工作负载。仅当您的知识库超过约 50 个事实、需要矛盾检测或多个代理正在写入同一内存库时,才升级到 memory-wiki。
问:在 2 小时的自主运行中,我预计可以进行多少次压实循环?
答:预计 3-5 个压实周期。该阈值基于令牌计数,而不是经过的时间或任务阶段,并且在默认的 memory-core 插件中用户不可配置。这就是为什么 MEMORY.md 中的抗压缩固定对于长时间运行的任务至关重要。
问:内存搜索返回不相关的结果。我该如何修复它?
答:SQLite 矢量索引可能已损坏或过时。运行 rm -rf memory/.index/ && OpenClaw reindex 以从 .md 文件重建它。这样可以随时安全运行。如果 sqlite-vec 错误仍然存在(在 ARM Linux 和某些 Windows 设置上常见),请切换到 JS 回退后端。
问:我可以针对同一内存目录运行多个代理吗?
答:可以,但是需要明确的所有权规则。对同一个 .md 文件的并发写入将产生冲突。将每个代理的子目录(memory/agent-a/、memory/agent-b/)与共享 memory/shared/MEMORY.md 一起使用,并为共享保管库使用内存维基。
问:每日笔记在自动加载窗口中停留多长时间?
答:只有今天和昨天的每日笔记会在会话开始时自动加载。较旧的注释不在自动加载窗口之内,只能通过语义搜索访问。这是设计使然——加载每个历史笔记会消耗太多的上下文预算。
最终结论——实际有效的内存设置
为大多数用户推荐的基准: memory-core 插件,在第一次会话之前创建的 memory/ 目录,MEMORY.md 在明确标记的固定部分中包含行为规则,在每个会话中附加每日注释。
80% 的遗忘问题背后有一个错误: 不创建 memory/ 目录,并且在 MEMORY.md 中没有抗压缩固定。代理在第一个压缩周期中丢弃上下文,并且无处可写回。
您的行动清单:
- 在项目根目录中创建
memory/目录 - 复制上面的起始
MEMORY.md模板并填写您的上下文 - 验证
plugins.slots.memory设置为"memory-core"(或您选择的插件) - 在
MEMORY.md中的## [PINNED]下添加 3–5 条最关键的行为规则 - 第一次会议后,确认已写下注明日期的每日笔记
- 如果语义搜索感觉不太好,请运行
OpenClaw reindex来重建向量索引
一旦你理解了它,这个架构就是合理的。大多数遗忘问题会在遵循此清单后 10 分钟内得到解决。