深度剖析腾讯云出品的 memory-tencentdb:它到底给 OpenClaw 补上了什么能力?

@tencentdb-agent-memory/memory-tencentdb 是一款 腾讯云团队出品 的 OpenClaw 长期记忆插件。

它看起来像是“给 AI 多加了一层记忆”,但真正值得拆开的,是它背后那套运行条件:Node 版本、node:sqlite 的能力边界、SQLite FTS5 是否可用、以及它到底是在“存聊天记录”,还是在做一套更完整的长期记忆系统。

折腾完以后,我反而觉得这个插件挺值得写一篇。因为它不是那种“装了一个新功能”那么简单,它其实对应的是一个很现实的问题:

AI 聊天时看起来什么都懂,但一旦跨会话、跨天、跨场景,记忆就会开始断层。

memory-tencentdb,本质上就是给 OpenClaw 补这一层能力。


先说结论:这插件到底是干什么的?

一句话说,它是一个给 OpenClaw 用的本地长期记忆插件

它做的事不是简单保存聊天记录,而是把一次次对话,慢慢沉淀成更适合以后调用的内容。它的大概思路是:

  1. 先把原始对话记下来
  2. 再从对话里提取“值得记住的信息”
  3. 再把这些信息按场景归纳
  4. 最后形成更稳定的用户画像和长期记忆
  5. 下次对话开始前,再把相关记忆召回回来

所以它不是一个“聊天归档工具”,更像是一个本地记忆流水线


它跟我们原来那种文件记忆有什么区别?

这个问题我一开始也有。

