OpenClaw 篇六:长期记忆系统与内存问题修复指南

2次阅读
没有评论

共计 6149 个字符,预计需要花费 16 分钟才能阅读完成。

OpenClaw 篇六:长期记忆系统与内存问题修复指南

OpenClaw 的记忆系统是构建 AI Agent 最重要的组成部分之一,但也是最容易让人困惑和踩坑的部分。这篇文章把我对 OpenClaw 记忆系统的理解和优化经验整理出来,希望能帮你少走一些弯路。

OpenClaw 记忆机制详解

OpenClaw 的记忆系统完全基于本地工作区文件,没有任何云端依赖。所有记忆都以 Markdown 格式存放在工作区目录下,随时可以查看、修改和删除。这种「文件即真相来源」的设计理念是 OpenClaw 记忆系统的根基——你的记忆不是锁在某个数据库里的黑盒,而是一堆你可以用任何文本编辑器打开的 Markdown 文件。

记忆的层次结构

OpenClaw 的记忆分为几个层次,每个层次承担不同的职责。

长期记忆存储在 MEMORY.md 文件中。这是 Agent 的核心记忆库,存放用户的固定偏好、重要决策、项目背景和核心约定。在主会话中,这个文件会被自动加载到 Agent 的上下文里。理想情况下,它应该只包含那些即使一个月后仍然重要的信息。

日常日志存储在 memory/YYYY-MM-DD.md 格式的文件中,类似于 Agent 的日记。它会记录当天发生的关键事件、临时笔记和待办事项。通过后台的心跳任务(Heartbeat),Agent 会定期回顾这些日志,把值得长期保留的经验提炼到 MEMORY.md 中。日常日志采用追加写入(Append-only)的方式,保证了可靠性和可审计性。

身份与基础上下文则由几个专用文件定义:USER.md 记录关于用户的信息(比如时区、沟通偏好),SOUL.md 和 AGENTS.md 定义了 OpenClaw 的行事风格和工作流规则,TOOLS.md 存放本地环境的备忘录(SSH 别名、设备 ID 等)。

检索系统

当 Agent 需要从记忆中提取信息时,它不会简单地读取所有文件——那样会导致上下文窗口溢出。相反,它采用混合记忆搜索(Hybrid Memory Search)机制,结合精确关键词匹配和语义向量搜索,只提取最相关的信息片段。具体来说,[[BM25]] 关键词搜索(默认权重 30%)基于 SQLite 的 FTS5 全文搜索引擎,擅长精确匹配错误码、函数名、API 名称等标识符;向量语义搜索(默认权重 70%)使用余弦相似度计算,擅长捕捉措辞不同但语义相近的内容。两条检索路径的结果通过加权分数合并后排序,混合搜索的 p50 延迟约为 15 毫秒。

上述核心文件(USER.md、SOUL.md 等)会在对话开始时自动作为系统提示词的一部分注入。而当你问 Agent「上周那个决定是什么」或「之前我说的那个偏好」时,它会使用内置的 memory_search 工具对所有记忆文件进行搜索,精准提取过去的片段后再回答。

默认记忆系统的六大问题

理解了记忆机制之后,接下来要面对的现实是:OpenClaw 的默认记忆实现存在诸多不足。这不是说它的设计有根本性错误,而是说默认配置在实际使用中会暴露出一系列需要手动修复的问题。

信息保存决策不当

Agent 自动决定哪些信息应该保存、哪些不应该保存,但它的判断标准往往和你的期望不一致。结果就是重要的信息可能不会被自动保存,而一些无关紧要的细节反而被写入了记忆文件。比如你告诉 Agent「我们项目的部署环境用的是 K3s」,这显然是需要记住的关键背景,但 Agent 可能觉得这是当前对话的临时信息而没有持久化。

对应代码位置 https://github.com/openclaw/openclaw/blob/main/extensions/memory-core/src/flush-plan.ts#L25

OpenClaw 篇六:长期记忆系统与内存问题修复指南

检索优先级错位

Agent 经常基于当前上下文窗口中已有的信息来回答问题,而不是主动去搜索记忆文件。这意味着如果某条信息已经不在当前上下文中了,Agent 可能会「编造」一个答案,而不是先查一下记忆库。这是一个很微妙但影响很大的问题——用户会以为 Agent 记住了什么,实际上它只是在猜。

Compaction 导致信息丢失

当上下文窗口即将溢出时,OpenClaw 会触发压缩(Compaction)来释放空间。这个过程会清除大量历史消息,而被清除的信息如果没有在压缩前被保存到记忆文件中,就永久丢失了。这是默认记忆系统最严重的结构性缺陷——压缩是不可逆的,一旦信息丢失就无法恢复。

Memory Flush 质量差

OpenClaw 在压缩前会触发一次 Memory Flush,试图把上下文中的重要信息保存到记忆文件中。但默认的 flush 提示词仅仅是「store durable memories」,没有明确定义什么才算「持久」的信息。结果就是 flush 倾向于保存大量「噪音」——格式化的日志片段、中间推理过程、重复的状态描述——而真正重要的决策和结论反而被忽略。

无法访问历史对话

