☰
claude-mem:基于MCP和SQLite,为Claude打造跨会话持久记忆
2026/10/7 23:43:21 网站建设 项目流程

我先说一个很现实的问题:哪怕你天天在用 Claude Code,它也记不住你昨天让它改过的代码。每次新开一个会话,它都像第一次见到你一样,客客气气问“请问你想让我做什么”。对一次性提问没影响,但对跨天的项目、连续的调试、长期的技术方案来说,这个“失忆”真的能把人逼疯。我在 GitHub 上看到 claude-mem 这个开源项目的时候,第一反应是:终于有人把这件事做成正经工具了。

claude-mem 是一个给 Claude 提供持久记忆的 MCP 服务器,底层用 SQLite 存数据,Claude 可以在会话过程中主动往“记忆库”里写东西,下次新会话再把这些内容捞回来用。它解决的不是“多轮对话里能不能记住上文”,而是“跨会话、跨项目、跨时间,Claude 能不能像老同事一样记得你的偏好和项目脉络”。这篇文章我会把它的原理、安装配置、实际使用中的坑,以及我对它边界的真实感受都写一遍,适合正在用 Claude Code、或者想把 Claude 用在长期项目里的朋友参考。

1. Claude 没有记忆,不是简单的“忘了”

1.1 三个让我崩溃的真实场景

先具体说一下被“失忆”折磨的过程。

第一个场景发生在一次 API 服务重构里。我第一天下午让 Claude Code 把某个模块从 Flask 改成 FastAPI,并且把路由风格统一成 RESTful 规范,当时它做得挺好。第二天早上我想让它接着改下一个模块,于是新开了一个会话,结果它来了一句:“我没有看到你之前改过的代码,请告诉我哪个文件需要处理。”我不得不把整个项目结构、改动范围、第一天定下的规范重新贴一遍。等于第一天下午讨论出来的东西,第二天全清零。

第二个场景跟个人偏好有关。我写 Python 的时候有一个非常具体的习惯:import 必须按 stdlib、第三方、本地模块分组,类注释写特定格式,异常处理宁可多写一个 logger 也不静默吞掉。这种偏好我几乎每隔几天就要重新跟 Claude 解释一次。一次两次还能忍,时间长了真的烦躁。明明这些规则完全具备“沉淀”的条件,但每个新会话都是白纸一张。

第三个场景最坑,是跨会话的技术决策反复。一个项目进行到中期,我让 Claude 在前端技术选型上给个结论。第一天它建议用状态管理库 A,第二天我发现库 A 的学习成本太高,让它换库 B,到了第三天它又建议回到 A,因为它根本不知道第二天我们已经推翻过 A。这种“忘记自己在上一轮已经拍板过什么”的问题,会让项目在同一个坑里反复横跳,个别情况下还会越改越乱。

这三个场景是 claude-mem 诞生的最直接动机:Claude 本身是强大的工程师,但它没有“项目记忆”。你给它上下文,它就能干活;你不给,它就只能靠猜。

1.2 把提示词塞满 System Prompt,是条死路

有人可能会说:既然它记不住,那我每次把规则写进 System Prompt 不就行了?我确实试过,而且试了很久,这条路本质上走不通。

第一是成本问题。System Prompt 每轮对话都要作为输入 token 被计算,你塞 2000 字进去,短时间看着没事,连续聊几十轮之后,那是一笔很实在的开销。第二是稀释效应。当 System Prompt 里的背景信息越来越多,真正关键的任务指令就会藏在一堆冗长的偏好描述里,模型对相关信息的注意力反而不集中,回答质量会下降。第三是硬上限。Claude 的上下文窗口再大也是有限的,规矩、背景、示例、历史结论全堆在里面,迟早有爆的一天。到了那时候,最先被挤掉的反而是最重要的早期决策记录。

所以结论很清楚:把记忆硬塞进“对话上下文”不是可持续的方案。真正的记忆应该独立存在,需要的时候拿一部分出来用,用完了再放回去,而不是全程占着地方。

1.3 记忆不该放在“提示词”里,而该放在“记忆库”里

想明白这点之后,思路就变了。Claude 需要的不只是更长的上下文,而是一个可以在会话之外持续写入、持续读取的“外部存储”。这个外部存储要能满足几个条件:

  • Claude 在会话过程中能主动把重要信息写进去;
  • 新会话启动时能快速检索到相关内容;
  • 不会因为对话结束而丢失;
  • 读写成本足够低,不会严重影响对话效率。