因为我们本来就有类似的记忆逻辑:

  • MEMORY.md
  • memory/客观事实.md
  • memory/偏好和观点.md
  • memory/实体/*.md
  • memory/daily/*.md

这套东西本来就在工作,而且优点很明显:

  • 可读
  • 可改
  • 可审计
  • 规则和事实落点很明确

但它更偏向显式维护。也就是说,重要信息得有人写进去,结构得有人整理,记忆质量强依赖维护习惯。

memory-tencentdb 走的是另一条路:自动捕获、自动提炼、自动召回。

而且我们原来其实已经做过不少优化,不是完全靠手工硬记。

比如之前就有两类做法:

  • 通过 cron 定期整理 JSONL:把前一天的对话和运行产物做归档、整理,再把重要信息提取进固定的记忆文件
  • 通过 AGENTS.md 约束日常写入:要求 agent 在对话过程中,把规则、偏好、更正、决策这类重要信息写进当天记忆,而不是只留在会话上下文里

也就是说,原来的思路更像是:

  • 先有原始材料
  • 再靠定时任务整理
  • 再靠规则要求把重点内容沉淀到 md 文件

这套方法其实已经很实用了,而且优点很明确:稳定、可读、可控、方便人工校正。

memory-tencentdb 真正补上的,不是“从无到有的记忆能力”,而是把这套流程继续往前推进了一步:把原本依赖 cron 和规则驱动的整理动作,进一步变成了更细颗粒度的自动捕获、自动提炼和自动召回。

所以更准确地说,它不是从零发明了一套全新的“记忆”概念,而是在原有文件记忆之外,又补了一层自动化能力。

如果用一句比较直白的话来区分:

  • 文件记忆,像是你自己整理的知识库
  • memory-tencentdb,像是一个自动做会议纪要、专题归档和人物画像的助手

两者目标有重叠,但手法不一样。


它内部到底怎么工作?

这个插件的 README 里把它分成了四层,我觉得这个拆分是有意义的。

L0:原始对话层

最底层先做一件很朴素的事:把对话录下来。

它会把每轮对话保存到本地,通常会双写:

  • JSONL 文件
  • SQLite 数据库

这层像原始流水账,不做太多判断,先把事实保住。

L1:结构化记忆层

有了原始对话之后,插件会调用模型,从里面提取“值得长期保留的信息”。

比如:

  • 用户喜欢简洁直接的回复
  • 用户偏好先确认能力边界再决定修复路径
  • 某次对话里决定把运行时切到 Node 24
  • 某个插件必须支持 FTS5,而不是仅仅降级跳过

这一步已经不是“记录”,而是“提炼”。

L2:场景归纳层

L1 记忆条目多了之后,插件还会继续往上抽象,把零散的事实组织成场景块。

比如:

  • OpenClaw 插件兼容修复
  • 记忆系统改造
  • 国际物流内容生产与发布流程

这样后面召回的时候,就不只是零碎句子,而是能带回一个相对完整的上下文场景。

L3:用户画像层

再往上,就是更稳定的用户画像。

这一层不关心某一条消息,而关心这个人长期表现出来的习惯、偏好、工作方式和决策风格。

比如:

  • 更重视真实根因,不满足表面止血
  • 偏好低侵入、可回退、可降级的方案
  • 交流风格简洁直接
  • 先验证能力边界,再推进改造

你会发现,到了这一步,已经很接近“长期认知模型”了。


它为什么不只是“记住聊天记录”?

因为真正有用的记忆,从来不是“把所有消息无限堆起来”。

单纯归档聊天记录,当然有价值,但问题也很明显:

  • 信息量大
  • 召回成本高
  • 很多内容其实不值得长期保留
  • 真正需要的时候,很难快速拿到有用部分

memory-tencentdb 的价值,在于它不是只存原文,而是做了一条链路:

原文 → 结构化记忆 → 场景 → 用户画像 → 自动召回

也就是说,它不是“多存一点”,而是试图把存下来的内容变成后续真能用的上下文。


它具体怎么装?

安装命令其实很直接:

openclaw plugins install @tencentdb-agent-memory/memory-tencentdb

装完以后,要重启 gateway:

openclaw gateway restart

如果只是看 README,到这里好像就完事了。

但我实际装的时候,问题正好出在“看起来很正常”的这一步之后。


真正的坑:不是插件装不上,而是 FTS5 不可用

我一开始装完插件,日志里出现了一条关键信息,大意是:

  • FTS5 tables NOT available
  • no such module: fts5

这说明插件启动了,但它依赖的 SQLite FTS5 全文检索能力并没有真正可用。

这里得解释一下,FTS5 是 SQLite 的全文搜索模块

如果没有它,插件虽然不是完全不能跑,但很多基于关键词的搜索、全文检索能力就会打折,整个记忆系统的实际效果会差不少。

问题的关键不在“SQLite 是不是存在”,而在于:

当前 Node 运行时里绑定的 node:sqlite,到底有没有把 FTS5 编进去。

这就是这次排查真正绕进去的地方。


为什么 Node 版本会影响 SQLite FTS5?

很多人会以为 SQLite 是系统层面的东西,装了就是装了。

但在 Node 里,情况没那么简单。

memory-tencentdb 用的是 node:sqlite。这意味着它依赖的不只是系统有没有 SQLite,而是Node 自己打包或绑定出来的 SQLite 能力集

结果我这边在 Node 23 环境下测出来的结论是:

  • sqlite_compileoption_used('ENABLE_FTS5') = 0
  • CREATE VIRTUAL TABLE ... USING fts5 直接报错

换句话说,问题不是插件 SQL 写错了,也不是配置不对,而是当前 Node 23 这套 node:sqlite 本身就没有 FTS5。

后来再核了一轮资料,也印证了这一点:Node 23 这边不行,Node 24 才真正能跑通。


这个插件依赖什么?

如果看它现在的依赖,核心有三个:

1)node:sqlite

这是整个本地记忆存储的基础。

它负责:

  • 本地 SQLite 数据库
  • 记忆和对话索引
  • FTS5 全文搜索

现在这部分要想稳定跑通,Node 24 基本已经是必要条件了

2)sqlite-vec

这个是 SQLite 的向量检索扩展。

它的作用是做语义相似搜索,也就是不只是按关键词搜,而是按“意思接近”去找内容。

如果后面配置了 embedding,这块会非常关键。

3)node-llama-cpp

这是本地模型相关的依赖。

它主要用在本地 embedding 和离线向量化这类能力上。

从插件定位来看,它明显是往“尽量本地化、尽量少依赖外部 API”的方向走的。

本地向量怎么来的

我这次实际触发过一次 warmup,确认它真的会拉起本地模型。

  • 模型名embeddinggemma-300m
  • 默认模型路径hf:ggml-org/embeddinggemma-300m-qat-q8_0-GGUF/embeddinggemma-300m-qat-Q8_0.gguf
  • 下载落点~/.node-llama-cpp/models/hf_ggml-org_embeddinggemma-300m-qat-Q8_0.gguf
  • 向量维度:768
  • 上下文窗口:256 tokens(代码里按 512 字符做了保守截断)

我这台机器上,第一次 warmup 的表现是:

  • 先下载了约 328.58MB 的模型
  • 下载过程用了大约 9 秒
  • 加上加载和创建 embedding context,15 秒左右就进入 ready

这也说明它不是“写死只做关键词检索”,而是可以在本地直接把文本转成向量,再交给 sqlite-vec 做检索。

是否可配置

这块要分两层看:

  • 当前对用户暴露的配置:主要是远端 embedding(apiKey / baseUrl / model / dimensions
  • 本地 embedding 的模型路径和缓存目录:在代码里可以改成别的 modelPath / modelCacheDir,但默认配置里没有把这个本地开关直接暴露出来

所以对普通使用者来说,最简单的理解是:

  • 不配远端 embedding → 默认走本地 node-llama-cpp
  • 想换本地模型 → 目前要改代码里的默认值,或者等后续把本地参数开放出来

另外还有一个细节很重要:我们最后把这个插件的 Node 版本要求收紧到了:

"engines": {
  "node": ">=24.0.0"
}

这不是装样子,而是因为前面已经验证过:

  • Node 23:FTS5 不成立
  • Node 24:node:sqlite + FTS5 可以正常工作

既然真实边界已经清楚了,就没必要再装作“22+ 都差不多”。


这个插件现在是怎么接入 OpenClaw 的?

从插件代码看,它主要挂了两个关键时机:

1)before_prompt_build

在模型真正开始回答前,它会先做自动召回。

也就是:

  • 读当前用户输入
  • 去检索相关记忆
  • 把召回结果注入到这轮上下文里

这一步决定了 AI 是不是能“在回答前想起该想起的东西”。

2)agent_end

一次对话结束后,它会做自动捕获。

也就是:

  • 记录 L0 原始对话
  • 通知调度器
  • 后续按条件触发 L1 / L2 / L3

这个设计我觉得挺合理,因为它把“回忆”和“沉淀”拆开了:

  • 回忆在回答前
  • 沉淀在回答后

这比把所有事情都堆到一个钩子里干净得多。


它实际能给 OpenClaw 带来什么?

如果只讲概念,会很空。我更愿意直接讲实际效果。

第一,跨会话连续性更强

以前很多信息如果不手工写进记忆文件,下一轮对话就未必接得住。

现在插件能自动把一部分内容沉淀下来,后面检索和召回会自然很多。

第二,原始对话不再只是“看过就没了”

很多系统只能记住你手工整理后的结论,原始对话本身很难重新利用。

这个插件把 L0 保留下来,相当于保住了原始语料和证据层。

第三,记忆不再只是“关键词堆积”

如果只有文件记忆,很多时候你知道信息在,但得靠你自己组织结构。

而这个插件多做了几步提炼,把它往“可自动使用的长期记忆”方向推了一把。

第四,给未来的自动化留了空间

尤其是 embedding、向量搜索、scene block、persona 这些东西,一开始你可能感受没那么强,但它们决定了系统以后能不能继续往上长。


它有没有边界?当然有

我并不觉得这种插件一装上就万事大吉。

它有几个很现实的边界。

1)自动提取不代表一定提得对

模型提炼记忆,总会有噪音、偏差、过度概括的问题。

所以自动记忆体系再强,也不能完全替代人工可控的结构化记忆。

2)召回越强,不代表越好

记忆系统最怕的不是“记不住”,而是“乱想起”。

如果召回机制不克制,过期信息、边缘信息、无关信息都混进来,反而会污染上下文。

3)底层能力边界不能装作不存在

这次 FTS5 就是最典型的例子。

很多时候问题不是“调一调配置就好”,而是底层能力根本没成立。

如果不先把这件事弄清楚,后面的所有优化都只是表面文章。


这次折腾下来,我对它的真实判断

如果让我现在给 memory-tencentdb 一个不吹不黑的评价,我会这么说:

它不是 OpenClaw 从 0 到 1 必不可少的那块底座,但它是把 OpenClaw 从“有记忆”推进到“有自动化长期记忆流水线”的关键增强层。

也就是说:

  • 没有它,系统并不是完全没有记忆
  • 但有了它,记忆从“靠人维护”往“能自动沉淀、自动召回”走了一大步

前提是,你得先把运行环境搞对。

尤其是现在这版结论已经很明确:

  • 想让它正常用 FTS5,就别在 Node 23 上耗时间了
  • 直接上 Node 24
  • 确认 node:sqlite 真支持 FTS5
  • 再让 gateway 跑起来

这才是省时间的路径。


如果你也想装,最短路径建议

按我这次的经验,最短路径是这样的:

第一步:确认 Node 版本

先确认自己不是旧环境,至少直接上 Node 24。

第二步:安装插件

openclaw plugins install @tencentdb-agent-memory/memory-tencentdb

第三步:重启 gateway

openclaw gateway restart

第四步:检查日志

重点不是只看有没有报错,而是看下面这类关键信息:

  • 是否使用 node:sqlite
  • 是否显示 FTS5 available
  • 是否成功初始化 FTS5 表

如果这里没成立,后面很多功能就只是“看起来装上了”。


最后一句

我现在越来越觉得,真正难的从来不是“给 AI 加一个记忆插件”,而是:

  • 你要先知道它记什么
  • 你要知道它靠什么记
  • 你还得知道它什么时候其实根本没记住

memory-tencentdb 值得装,但前提是别把它当成一个“装完就自动变聪明”的插件。

它更像是一套记忆基础设施。

基础设施这个东西,真正有价值的时刻,往往不是你第一次装上的时候,而是你后面连续跑了很多天,发现系统终于开始有点“接得住上下文”了。