默认情况下,Agent 只能访问记忆文件中的内容,而无法回顾之前的对话记录本身。这意味着如果某次对话中讨论了重要内容但没有被写入记忆文件,这些内容就彻底消失了。Agent 的记忆完全依赖于「写入」这个动作——没被写入的等于没发生过。

搜索质量随规模下降

随着记忆文件数量和体积的增加,搜索质量会逐渐下降。更多的文本块意味着更多的噪音候选项,检索结果的准确性降低。而且,文本块之间缺乏明确的关联性,比如,当我们告诉 Open Claw 使用 Python 编写后端代码时,它会识别并使用 Python。但如果我们询问 Open Claw 用何种语言编写 API,它可能无法将这两条独立的记忆关联起来得出答案。

修复方案

针对上述问题,以下是我实践过的一系列修复方案,从简单的配置调整到引入外部工具,逐步递进。

优化 Memory Flush

这是投入产出比最高的第一步修复。Memory Flush 是在上下文压缩之前触发的函数,目的是在重要信息被清除前将其保存到持久记忆中。默认配置效果不佳的根本原因是提示词太模糊。

修复方法是在配置文件中自定义 flush 的提示词,明确指定 Agent 应该查找和保存的信息类型。比如你可以要求它关注:用户明确表达的偏好和约定、项目架构的关键决策及其理由、新发现的环境信息(端口、路径、凭证名称)、任务的最终结论和成果、用户纠正 Agent 行为的具体实例。同时明确排除:中间推理过程、已经在 MEMORY.md 中存在的重复信息、临时性的调试输出。

需要注意的是,一个过于宽泛的 flush prompt 反而会适得其反——它会往记忆中灌入大量低质量的「垃圾信息」,让后续的检索变得更加嘈杂。flush prompt 的目标不是「记住一切」,而是「只记住真正重要的」。

{
  "agents": {
    "defaults": {
      "compaction": {
        "mode": "safeguard",
        "reserveTokensFloor": 24000,
        "memoryFlush": {
          "enabled": true,
          "softThresholdTokens": 32000,
          "forceFlushTranscriptBytes": "2mb",
          "prompt": "Write a durable session note to memory/YYYY-MM-DD.md. Capture: decisions, constraints, open questions, owners, and any state that would break the plan if forgotten. If nothing meaningful happened, write NO_FLUSH.",
          "systemPrompt": "Session nearing compaction. Store durable memories now. Be terse. Prefer bullet points. Do not rewrite the conversation."
        }
      },
    }
  }
}

官方配置链接

启用 Session Indexing

Session Indexing 是解决「无法访问历史对话」问题的直接方案。通过在 Agent 配置中添加相应配置,可以让 Agent 搜索过去的对话记录,而不仅仅是记忆文件。

{
  "memorySearch": {
    "experimental": {
      "sessionMemory": true
    }
  }
}

这个功能存在一个权衡:它增加了记忆的覆盖范围,但也引入了更多噪音。过去对话中的每一轮交互都变成了可检索的内容,包括大量不那么重要的中间过程。这也是为什么优化后的 flush prompt 变得更为关键——好的 flush 为 Agent 提供了更清晰的检索信号,降低了从嘈杂的历史对话中误检索的概率。

手动记忆管理

不要完全依赖自动化。在日常使用中,养成几个习惯可以显著提升记忆系统的质量。

如果有特定信息希望 Agent 记住,直接告诉它。比如「记住我们的部署用的是 [[K3s]],集群有三个 master 节点」。主动保存比期待 Agent 自动判断要可靠得多。

在重要对话结束时,可以要求 Agent 列出这次对话中值得保存的关键信息,然后你来手动筛选哪些写入 MEMORY.md、哪些写入日常日志、哪些不需要保存。这个「人工审核」的步骤虽然增加了一点操作成本,但能大幅提升记忆的信噪比。

定期清理也很重要。每周至少花几分钟阅读一下 MEMORY.md 和最近的日常日志,清除过时的信息和噪音。用 [[Obsidian]] 打开这些 Markdown 文件会很方便——它提供了比终端更友好的编辑界面,而且可以通过双链看到记忆文件之间的关联。

引入 QMD 高级搜索

随着记忆的增长,默认搜索系统的局限性会越来越明显。QMD(Query, Match, Discover)是一个本地搜索引擎,可以替代 OpenClaw 默认的搜索后端。它结合了关键词搜索和语义搜索,并在此基础上增加了结果重排序(Re-ranking)步骤,把最相关的结果放在最前面。

QMD 比默认搜索更擅长处理大规模记忆文件的检索。当你的 MEMORY.md 超过几千行、日常日志累积了几十个文件之后,默认搜索的检索质量会明显下降,而 QMD 通过更智能的排序算法可以保持相对稳定的检索准确率。

安装方式很简单,通过 npm 或 bun 下载 QMD,然后在配置中将 memory backend 指向 QMD 即可。也可以直接让 Agent 帮你完成配置。

接入 Mem0 独立记忆层

[[Mem0]] 是一个开源的独立记忆层,它从根本上解决了 OpenClaw 默认记忆系统的两个核心痛点:自动捕获记忆(不再依赖 Agent 自行判断哪些信息该保存),以及自动回忆相关记忆(在 Agent 回复之前自动召回相关的历史信息)。