这就是 MCP(Model Context Protocol)服务器最合适的用武之地。MCP 可以理解成一个标准化的“外部工具接口”,Claude 这种模型客户端不需要知道记忆具体存在哪里,只需要通过协议调用工具,就能完成“存一条记忆”“查一批记忆”的操作。claude-mem 正是以 MCP 服务器的形态出现的,这也是它在设计上最聪明的地方——它不尝试改造模型本身,而是给 Claude 接了一个独立于会话的“外脑”。

2. claude-mem 的“记忆”到底是怎么实现的

2.1 它不是一个聊天框,是一个 MCP 服务器

很多第一次接触这个工具的人会误解,以为 claude-mem 是个聊天界面或者插件。它不是。它是一个独立运行的进程,通过 MCP 协议和 Claude Code 这类客户端进行通信。

你可以把 MCP 想象成 USB-C 接口:设备只需要遵循同一个标准,就可以接上各种不同的外设。Claude Code 是设备,claude-mem 就是接上去的“记忆外设”。Claude 在对话中会收到一组额外的工具,比如“保存记忆”“搜索记忆”“获取记忆概览”,当它判断当前信息值得记住时,就会主动调用这些工具写入数据库;当它需要回顾过去的上下文时,就通过搜索工具把相关记录拉回来。

这个设计有个直接好处:记忆的读写是和具体对话解耦的。你在会话 A 里写入的内容,会话 B 完全可以读到,因为它们共用同一个 SQLite 数据库,而不是共享同一段上下文。

2.2 记忆库里到底存了哪几类东西

我实际用过之后,发现 claude-mem 的记忆组织方式可以大致分成几类:

  • 用户偏好:比如代码风格、命名习惯、常用工具链、回答问题的语气。这类信息通常具有全局性,任何项目都能用。
  • 项目事实:比如某项目采用了什么架构、模块之间怎么依赖、哪些目录是核心代码。这类信息服务于特定项目的长期维护。
  • 会话摘要:每个会话结束或被触发时,系统会生成一段摘要,记录这个会话里完成了什么、决定了什么、遗留了什么。

这些内容不是混成一团的,而是按一定的结构和标记存进 SQLite,方便后续搜索和过滤。从使用体验上说,Claude 在收到一个跨会话任务时,会先去查项目事实和用户偏好,而不是一股脑把所有历史消息翻出来。

2.3 写入和读取的完整链路

我跑起来之后观察它的行为,整个过程大概是这样的:

在会话过程中,Claude 如果确认了一条值得长期保存的信息(比如“项目使用 pnpm 作为包管理器”),它会调用一个类似“记忆保存”的工具,把这条信息写入数据库。这个写入动作不是存储整段对话文本,而是存储经过提炼的内容。这也是 claude-mem 区别于简单“聊天记录回放”的地方。

新会话开始后,Claude 会根据当前项目目录、用户身份等信息,主动读取一部分记忆概览,再把与当前任务相关的记忆通过搜索工具捞回来。这里面的搜索逻辑很关键——它不是拉全部记忆,而是按 relevance(相关度)挑有用的。

有一次我让它继续处理一个三天前的任务,我只是说了句“继续我们之前讨论的方案”,它竟然直接把我三天前记录的“API 版本兼容策略”写进了回答里。那一刻你会明显感觉到,多个会话之间的信息终于串起来了。

2.4 为什么用 SQLite 而不是一个 JSON 文件

有人会问,记一点东西而已,直接存成 JSON 文件不也行吗?我从实际使用角度来说,SQLite 的优势非常明显。

首先是搜索效率。记忆量一旦过百条,线性扫描 JSON 文件和数据库索引检索的差距是可怕的。其次是并发安全。Claude Code 可能有多个会话同时运行,如果都往同一个 JSON 文件里写,极容易出现互相覆盖的问题。SQLite 对并发写有成熟的处理机制,不容易写坏。

还有一个很多人想不到的好处:SQLite 文件可以直接用sqlite3命令行打开。想查库里到底存了什么、有没有存错,把表数据拉出来看一清二楚,不用专门写管理界面。这对一个开发者工具来说,是很有价值的可观察性。

3. 从零跑起来:安装、配置、首次落库

3.1 安装之前的准备

