OpenClaw 中的高级内存管理:QMD、图、mem0
如果你的内存使用场景主要是“查找与此查询相关的笔记”,那么 QMD 是一个合适的起点。Cognee 是一款开源的内存引擎,它正是为此而设计的:它读取你的 Markdown 内存文件,提取实体和关系,构建图,并提供基于图的搜索模式,这些模式可以通过遍历连接而非仅仅匹配向量来回答问题。最大的问题在于关系性:如果你周一写了“Alice 管理认证团队”,周五又问“谁负责认证权限”,纯粹的向量搜索可能会搜出
如果你使用 OpenClaw 几周后开始注意到它“忘记”了一些它应该知道的信息,那并非遇到了 bug,而是遇到了设计上的限制。默认的内存系统刻意保持简洁:磁盘上的 Markdown 文件、用于检索的本地向量索引,以及一个上下文窗口,当内容过多时会自动压缩并删除旧内容。
刚开始的时候这没问题。但一旦你有了真实的过往记录可以参考,而经纪人却无法将这些线索联系起来,那就令人沮丧了。
本文介绍了扩展 OpenClaw 内存的三种主要方法(超出默认设置):QMD(混合检索,可显著提高召回准确率)、Cognee(知识图谱内存,可理解关系,而不仅仅是相似性)和 Mem0(自动事实提取和长期存储,具有云模式和自托管模式)。
如果您还没有了解OpenClaw 内存的工作原理,请先从那里开始,因为本文假设您已经了解 Markdown 层、每日日志、MEMORY.md 以及基本的嵌入/检索流程。
为什么默认系统会随着时间的推移而失效
以下是对您目前所用设备的真实评估……
内置系统将内存文件分割成大约 400 个标记(token)的块,块之间有 80 个标记的重叠,并将每个块嵌入到本地 SQLite 支持的索引中。查询时,它会对这些块进行语义搜索,并返回最佳结果。对于小内存量,这种方法效果很好。但随着工作空间的增长,一些实际问题就会显现出来。
最大的问题在于关系性:如果你周一写了“Alice 管理认证团队”,周五又问“谁负责认证权限”,纯粹的向量搜索可能会搜出一些关于 Alice 的信息片段和一些关于认证的信息片段,但它无法将这些信息关联起来,形成一个连贯的答案。借用一句在讨论这一局限性时经常用到的话来说,系统记住了所有信息,但却什么也理解不了。
规模化搜索还会带来检索质量问题。对数百个包含 400 个词元的词块进行纯向量搜索,随着内存容量的增长,收益会递减。词汇相同但概念不相关的词块会与正确答案一同出现。而使用与查询不同术语的词块则根本不会出现,即使它们正是你所需要的。
此外,还有数据压缩。在长时间会话期间,OpenClaw 必须将当前上下文压缩到模型的令牌窗口中。较早的对话部分会被汇总或丢弃。如果在数据压缩运行之前没有显式地将某些内容写入内存文件,那么这些内容就会丢失。代理的行为就好像这些交互从未发生过一样。
下面这三个后端分别解决了这个问题的不同部分。
QMD:混合检索以提高召回率
QMD(查询-内存-文档)是一种替代的内存后端,它会在保留现有 Markdown 文件不变的情况下替换默认的搜索层。它不需要您更改任何内存写入方式,而是通过并行运行多个搜索策略并合并结果,显著提升检索效率。
QMD的工作原理
QMD 并非仅进行一次向量搜索,而是同时运行至少两个检索通道,对现有的 Markdown 内存进行搜索。关键词通道(BM25 或类似的词汇搜索)能够很好地处理精确匹配和近似匹配的词条。向量通道则负责处理语义相似度。然后,通过重新排序步骤对组合后的候选词集进行评分,平衡词汇精确度和语义召回率,最终生成一个排名列表。
实际上,这意味着像“网关服务器设置”这样的查询可以匹配到讨论“在 Mac Mini 上运行网关”的笔记,即使“服务器”和“设置”这两个词并没有直接出现在该笔记中。这也意味着,当你搜索非常具体的内容,例如端口号或项目名称时,关键词通道可以确保这些精确匹配不会被语义相近但相关性较低的结果所掩盖。
安装 QMD
QMD 作为本地 sidecar 服务与 OpenClaw 并行运行。常见的安装方式是通过 Bun:
bun install -g https://github.com/tobi/qmd
安装完成后,启动它并让它在 OpenClaw 实例附近运行。它监听本地端口,并提供一个简单的 API,OpenClaw 的内存后端会在每次检索时调用该 API。所有操作都在本地运行,这意味着您的内存文件永远不会离开本地计算机。
在 OpenClaw 中配置 QMD
在代理配置中切换到 QMD 后端:
memory:
backend: qmd
citations: auto
qmd:
includeDefaultMemory: true
update:
interval: 5m
debounceMs: 15000
onBoot: true
waitForBootSync: false
limits:
maxResults: 6
maxSnippetChars: 700
timeoutMs: 4000
scope:
default: deny
rules:
- action: allow
match:
chatType: direct
这里有几点需要了解。设置includeDefaultMemory: true会保留所有现有的 Markdown 源文件,这正是你想要的。`and`update.interval设置debounceMs控制 QMD 重新索引内存文件的频率。5 分钟的间隔加上 15 秒的延迟是一个合理的默认值,这意味着快速编辑不会触发频繁的重新嵌入。
这个scope屏蔽功能很重要,但很容易被忽略。加上default: deny一条明确的允许直接聊天记录的规则,QMD 只会索引和检索直接消息对话。这样就能将嘈杂的群聊信息排除在长期记忆之外,这通常正是你想要的,除非你明确地构建了一个共享记忆系统。你还可以直接控制搜索策略:
memory:
backend: "qmd"
qmd:
searchMode: "query" # hybrid (default), "search" (keyword only), or "vsearch" (vector only)
query模式是完整的混合管道。当您想要隔离一个通道进行调试,或者当某个特定用例比另一种方法更有优势时,search这些模式非常有用。vsearch
QMD何时值得
如果你刚开始使用全新的工作区,并且每天的日志量很小,那么默认的 SQLite 内存就足够了。但当你积累了几周的日志,开始发现代理程序本应发现某些信息却未能找到时,QMD 的性能就会明显提升。这时就应该考虑切换了。
Cognee 的知识图谱存储
QMD 改进了查找文本块的方式,但它对关系推理没有帮助。要进行关系推理,你需要一个能够构建实体及其连接的显式模型的工具。Cognee 是一款开源的内存引擎,它正是为此而设计的:它读取你的 Markdown 内存文件,提取实体和关系,构建图,并提供基于图的搜索模式,这些模式可以通过遍历连接而非仅仅匹配向量来回答问题。
知识图谱能带来什么?
想想这在实际内存内容中是如何体现的。周一,你在内存笔记中写道“Alice 管理认证团队”。周三,你又写道“认证团队拥有权限服务”。周五,你问“谁负责权限服务?”向量搜索或许能分别找到这两条笔记,但无法将整个链条连接起来:Alice → 管理 → 认证团队 → 拥有 → 权限服务。而图遍历则可以。
Cognee 与 OpenClaw 的集成旨在确保 Markdown 始终是您的数据来源。图谱在后台作为额外的检索层运行。您无需更改内存文件的写入方式;Cognee 会自动读取它们、提取结构并将其添加到图中。
Cognee插件的工作原理
该插件分三个阶段运行,每个代理会话都会运行这些阶段。
启动时,它会扫描 MEMORY.md 文件以及工作区中该目录下的文件memory/*.md。新文件会被添加,已更改的文件会被更新(使用基于哈希的变更检测来避免重复处理),而未更改的文件则会被跳过。一个同步索引位于 [此处应填写索引路径],用于~/.openclaw/memory/cognee/跟踪已建立索引的内容。
在每次代理运行之前,插件会将当前提示发送给 Cognee。Cognee 使用GRAPH_COMPLETION搜索(或其他已配置的搜索类型)查询图,找到相关的实体和关系,插件会将这些结果作为结构化上下文注入到基础内存系统返回的常规 Markdown 代码片段中。
每次代理运行后,插件都会再次扫描内存文件,查找会话期间发生的任何更改并更新关系图。对话期间写入的新知识和关系会反映在后续查询中。
为 OpenClaw 设置 Cognee
Cognee 作为独立服务器运行,通常通过 Docker Compose 实现。本地运行后,插件配置~/.openclaw/config.yaml如下所示:
plugins:
entries:
memory-cognee:
enabled: true
config:
baseUrl: "http://localhost:8000"
apiKey: "${COGNEE_API_KEY}"
datasetName: "my-project"
searchType: "GRAPH_COMPLETION"
autoRecall: true
autoIndex: true
对于运行多个项目的人员来说,这个datasetName字段非常重要:每个项目或工作区使用不同的名称,这样关系图就不会混淆来自不相关上下文的实体。例如,如果一个项目中的 Alice 和另一个项目中的 Alice 是不同的人,您肯定不希望关系图将她们混淆。
如果您想要更精确地控制进入索引图的内容,可以从头开始autoIndex: false,然后显式地添加文档。当您有一个庞大的现有内存目录,并且希望有意识地控制哪些内容优先处理,而不是在启动时一次性索引所有内容时,这种方法非常有用。
Cognee 与 QMD
它们解决不同的问题,可以协同使用。QMD 可以提升所有 Markdown 文档的文本检索效率。Cognee 在此基础上增加了关系推理功能。如果你的内存使用场景主要是“查找与此查询相关的笔记”,那么 QMD 是一个合适的起点。如果你正在运行长期项目,其中人员、团队、系统及其相互关系对最终结果至关重要,那么 Cognee 才是实现这一目标的关键。
Mem0:自动事实提取和长期存储
QMD 和 Cognee 都基于你已编写的 Markdown 文件运行。Mem0 则采用不同的方法:它监控对话,自动从中提取结构化信息,进行去重,并将它们存储在向量数据库中以便后续检索。你无需向 MEMORY.md 文件写入任何内容。系统会自动从对话中提取并存储知识。
Mem0 的独特之处
每次交流结束后,Mem0 会使用 LLM 处理完整的对话记录。它会识别出有意义的事实(例如“用户偏好深色模式”、“项目截止日期是 3 月 15 日”、“服务 X 的 API 密钥每月过期”),并与已有的信息进行去重,然后将结果存储为嵌入。在发出下一个回复之前,它会查询这些已存储的事实,查找与当前消息相关的任何信息,并将其注入到提示中。
当您在多个会话中以对话方式使用 OpenClaw 并且不想手动管理内存文件时,这非常有用。对于多用户设置中的每个用户的内存管理也很有用,因为 Mem0 会按命名空间对内存进行划分userId。
Mem0 云托管 vs 自托管
有两种部署模式。托管版本使用 Mem0 的云基础设施。安装插件:
openclaw plugins install @mem0/openclaw-mem0
从 app.mem0.ai 获取 API 密钥,然后进行配置:
"plugins": {
"entries": {
"@mem0/openclaw-mem0": {
"enabled": true,
"config": {
"mem0Url": "https://api.mem0.ai",
"apiKey": "your-key-here",
"userId": "your-identifier",
"autoRecall": true,
"autoCapture": true
}
}
}
}
如果您希望将内存数据保留在本地,则可以使用自托管选项运行由 ChromaDB 支持的 FastAPI 服务器。安装服务器依赖项:
pip install mem0ai fastapi uvicorn chromadb
启动服务器(默认端口 8080):
python server.py
然后配置 OpenClaw 以使用它,并使用社区自托管插件:
"plugins": {
"entries": {
"openclaw-mem0-memory": {
"enabled": true,
"config": {
"mem0Url": "http://localhost:8080",
"userId": "openclaw_local",
"autoRecall": true,
"autoCapture": true,
"maxRecallResults": 10,
"profileFrequency": 50,
"captureMode": "all",
"debug": false
}
}
}
}
自托管服务器需要 LLM 和嵌入式凭据才能进行提取。请通过环境变量提供这些信息~/.openclaw/workspace/.env:
OPENAI_API_KEY=your-key
# or ANTHROPIC_API_KEY=your-key, depending on which model you're using for extraction
此profileFrequency设置控制 Mem0 从存储的内存中重建整合配置文件的频率(默认为每 50 次捕获一次)。这captureMode: "all"意味着每次对话都会被处理,这通常是你想要的,但如果你发现存储了太多噪声,可以限制此频率。
Mem0 可用的命令和工具
该插件公开了多个代理工具和斜杠命令,用于显式内存操作:
mem0_store,,,作为代理mem0_search工具mem0_forgetmem0_profile/remember如同/recall聊天中的斜杠命令openclaw mem0 status,,作为 CLIopenclaw mem0 search命令openclaw mem0 wipe
openclaw mem0 wipe值得了解。如果自动捕获功能存储了大量无关信息,而您想在不破坏 Markdown 内存文件的情况下重新开始,此操作只会清除 Mem0 存储。
当 Mem0 有意义时
当您需要无需手动维护 MEMORY.md 即可实现自动长期存储时,Mem0 最为实用。当您需要在多个代理或通道中为每个用户设置内存命名空间时,它也是理想之选。但缺点在于,您需要依赖 LLM 提取步骤来决定哪些信息值得存储,这意味着有时会存储一些无关信息,有时又会遗漏一些重要信息。/remember如果您希望确保某些信息被正确捕获,则可以使用显式命令。
内存隔离、最佳实践和备份
每个项目使用独立的存储空间
无论你使用默认的 Markdown 系统、QMD、Cognee 还是 Mem0,为每个项目分配独立的内存都能防止信息交叉污染,并提高检索精度。实际上,这意味着每个主要项目需要单独的工作区,或者至少需要单独的内存目录。对于 Cognee,datasetName每个项目使用不同的内存。对于 Mem0,userId每个用户或上下文使用不同的内存值。项目内存混用造成的混乱非常隐蔽,难以调试,例如,代理给出的答案可能略有偏差,需要花费一些时间才能追溯到内存冲突。
控制哪些内容会被索引。
不要盲目地索引所有内容。在 Markdown 系统中,使用 MEMORY.md 来存储经过整理的、稳定可靠的知识,而让每日日志承载那些嘈杂的短期细节。定期清理或汇总每日文件,而不是任其无限累积。在 QMD 中,使用范围规则,避免群聊和嘈杂的公共频道最终被写入长期记忆。在 Mem0 中,如果发现存储了过多无关内容,请captureMode进行调整。autoCapture
压实前写下重要事项
上下文窗口压缩会丢失信息,而且无法绕过令牌限制。实际的应对方法是将压缩视为一种强制操作:如果某些信息很重要,则应在会话期间将其写入内存文件,而不是寄希望于它在压缩后仍然保留。一些设置实现了每晚的“整合”工作流,其中 cron 作业读取最近的会话日志,提取关键决策和事实,并将摘要版本写入 MEMORY.md 文件,同时修剪原始日志。这与 Cognee 插件的 autoIndex 自动执行的操作类似,但允许您更好地控制要保留的内容。cron调度程序指南介绍了如何设置此类工作流。
备份内存
由于 Markdown 是本文所述所有系统的主要数据源,因此基本备份非常简单:~/.openclaw/workspace/定期创建快照,包括 MEMORY.md 文件、memory/目录以及任何 USER.md 或类似文件。对于 QMD,索引通常可以从 Markdown 源文件重建,但备份索引可以节省大型语料库的重新嵌入时间。对于 Cognee,在迁移或克隆环境之前,请从其数据库中导出数据集。对于自托管的 Mem0,请将 ChromaDB 目录与配置文件一起备份。备份和导出指南详细介绍了具体操作步骤。
隐私护栏
内存通常包含敏感信息。以下几个默认设置值得检查:memorySearch.fallback = "none"如果您希望阻止远程嵌入后端处理本地文档,请进行相应设置。请将 Cognee 和自托管的 Mem0 服务部署在本地主机或私有网络上;如果您使用云 API(Mem0 云、远程嵌入),请确保令牌的作用域设置正确,并且配置文件中不会以明文形式存储密钥。OpenClaw 默认仅在私有会话中加载 MEMORY.md,而不在群组上下文中加载,这是一个值得保留的合理基准。
比较三个后端
明确何时使用哪种工具:大多数人在无法满足默认设置需求后,应该首先使用 QMD,因为它所需的设置更改最少,并且在最广泛的使用场景下都能最大程度地提高记忆召回质量。如果关系推理对您的项目至关重要,特别是当您需要系统将不同记忆笔记中的事实联系起来,而不仅仅是找到相关的片段时,请添加 Cognee。如果您希望从对话中自动提取信息并尽量减少手动管理,或者当您需要为每个用户设置记忆命名空间以进行多用户部署时,请使用 Mem0。
这些功能并不互斥。QMD 和 Cognee 可以叠加使用。Mem0 可以与它们同时运行。Markdown 文件始终作为统一的数据源。
更多推荐


所有评论(0)