Mem0 的工作方式和 OpenClaw 内建的记忆系统有本质区别。OpenClaw 的记忆依赖于 Agent 在上下文窗口内的判断——Agent 需要「意识到」某条信息重要并主动保存它。但 Mem0 作为独立的外部层,会截获所有对话内容并自动提取和存储关键信息,不依赖 Agent 的判断力。这直接解决了「未写入」和「压缩丢失」两个问题,因为记忆存储在上下文窗口之外,不受 Compaction 的影响。

Mem0 作为 OpenClaw 插件安装,只需一个简单的命令,可以在很短的时间内为 Agent 提供跨会话的持久记忆。它获得了 Y Combinator 的支持,拥有超过五万名开发者用户,是目前这个领域最成熟的方案。Mem0 支持知识图谱构建和 prompt 压缩(最高可减少 80% 的 token 消耗),提供从免费到每月 249 美元的 SaaS 服务,也支持自托管。

需要注意的是,Mem0 虽然功能全面,但它的定位不只是 AI Coding Agent——它面向所有 AI 应用场景。对于只需要解决编程 Agent 记忆问题的用户来说,可能存在一定的过度设计。如果你追求更轻量、更专注于 Coding Agent 的方案,也可以考虑 [[mem9]](由 [[PingCAP]] 团队开发,基于 [[TiDB]] 后端,专为 AI Coding Agent 设计)。

增强记忆关联性:Cognee

前面提到的所有方案都在解决「存储」和「检索」的问题,但还有一个更深层的问题没有触及——记忆片段之间缺乏关联性。默认的向量检索擅长相似性匹配,但在推理关系(如所有权、依赖性、因果关系)方面表现不佳。

[[Cognee]] 是一个开源的知识引擎,它让文档不仅可以通过语义搜索连接,还能通过关系图谱进行关联。就拿之前的例子为例,我们让Agent记住我们使用 Python 编写后端代码,后端提供 RESTful API ,那么通过 Cognee 构建知识图谱,我们就可以发现 ,API 是可以沿着「API → 后端项目 → Python」的关系链自动推导出项目的 API 是 Python 编写的。

Cognee 适用于需要深入理解关系和结构化知识的场景,比如企业环境中的多人协作、多 Agent 团队的知识共享、复杂项目中组件之间依赖关系的追踪。不过对于个人开发者的基础 OpenClaw 设置,引入 Cognee 可能有些过度——只有当你的记忆规模大到默认搜索和 QMD 都难以应对时,才需要考虑它。

各方案对比与选择建议

方案 解决的问题 复杂度 适用场景
优化 Memory Flush 保存决策不当、噪音过多 所有用户的第一步
启用 Session Indexing 无法访问历史对话 需要回溯历史对话的用户
手动记忆管理 信噪比低、重要信息遗漏 所有认真使用的用户
QMD 搜索引擎 大规模记忆下搜索质量下降 记忆文件超过数十个的用户
[[Mem0]] / [[mem9]] 自动捕获和回忆、跨会话持久化 中高 需要跨会话记忆的用户
[[Cognee]] 记忆片段缺乏关联性 企业级或多 Agent 协作场景

我的建议是按照上面的顺序逐步推进。先从优化 Memory Flush 和手动管理开始,这两步零成本但效果显著。等到记忆规模增长后再考虑 QMD 和 Mem0。Cognee 留到真正需要关系推理的时候再引入。

最后

OpenClaw 的记忆系统在设计理念上是优秀的——文件优先、本地存储、人类可读、可审计。但默认实现在「什么时候保存」「保存什么」「如何检索」这三个环节上都有明显的提升空间。好消息是,OpenClaw 的插件化架构让这些问题都可以通过外部工具来修复,而不需要修改核心代码。

从 Memory Flush 的精细化配置,到 QMD 搜索引擎的引入,再到 Mem0 和 Cognee 这样的独立记忆层和知识图谱——每一层优化都在解决记忆链路上的一个具体瓶颈。最终的目标是让 Agent 的记忆系统从「偶尔能记住一些东西」进化为「几乎不会遗忘任何重要的信息」。

结合之前介绍的 [[OpenClaw Lossless 记忆和上下文管理|lossless-claw]] 插件(解决会话内上下文连贯性问题),OpenClaw 的记忆体系正在逐步完善。会话内有 lossless-claw 保证不丢失上下文,会话间有 Mem0/mem9 保证知识积累,加上 QMD 和 Cognee 提升检索质量和关联推理——这套组合拳让 AI Coding Agent 的记忆能力离「真正可靠」越来越近。

related

  • [[OpenClaw]]
  • [[OpenClaw 记忆]]
  • [[OpenClaw Lossless 记忆和上下文管理]]
  • [[mem9]]
  • [[Mem0]]
  • [[Cognee]]
  • [[BM25]]
  • [[OpenClaw 篇五:必备的 Skills]]
  • [[OpenClaw 篇七:配置多 Agent 解决不同问题]]

正文完
 0
评论(没有评论)