在装 claude-mem 之前,我建议你先确认两件事。第一,你已经安装了 Claude Code CLI 并且登录了账号,毕竟工具是给 Claude 客户端用的,没有客户端装好也无从验证。第二,本机有 Python 环境,因为 claude-mem 本身是用 Python 写的,官方推荐的启动方式是uvx。如果你之前完全没装过 uv,可以先装一下,它本质上是一个 Python 包管理器,用来快速运行 claude-mem 这个命令。

准备好之后,最直接的方式是通过 Claude Code 自带的 MCP 注册命令把服务器加进去。大致命令就是:

claude mcp add claude-mem -- uvx claude-mem

这条命令的含义是:让 Claude Code 知道有一个叫 claude-mem 的 MCP 服务器,启动方式是用uvx运行claude-mem。如果你本机的uvx不在 PATH 里,注册之前最好先跑一下which uvx确认能找到,不然后面会出一堆莫名其妙的问题。

3.2 项目级配置还是全局配置,要提前想清楚

claude-mem 支持按项目注册,也可以做全局配置。这一步很多人一开始没在意,后面才来后悔。

如果你希望每个项目都有独立的记忆库,那就在进入项目目录之后再执行注册命令,这样配置会被写入当前项目的.mcp.json文件,只在当前项目里生效。如果你希望所有项目共享一套偏好(比如代码风格、工具链偏好),那就在用户配置层面注册,这样任何项目都能读到全局记忆。

我的建议是:偏好类信息走全局,项目事实走项目级。这样既能享受记忆带来的连续性,又不会出现“项目 A 的架构信息出现在项目 B 的对话里”这种串味情况。这个决定后续改起来稍微有点麻烦,但也不是不能改,关键是先想清楚。

3.3 非 Claude Code 客户端的配置写法

如果你用的不是 Claude Code,而是 Claude Desktop 或者其他支持 MCP 的客户端,配置方式也类似,只是改配置文件而已。Claude Desktop 的配置一般在一个叫claude_desktop_config.json的文件里,需要把 mcpServers 这一段加进去:

{ "mcpServers": { "claude-mem": { "command": "uvx", "args": ["claude-mem"] } } }

这段配置的意思是告诉客户端:遇到 claude-mem 这个服务器时,就用uvx claude-mem把它启动起来。不同客户端加载配置的位置不太一样,但结构基本都是这个模式。配置完记得完全退出客户端再重启,因为 MCP 服务器的加载发生在启动阶段。

3.4 第一次写入记忆,验证工具真的在工作

配置好之后,别急着干嘛,先做一个验证测试。运行一个简单的任务,例如:

  • 让 Claude 记住一个事实:“我的项目使用 Rust 编写,模块划分遵循 Cargo workspace 规范。”

等它执行完,我们去数据库里看看有没有真的写进去。claude-mem 的数据库位置一般在用户目录下的.claude-mem目录里,也就是~/.claude-mem。打开终端执行:

sqlite3 ~/.claude-mem/memories.db ".tables" sqlite3 ~/.claude-mem/memories.db "SELECT * FROM memories;"

如果能看到刚才让 Claude 记住的内容,说明整条链路已经通了。然后你新开一个会话,不用重复任何背景,直接问它“我们项目的模块划分是什么样的”,它如果能答出来,那就说明 claude-mem 真正起作用了。

4. 跑了两个月之后,我踩过的配置坑

4.1 MCP 工具没暴露,Claude 完全不接茬

第一次安装完,我以为配好就完事了,结果新会话里 Claude 就是不用记忆功能。我让它“查一下之前记录的项目偏好”,它回了一句“我之前没有和你聊过这个话题”。

后来排查发现,问题出在运行中的会话没有重新加载 MCP 配置。Claude Code 的 MCP 服务器是在会话启动时被加载的,我是在会话中途注册的 claude-mem,当前会话压根不知道有这个工具。解决方式很简单:完全退出 Claude Code,再重新启动,然后在对话里输入命令看看工具列表里有没有 claude-mem 相关的工具。如果你用的是 Claude Desktop,同样要彻底退出再重进。

这个坑非常典型,不是 claude-mem 的问题,而是 MCP 这套机制的工作方式问题。遇到“配置了但没用上”的情况,第一件事永远是重启客户端,不是怀疑配置写错了。

4.2 uv 环境路径问题,让服务器启动失败

另一个高频问题出在uvx命令。Claude Code 通过配置文件启动 MCP 服务器时,它继承的 PATH 不一定跟你终端里一样,很多时候 GUI 应用或某个服务进程的 PATH 特别精简,根本找不到uvx在哪里。

