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

523次阅读
没有评论

共计 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
评论(没有评论)