用过 Claude Code 的人,十有八九都有过这样的憋屈时刻:上午明明已经告诉它“这个项目统一用 pnpm,锁文件别乱动”,下午新开一个会话,它又一脸茫然地问你要不要用 npm。你重复了三遍的代码规范、环境变量、部署流程,它永远像金鱼一样七秒记忆。这不是模型不够聪明,而是对话式 AI 天然缺少一条跨会话的“记忆神经”。我为了解决这个问题折腾过各种方案,最后找到了 claude-mem——一个专门给 Claude 补上长期记忆的开源工具,也是今天这篇博文的主角。它能自动从对话里抽取关键信息,存成结构化记忆,下次会话直接调用。无论你是拿 Claude Code 写代码、跑自动化脚本,还是拿它做文档整理,只要来回切换会话比较频繁,这个工具都能帮你省掉大量重复沟通的成本。
1. 为什么会做这么个工具:AI 记忆的痛点在哪
1.1 会话隔离是原罪
所有大模型产品的底层都是“无状态”的。每次你发起对话,模型看到的只是当前会话里这些上下文,之前的会话、之前的项目历史,它一概不知。所谓“记住”,其实是靠你在对话里不断重复喂给它。这种设计在聊天场景下没问题,但在真正干活的时候就成了大麻烦。尤其是 Claude Code 这种深度嵌入工作流的终端工具,你可能会开十几个会话处理不同任务:一个写后端接口,一个做前端页面,一个在排查 CI 报错。它们之间完全隔离,掌握的上下文互不相通。
我在实际使用中最直观的感受是:项目里有些约定俗成的东西,根本不在代码里,只在脑子里。比如“数据库迁移脚本不能直接跑在线上环境”“测试环境要用 mock 的支付回调地址”“这个仓库存放在 monorepo 的 packages/shared 目录下”。每次开新会话,我都得像念经一样重新交代一遍。更烦的是,如果哪次忘了说,它就可能按照最常规、最普适的做法去处理,然后产出一个和项目风格完全不一致的代码。
1.2 那些“说了就忘”的真实场景
我举几个自己踩过的具体例子。第一个是技术栈约定。我有个项目前端用 Vue 3 的<script setup>写法,禁用了 Options API。头一天告诉 Claude Code 之后,它写得挺好;第二天换个会话让它加个页面,它直接给你整出export default { data() { ... } }的老写法。不怪它,是它确实“不记得”了。
第二个是常用命令和路径。项目里有个内部 CLI 工具,路径是./scripts/dev-tool.sh,启动参数很怪。这工具在会话里提到过一次,但下次会话它忘了,还会自作主张地建议你npx dev-tool,然后你得到一个 command not found。
第三个是配置文件的坑。.env.example里有个VITE_API_BASE_URL需要指向 staging 域名,这种信息在团队 wiki 里写着,但你没法每次都贴给 AI 看。它一旦不知道,就可能生成指向 localhost 的接口代码,让你的联调崩溃。
1.3 claude-mem 到底解决什么问题
claude-mem 的核心思路特别朴素:把“记忆”从模型的临时上下文里搬出来,落到本地持久化的存储里。它监听你和 Claude Code 的对话过程,在合适的时机(例如一轮对话结束)自动提取其中有保留价值的信息,整理成一条条记忆。这些记忆会存在项目本地,下次会话启动时,Claude Code 就会通过工具调用把它们加载回来。
我用下来感觉它解决的不是“模型记性好不好”的问题,而是“要不要一遍遍重复”的问题。你只需要在某个会话里说一次“这个项目用 pnpm”,它就变成一条记忆。之后任何新会话都自动具备这条知识。对于日常重复性的业务开发,这个价值极其明显:把 AI 从“聊天机器人”变成了一个有项目记忆的“长期协作者”。
2. 核心机制拆解:claude-mem 是怎么记住东西的
2.1 记忆的捕获:从对话流里截取关键信息
claude-mem 的工作方式非常依赖 Claude Code 的 hooks 机制。Claude Code 允许你在特定事件(比如每次模型回复结束)时触发外部脚本,claude-mem 就是利用这个“Stop hook”作为触发点。每当一轮交互结束,它会把当前会话的完整文本交给一个分析流程,从中抽取候选记忆。
这里有个关键设计:它不是把整段对话原样存下来,而是做“抽取式提炼”。我理解它内部有一个 Prompt 模板,会要求模型以特定格式输出记忆条目。常见的抽取维度包括:用户的明确偏好(“不要用 npm”)、项目技术决策(“我们用 Vite 而不是 Webpack”)、具体的工作流约定(“每次发版前要跑 lint”)、环境相关的事实(“生产环境数据库账号存在 1Password 里”)。这些维度的设定直接决定了记忆库质量的上限。
你说这不就是把对话丢给模型让它总结吗?没错,逻辑上确实是。但它的价值在于自动化:你不用手动复制、粘贴、整理,它全帮你做完了。而且你可以控制触发频率,不用每句话都存,通常几个来回才触发一次,成本和噪音都可控。
2.2 记忆的存储:Markdown 文件 + SQLite 索引
存储层是 claude-mem 另一个比较务实的设计。记忆最终会写入一个 Markdown 文件,通常放在项目目录下的.claude-mem文件夹里,主文件名一般是MEMORY.md。Markdown 的好处不用多说:人类可读、可直接编辑、能用 git 做版本管理。你完全可以打开这个文件,手工删掉某条过时的记忆,或者补充一条新的。
但纯文件存储有个问题——检索效率。当记忆数量涨到几百条,你想快速找到“和数据库相关的那条”,靠 grep 效率太低了。所以 claude-mem 同时维护了一个 SQLite 索引库,对每条记忆做了分词和全文索引。查询的时候,先走 SQLite 的 FTS 做全文检索,再把命中的 Markdown 片段返回给 Claude。这个设计思路类似一个极简版的笔记系统:文件是人能看懂的真相,SQLite 是给机器用的加速索引。
还有一点值得提,它的记忆条目本身可能有结构化的 meta 信息,比如创建时间、来源会话、标签。这些 meta 信息对后续的去重、排序、过期清理非常重要。我看它的存储结构时会觉得,这不像一个随手写的玩具,而是一个认真设计了数据模型的工具。
2.3 整理与去重:不让记忆库变成垃圾场
凡是搞过知识库的人都知道,收集容易整理难。claude-mem 如果只负责往 MEMORY.md 里堆内容,用不了多久这个文件就变成一坨没人看得下去的废料,Claude 也会被误导。所以它内置了一些记忆维护机制。
一个是相似度去重。新抽取出的一条记忆,会先和历史记忆做向量或文本相似度计算,如果发现内容高度重叠,就不会重复插入。我实际用下来,这种去重对“同一件事换个说法反复出现”的情况比较有效。比如第一次你说了“使用 pnpm”,第二次说“包管理器统一用 pnpm”,它不会存两条。
另一个是自动归档。记忆库里有些内容时效性很强,比如“当前正在解决的问题是登录接口 401”,这种信息过几天就没意义了。claude-mem 会通过定期总结或规则判断,把这类临时性记忆压缩掉,只保留那些长期稳定的事实。我以前没注意这个功能,导致记忆库膨胀到几百条,里面一半是过期信息。后来打开 MEMORY.md 才发现,整理得越干净,Claude 调用记忆时的表现越准确。
3. 安装与集成:把记忆装进 Claude Code
3.1 安装 claude-mem 的两种方式
claude-mem 的安装门槛很低。最常规的方式是直接用 Node 包管理器装,因为它本身是一个 CLI 工具,依赖 Node.js 运行时。你可以在全局装,也可以装在某个项目里。我个人的建议是全局安装一次,然后在需要启用记忆的项目里单独做初始化。命令很直白,就是npm install -g claude-mem。装完跑一下claude-mem --version,能输出版本号就说明环境没问题。
第二种方式是跑它自带的一条初始化命令,在项目目录里执行claude-mem init。这条命令会帮你生成必要的配置文件和目录结构,比如.claude-mem/文件夹、一个记录夹取频率的配置文件。如果你是第一次用,直接 init 比自己手动 mkdir 省事得多。初始化之后,你的项目里就多了一套私有的记忆仓库。
还有一点要注意,claude-mem 有几个可选依赖。比如它支持的记忆提取后端可以配置成调用 Claude API,也可以配置成本地的 Ollama。默认情况下它会走当前 Claude Code 所在的模型环境,也就是说不额外产生 API 费用。熟悉配置之后,你完全可以按自己的需求调整提取后端。
3.2 与 Claude Code 的 hooks 配置
安装完只是第一步,真正让它跑起来的关键在于把 claude-mem 的 CLI 命令注册成 Claude Code 的 hook。Claude Code 的配置通常在项目根目录的.claude/settings.json里。你需要在这个文件里定义一个Stop事件的后置命令,让 claude-mem 在每次对话停止时去执行一遍记忆提取。
具体的配置片段大致长这样:
{ "hooks": { "Stop": [ { "matcher": "", "hooks": [ { "type": "command", "command": "claude-mem capture" } ] } ] } }这里的matcher留空表示所有对话都触发。这是我建议初学者先用的配置。跑一段时间你想精细化控制,也可以填上特定的正则,只让某些类型的对话触发记忆捕获。总之,注册好 hook 之后,claude-mem 才算是真正接入了你的开发流。如果漏掉这一步,装了半天它也只是个空转的 CLI。
配置完成后,我建议你立刻做一次验证。随便开一个会话,对 Claude Code 说一句“从今往后,这个项目的代码风格统一使用函数式组件”,然后结束对话。再去查看.claude-mem/MEMORY.md,如果能看到这条信息的相关记录,就说明整套链路已经通了。
3.3 递归记忆与跨项目记忆的边界
claude-mem 默认的记忆范围是当前项目。每个项目有自己独立的记忆文件,这能有效避免“项目 A 的技术栈约定串到项目 B”的混乱。但是有些内容可能是通用的,比如“我习惯用双引号不用单引号”“我写的提交信息要带 Jira 单号”。这类个人偏好如果只存在某个项目里,换个项目就又忘了。
我的处理方式是把 claude-mem 的记忆目录按两层来理解:项目级记忆和个人级记忆。项目级记忆随着项目走,跟着 git 仓库走,团队成员拉下来也能共享。个人级记忆则存在你的用户目录下,专门存放跨项目普适的偏好。claude-mem 在初始化的时候会让你选存储位置,我建议你认真审视一下哪些内容该放哪一层。
交叉使用的时候注意一点:当你同时开了多级记忆,Claude Code 加载记忆时会把两层内容都带进上下文。如果两层内容出现了矛盾条目,模型的判断可能被干扰。所以隔一段时间清理个人记忆里的过期约定,跟清理项目记忆一样重要。
4. 实操:记忆的查看、搜索与清理
4.1 查看全部记忆:清单会暴露你的习惯
开箱之后,很多人会好奇自己的记忆库里到底存了什么。命令很简单,claude-mem --list就能把当前项目的记忆条目全部列出来。我第一次执行的时候发现它已经存了三十多条,里面有几条我自己都快忘了。这其实是个很有意思的“元认知”过程:你会看到自己在日常工作中反复强调什么、最在意什么。
清单输出通常是分条展示的,每条记忆有编号、创建时间、内容摘要。如果内容太长,它只显示一个摘要,不会把整个记忆体塞满终端。这条命令最大的用途是帮你快速确认“它记住了哪些东西”,从而判断记忆库的质量是否正常。如果发现大量重复或无关内容,就该考虑清理了。
我习惯于在每周五下午跑一次claude-mem --list,快速扫一遍这周积累的记忆。看到过时信息就顺手清掉,看到表达混乱的就手动改。这十分钟的维护工作,比后续让 Claude 带着一堆垃圾记忆干活要划算得多。
4.2 按关键词搜索:把记忆变成可检索的增量知识
记忆库最大的优势是可检索。当你想确认“之前有没有讨论过日志格式的问题”,不需要翻聊天记录,直接claude-mem --search 日志格式就行。这个搜索走的是 SQLite 全文索引,聊胜于 grep,速度非常快。搜索结果的展示会带上记忆条目的上下文片段,方便你判断哪一条才是自己要的。
我发现这个搜索功能在日常开发中最实用的场景其实是“找回失散的技术决策”。比如半个月前我们讨论过为什么用tsx而不是ts-node,当时没来得及记到正经文档里,但我记得跟 Claude 说过几句话。这种情况下,搜索引擎比文档还靠谱,因为它保存的是当时对话里的原始表达,包含了决策动机,而不像文档那样总是一版一版地精简。
搜索还有个用法你可能想不到:它能把 Claude Code 从“遇到问题只会给通用答案”变成“遇到问题先查历史经验”。比如你问它“这个项目怎么跑测试”,它如果搜到了记忆里“测试要用 vitest 且要带上--run参数”,回答就会比那种泛泛的“运行 npm test”准确得多。
4.3 删除错误记忆与手动修整
没有任何工具能保证自动抽取出来的记忆百分百正确。我也遇到过它把一句玩笑话当成正经偏好存了下来,比如我随口说“再也不要用 less 了”,它就把“禁用 less”记录在案。这种误存如果不及时清理,会影响后续所有会话的判断。
删除命令是claude-mem --forget <记忆编号>。先--list找到编号,再执行删除,两步就能完成。这个命令的作用是同时删除 SQLite 索引里的记录和 Markdown 文件里的对应条目,保持两边一致。实际用下来删除很干脆,不会有残留脏数据。
除了删除,我也经常直接手改 MEMORY.md。claude-mem 设计得比较放心的一点是它不怕你手工改,甚至鼓励你手工维护——文件就是最直接的真相。你可以在文件里手写一条新记忆,下次 Claude 加载时同样能读到。我觉得这种“系统自动提取 + 人工兜底修正”的组合,是平衡效率和准确度的好方案。完全依赖自动提取是不可能高可靠的,毕竟语言理解的边界太宽。
4.4 记忆合并与压缩的时机
记忆库维护不只有增删,还有合并。比如你一开始记住的是“测试用 vitest”,后来又记住了“测试命令要加 --coverage”,这两条逻辑上可以合并成一条“测试用 vitest 且带覆盖率参数”。分开存倒也不会出错,但会让记忆数量虚高,让 Claude 在加载时看到更多琐碎条目。
claude-mem 本身具备某种自动压缩机制,但我并不全依赖它。我发现手动合并的效果通常更好,因为你能捕捉到两条记忆之间的语义关联,而自动算法往往只能识别文本相似。所以说白了,这工具是你的记忆助理,不是你记忆的最终决策者。
压缩的时机也有讲究。我的经验是不要每天都做,那样太累;也不要攒到几百条再做,那样清理成本巨高。合理周期是两周左右检查一次,或者在你感觉 Claude 的回答“开始变啰嗦、什么旧知识都在往外翻”的时候,就是该压缩了。
5. 常见问题与排查实录
5.1 记忆完全没有生效怎么办
最常见的问题就是:配置好 claude-mem 之后,新开会话,Claude 还是什么都不记得。我排查这种问题一般按三个顺序来。
第一,看 Stop hook 是不是真的注册成功了。很多人改了settings.json但格式写错,导致 Claude Code 静默忽略了整个钩子配置。你可以在对话里故意问一句“你刚才从我的记忆里看到了什么”,如果它说没有任何记忆,大概率是 hook 没生效。第二,看claude-mem capture命令是否能手动跑通。在终端直接跑一次,如果命令报错,那可能是全局安装路径没被 Claude Code 的 shell 环境识别到。第三,确认记忆库文件是不是空。跑claude-mem --list,如果列表为空,说明捕获链路有断点,但配置本身是通的。
我遇到过一种诡异的情况:hook 配置正确、命令能执行,但 MEMORY.md 里还是什么都没有。后来发现是因为触发条件太苛刻,我设置的 matcher 正则不匹配任何实际对话。这种问题嵌套得很深,排查时最好一步步拆解,先验证配置层,再验证命令层,最后才是验证业务层。
5.2 重复记忆堆积如山
另一个高频问题:没用多久,记忆库里出现了大量内容重复的条目。虽然 claude-mem 有去重逻辑,但在某些情况下它依然会失效。比如你每次会话都重新说明一遍同样的规范,每次都用了不同的措辞,向量语义虽然可能接近,但文本相似度的阈值没触发,就会重复插入。
解决办法有两个方向。一个是优化使用习惯:对于长期稳定的规范,与其反复在对话里说,不如直接写进 MEMORY.md 文件里,作为“种子记忆”。这样既减少了重复捕获的机会,也让 Claude 从一开始就具备这些基础认知。另一个是定期合并清理,把重复的条目手动删掉,只保留信息最完整的一条。
这里我要多说一句:别指望任何自动去重能做到完美,语言太灵活,同一个意思可以有一百种表达方式。把记忆库当成你手头的一堆卡片,定期归类整理,才是靠谱的心智模型。
5.3 多项目之间的记忆串台
当你在好几个项目里都启用了 claude-mem,而且把它们放在同一个全局存储位置,就有可能出现串台。我实际遇到过一次:A 项目里记录了“用 pnpm”,B 项目的会话里它居然问我“要不要用 pnpm 装依赖”,可 B 项目明明是 npm 项目。查了半天发现是两个项目共用了一套全局记忆库,导致记忆鱼龙混杂。
这个问题的最佳解法是在初始化时就明确区分存储位置。每个项目都应该有自己独立的.claude-mem目录。个人级偏好才放全局。另外,你在切换项目时最好留意一下当前工作目录,Claude Code 的 hook 触发时会读取项目根目录的配置,如果目录不对,命令可能作用在了错误的记忆库上。
如果你已经出现串台,处理也不难:打开两个项目的 MEMORY.md,把不属于该项目的条目删掉,同时查看个人记忆库里是否有需要清理的交叉内容。这种整理工作有点像搬家时的断舍离,过程麻烦,但搬完之后住着舒服。
5.4 模型更新后记忆格式不一致
我遇到过 claude-mem 在 Claude 模型版本更新之后,抽取的记忆格式偶尔会发生变化。比如以前偏好用列表形式输出事实,新版本开始用一段话描述。这种不一致本身不影响使用,但如果你依赖工具自动去重,就可能因为格式差异导致去重失败。
我的习惯是每个季度检查一次 claude-mem 的更新版本,有更新就及时升级。因为这个工具还在快速迭代,作者经常修格式兼容类的 bug。如果你发现升级后老记忆出现乱码、或根本读不出来,别急着删文件,备份一下 MEMORY.md,然后重新 init 一次存储目录,通常能恢复。
从这些坑里走出来的经验可以总结为一句话:记忆工具不是“装完就万事大吉”的,它需要你花一点心思去维护格式、位置、内容边界。但这份维护成本,相比每天重复向 AI 交代背景,已经是极低的支出了。
6. 进阶玩法与个人经验
6.1 把记忆当作团队交接文档
claude-mem 不知不觉间让团队协作多了一个层面。因为项目记忆存在项目目录里,如果团队成员都在用 Claude Code,大家共享的记忆库就变成了一份活文档。新同学上手时,不用翻半天的 wiki,Claude Code 自己就能从记忆里给出符合项目惯例的建议。
我们团队现在有个不成文的规矩:遇到复杂的项目决策,会在对话里特意强调一遍结论,比如“定下来,生产环境用 PostgreSQL,不要用 MySQL”。这种话不是为了说给 AI 听,而是为了让 claude-mem 捕获,变成长期的团队共识。久而久之,MEMORY.md 成了另一份团队知识库,它和正式文档的区别在于:它保留了很多“为什么当时这么决定”的对话痕迹,这个价值非常大。
我强烈建议你在项目初期就把记忆库的维护习惯建立起来,等积累了半年再看,你会惊讶于这份资产的厚度。它就像代码注释一样,平时不觉得有啥,但到了交接、复盘、维护老功能的时候,每一条记忆都在帮你省时间。
6.2 控制记忆的颗粒度,别什么事都让它记
用久了你就会发现,记忆库里真正有价值的信息其实占比不高。原因主要在于捕获粒度没控制好。claude-mem 的默认行为可能偏保守,会尽量多记一些,以免遗漏。但记太多也是有代价的——每次会话加载的记忆越多,留给当前任务的有效上下文就越少。
我习惯在配置里调低捕获频率,并且对某些敏感或临时性内容明确不记。比如“我今天要修登录页的 bug”这种就应该让它自然消失;“这个项目的登录页用的是 OAuth 2.0 授权码模式”这种才值得记住。把握这个颗粒度的核心标准是:这条记忆在下一次会话里是否仍然有用?如果回答是“是”,才值得留住。
这个原则说起来简单,做起来需要一点点直觉。我的建议是先用默认配置跑一周,然后复盘一下记忆库里哪些条目是“废话”,再根据实际情况调整。越早形成自己的“记忆价值观”,你的记忆库质量提升得越快。
6.3 从 claude-mem 想到的 AI 使用哲学
最后聊一点超出工具本身的想法。用 claude-mem 的时间越久,我越觉得“给 AI 装记忆”这件事的本质,是在重新定义人机协作的边界。过去我们觉得 AI 是个单次对话的问答器,用完即走;现在有了记忆,它开始像一个“渐入佳境”的同事,和你一起成长、积累默契。
这背后也提醒我一件事:AI 已经不再是“用完即抛”的玩具,它正在变成真正参与项目长期建设的一份子。而给它持续投喂高质量记忆,就像给新员工做入职培训,前期投入是值得的。你不欠它什么,但你的项目会由于它的稳定发挥而明显受益。我个人在项目里推广 claude-mem 之后,最大的体会是:跟 AI 沟通的心智负担明显减轻了,不用再时刻想着“这句话要不要再说一遍”,因为它都会记得。这才是工具给工作流带来的最本质的改善。