表现就是:配置看起来没毛病,但 claude-mem 一直启动失败,日志里提示找不到uvx或类似的可执行文件。

我当时的解决办法是,先执行which uvx拿到它的完整路径,然后把它写进配置文件的 command 字段里,也就是:

{ "mcpServers": { "claude-mem": { "command": "/Users/你的用户名/.local/bin/uvx", "args": ["claude-mem"] } } }

这样客户端就不依赖 PATH,直接按绝对路径启动。这个问题在 Linux 和 macOS 上都很常见,Windows 大概率的坑点也类似,建议直接用绝对路径,省得后续反复排查。

4.3 多个项目共用一个记忆库,信息串味了

全局注册用了一阵子之后,我发现“串味”问题很严重。我在项目 A 里让 Claude 记住了“数据库表结构是 X”,结果跑到项目 B 里问它任何问题,它也会莫名参考这些跟 B 毫无关系的信息,回答甚至被带偏。

说到底,Claude 自己在判断相关度时,并不能保证 100% 区分清楚哪些记忆属于哪个项目。这个问题的本质是记忆库应该按上下文隔离。我现在用的方式是:项目事实尽量在项目目录下做配置,让每个项目有独立的记忆库;用户偏好这种没有冲突风险的,才放到全局库。如果你想偷懒,也可以做多套 MCP 配置,按项目切换,只是稍微麻烦一点。

空间隔离不是什么高深概念,但真的很重要。记忆串了味,比没有记忆更让人难受。

4.4 自动生成的摘要太啰嗦,信息密度反而下降

claude-mem 会在会话结束或者关键节点生成摘要,这个功能听起来很智能,实际用的时候需要注意控制粒度。我早期遇到过它把一次简单的“改了几行配置”的对话,生成了几百字的摘要,里面全是我当时讨论过程留下的细枝末节。等下次查询时,Claude 把这种低质量摘要当线索用,结果不仅没帮助,还把真正重要的决策记录给淹没了。

后来我调整了使用方式:不是让它随意记录所有对话,而是只让它记录明确的决策和结论。我会在对话中主动说类似“把这条保存下来:我们决定用 PostgreSQL 而不是 MySQL”这样的指令,把它当成一个需要显式调用的记忆接口来用。这样落库的内容精准很多,搜索召回的质量也明显提升。

任何记忆工具,都需要有人替它判断什么值得记。这个判断目前还不能完全交给模型,该手动的时候别偷懒。

4.5 隐私和敏感信息,千万别写进记忆库

这一点我要单独拿出来提。记忆库是明文的 SQLite 文件,位置就在你本地目录下。虽然比云端存储安全,但也意味着所有能访问你机器的人都读得到。密钥、内部 IP、用户身份证这类敏感信息,绝对不要让 Claude 存进记忆库。

有一次我不小心让 Claude 记住了一条包含了内部服务端口和调试账号的信息,事后清理时费了不少劲。从那以后我的做法就两条:第一,在对话里明确说“不要保存敏感信息”;第二,定期打开数据库文件看一眼,发现问题立刻删除对应记录。工具本身不会替你判断哪些内容敏感,这个责任只能自己扛。

5. 实际工作流中,我是这样用它的

5.1 把架构决策记录“喂”给记忆库

现在我在每个长期项目里,都会刻意让 Claude 把关键决策记下来。比如“为什么这个模块不用消息队列而用 HTTP 轮询”“为什么接口采用版本号前缀而不是 header 传递”,这些决策背后的原因如果脱离了上下文,隔两周再看可能完全看不懂。

我现在会让 Claude 在讨论出结论后,顺手执行一条保存操作,把结论和理由存进项目记忆库。这个做法的效果是:一个多月后我再开新会话处理同类问题时,Claude 能直接引用当初的决策依据,而不是又把方案从头推演一遍。这个体验真的是“老同事”级别的体验。

5.2 写作场景:术语表和语气偏好

我除了写代码,平时也会让 Claude 帮忙做技术写作和文档润色。这个场景对“记住偏好”的需求同样强烈。

比如我的写作风格要求:中文技术文档尽量用短句,不堆名词,术语第一次出现要加英文缩写,语气偏克制不夸张。以前每写一篇新文档,我都要重新复制粘贴一遍风格要求。现在只需要第一次写清楚,然后让它保存为偏好,之后所有写作任务都会自动带上这个约束。

对于固定团队的文档,这个功能还能解决风格统一问题。团队里只要有人把风格规范导入了记忆库,后续成员用同一个库时,写出来的文档就不会出现风格漂移。

5.3 让代码规范从“贴进提示词”变成“查记忆库”

在团队项目里,代码规范通常写在文档里,但 Claude 不会自己去看文档。以前的做法是把规范粘贴进对话上下文,既占 token,又容易因为太长让模型抓不到重点。

现在我会把代码规范拆成一条一条的“记忆条目”让 Claude 记住。比如:

  • 项目错误处理统一使用全局异常类;
  • service 层禁止直接操作数据库;
  • 所有 API 响应结构统一为{ code, message, data }。

新会话一启动,Claude 不需要我重新贴规则,它会主动查项目记忆来对齐这些约束。有一次我让它写一个新的 service 类,它居然自己引用了“service 层禁止直接操作数据库”这条记忆来设计方案,那一刻我确实觉得这工具值回票价了。

5.4 记忆库也是会过期的,定期要清

很多人以为记忆库是“永久有效的”,实际不是。项目会迭代,技术方案会调整,偏好也会变化。如果库里存着一堆三个月前的过时信息,Claude 查询时可能优先拿旧信息当依据,反而帮倒忙。

我现在每隔一段时间会打开~/.claude-mem/memories.db看一眼,把明显过时的记录删掉或更新。这个习惯一开始觉得繁琐,时间久了你会发现这是整个记忆系统保持有效性的关键。记忆不是越全越好,而是越准确越好。

6. token 成本、性能和它的边界,这里有个真实账

6.1 prompt 缓存确实帮了大忙

我刚开始担心一个问题:有了记忆库之后,Claude 每次启动新会话都要读一堆记忆,token 消耗会不会爆炸?

实际跑下来,情况还好,原因是 claude-mem 上了 prompt caching 的思路。记忆内容会命中缓存,不会像普通系统提示词那样每轮都全额计费。加上它有摘要机制,不会把几十条原始记录全部塞进上下文,而是先按需搜索再注入,所以单次消耗整体可控。

我自己的经验是:会话启动时它会拉一批概览信息,这部分是固定开销;真正动态消耗在于搜索动作命中了多少条记忆,而这个数量是可控的。

6.2 记忆条目不是越长越好,300 字是一个好上限

用了一段时间之后,我自己总结出一个铁律:单条记忆尽量控制在 300 字以内。

原因很简单,Claude 搜索记忆时是按照相关度召回若干条,如果每条记忆都写得又长又啰嗦,召回少量条目就把上下文塞满了,反而装不下更有用的信息。真正高质量的记忆条目,像便利贴一样短:一句结论,一个原因,就够了。

比如与其让 Claude 记住“我们讨论了三天,最终决定在订单服务中使用 PostgreSQL,因为团队最熟悉它,且运维成本低”,不如直接记“订单服务使用 PostgreSQL,理由:团队熟悉、运维成本低”。信息量几乎一样,但后者占的空间小太多。

6.3 什么样的人不适合用 claude-mem

说了这么多好处,我也得说点实话:这个工具不适合所有人。

如果你的 Claude 场景是“问一次就不用了”的零散问题,比如临时翻译一段文字、写个一次性脚本,那确实没必要上记忆功能,配置成本大于收益。记忆工具是为“长期、重复、有上下文依赖”的使用模式设计的,把单次任务硬套上记忆,属于画蛇添足。

另外,如果你的使用环境对数据安全要求极高,比如禁止任何形式的本地持久化存储,那 claude-mem 默认的“明文 SQLite 落盘”机制显然不合适。这种场景不是工具不好,而是场景不匹配,没必要硬上。

我个人对 claude-mem 的真实评价是:它把 Claude 从“每次都是陌生人”变成了“记得你习惯的老队友”。它不是能帮你解决所有问题的银弹,但对于长期项目和持续创作的人,它能消除的重复沟通成本,远大于配置它花掉的那点时间。

最后再分享一个小习惯:我每个周末会花五分钟,把 claude-mem 记忆库里这一周的记录扫一遍,删掉过时的、修正错误的、合并重复的。这个习惯看着很小,但效果非常明显——它能让记忆库保持“高效且可信”,而这恰恰是任何外部记忆系统最核心的价值。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询