如果你最近在用 Claude Code 写代码,估计你体会过这种崩溃:昨天刚跟它敲定的一整套 API 规范,今天新开一个会话,它像断片一样全忘了。我一度靠着反复把背景说明贴进 prompt 过日子,直到看到社区里有人安利claude-mem——一个给 Claude Code 加长期记忆的本地工具。装上以后,它会在对话过程中自动把关键信息抽出来存好,新会话开始时再把相关记忆递回去,等于给同一套 AI 配了一本随拿随用的项目笔记。
这篇文章不是官方文档的翻译,而是我自己从安装到调参、再到项目里实际用了两三周之后的完整记录。里面会有原理拆解、有可以直接照抄的命令、也有踩过坑之后的排查清单。如果你正在用 Claude Code 做正经项目、尤其是需要跨多天连续开发的场景,claude-mem 应该是你今年值得装的一个命令行工具。
1. 先说清楚:claude-mem 到底在解决什么问题
1.1 Claude Code 的"金鱼记忆"痛点
Claude Code 是 Anthropic 出的命令行 AI 编程助手,在终端里直接跑,能读文件、执行命令、写代码。它干活确实猛,但有个特别别扭的点:每次新开会话,之前聊的需求、决策、踩坑记录就全没了。
我举个自己遇到过的例子。之前做一个支付网关的改造,周一下午跟 Claude Code 确认了幂等方案——订单号用 Redis 锁、回调接口做成天然幂等、数据库唯一索引兜底。周二早上新开终端,它又用默认方案开始撸代码,差点把唯一索引去掉。你跟它说"昨天不是定了吗",它只能回你一句"我没有这次会话之前的上下文"。
你说,这些东西写进 CLAUDE.md 不就行了?理论上可以,但现实是大量上下文是碎片化的:可能是你随口提的一句"这个模块是历史包袱,别动"、也可能是在排查 bug 过程中敲定的临时约定。这些信息根本没法预先写成文档。想用 Claude Code 做可持续的日常开发,你需要的不是更长的 system prompt,而是一个能在会话之间保存、检索、自动回填记忆的机制。这是 claude-mem 存在的核心原因。
1.2 为什么选 claude-mem:自动化、本地化、语义化
在 claude-mem 之前,社区也有人用各种外挂思路给 Claude Code 做记忆,但普遍有硬伤:要么只做关键词匹配,换个说法就想不起来;要么得手动维护一个 Markdown 文件,写几轮就嫌累。claude-mem 的定位很干脆:记录和回忆两头都自动化。
它的核心思路可以拆成三个关键词:
- 自动化:不需要你手动说"记住这句话"。它通过 Claude Code 的 hooks 机制在后台拦截对话,自动抽取高价值信息。
- 本地化:数据默认落在你自己的机器上,用 SQLite 存储,不上第三方云端。对代码隐私要求高的人,这一点是刚需。
- 语义化:存储时不只留原文,还会做向量化索引。下次会话按"意思相近"来检索,而不是按"关键词相同"来匹配。
我自己的判断是,这三个词缺一个,工具都会变得难用。没有自动化就是又一个人肉记笔记工具;不上本地就很难解释自己企业代码为什么敢给第三方;没有语义检索就会出现"肯定记过但死活翻不出来"的挫败感。claude-mem 正好把三件事都占了,所以才会在社区里快速传开。
2. 记忆机制拆解:它是怎么"记住"的
2.1 从 Hook 到守护进程:拦截对话的链路
想给 Claude Code 做长期记忆,第一步是解决"怎么能看到对话内容"。claude-mem 用的是 Claude Code 官方支持的hooks 机制。你可以把 hooks 理解成官方预留的"外挂插槽":在用户输入、AI 输出、工具调用等节点,允许外部脚本插入执行。claude-mem 就在这些节点上挂了自己的监听逻辑。
具体工作链路是这样的:当你在一轮对话里按下回车,Claude Code 会先触发 hook,把用户输入和上下文快照转发给一个后台的 claude-mem 守护进程,然后再继续正常对话流程。守护进程拿到内容后,做解析、抽取、向量化、写入 SQLite,整套动作是异步的,所以不会卡住你的对话输入。
这里有一个很关键的设计取舍:为什么不直接改 Claude Code 的源码或者靠提示词注入来实现记忆?因为 hooks 是官方扩张点,未来 Claude Code 升级版本时,hooks 接口大概率保持兼容,而改源码的方式每次升级都会碎掉。用 hook 加一个黑盒外挂,对主程序的影响最小。这也是我后来愿意长期用它的原因——不侵入核心逻辑,出问题大不了禁用插件。
2.2 短期、长期、知识库的三层设计
很多人以为"记忆"就是把历史聊天记录存下来、下次全塞给模型。真这么干会出问题:几十轮对话的原文塞进上下文,占 token 不说,大部分都是客套话和过程噪音。claude-mem 在存储上做了分层,大致是三层结构:
- 短期会话记忆:当前会话内的逐条消息,用于会话过程中的上下文承接,会话结束或过期后自动降级。
- 长期偏好记忆:从历史会话里抽取出来的用户偏好、项目决策、明确约定。比如"接口返回格式统一用 code/data/msg"这类信息,会被单独提炼成结构化条目。
- 项目知识库记忆:更高层的归纳结果。比如项目的目录约定、历史包袱、业务规则,会被聚合为可检索的知识点。
分层设计的好处是:下次新会话注入记忆时,不会把原始日志全部倒给模型,而是优先注入高价值的长期记忆与知识库条目。短期原始日志只作为底层的回溯证据,一般不会主动进入上下文。这种设计让我想到人脑的记忆机制——重要的事存长期,无关细节随手丢,而不是把每天所有经历都原封不动背下来。
2.3 语义检索和记忆注入:它是怎么"想"起来的
记忆存进去了还得能"想起来"。claude-mem 在 SQLite 里同时存了文本和向量索引,用的是 sqlite-vec 这类本地向量扩展。新会话开始时,它会生成一个表示当前任务意图的查询向量,然后在整个记忆库里做相似度检索,挑出最相关的若干条记忆,注入到 Claude Code 的系统提示或工具调用环境中。
关键点在于"相关性匹配"而不是"关键词命中"。举个例子:你周一聊的是"支付回调幂等",周三新会话问的是"重复通知怎么防",两个问题的字面差异很大,但向量空间里它们距离很近,于是能成功命中之前的记忆。如果是传统关键词匹配,这条记忆大概率就石沉大海了。用通俗的话说,它不像在一本书里翻目录,更像在你的记忆里"联想"到相关内容。
整个过程不需要额外的向量数据库服务,也支持纯离线运行。结合 Claude Code 的插件机制,Claude 可以在需要时主动调用记忆查询工具,再结合检索结果组织回答。实际表现是,新会话里 Claude 会突然冒一句"根据之前你提到过的约定……",那种体验确实有点神奇。
3. 本地环境准备与快速上手
3.1 安装 claude-mem 与前置依赖
先说前置条件:你得先有一个能正常运行的 Claude Code 环境,能用claude命令在终端里启动对话。其次本地要有 Node.js 运行时,因为 claude-mem 的安装脚本和后端服务依赖它。不用提前装任何数据库,SQLite 文件会自动创建。
安装方式很简单,官方提供了一行脚本:
curl -fsSL https://claude-mem.sh/api/install | bash脚本会自动把可执行文件放到用户目录,并且注册好 Claude Code 需要的 hooks 配置。装完以后,我建议先跑一下:
claude-mem --version确认命令已经生效、能看到版本号。如果提示找不到命令,大概率是安装脚本写入的 PATH 没在当前 shell 里生效,重启终端或手动刷新一下 PATH 即可。
3.2 启用记忆:环境变量与 hooks
装完插件不等于立刻生效。claude-mem 的设计是"默认禁用",需要你主动设置环境变量才会开启。在~/.bashrc或~/.zshrc里加上以下内容:
export CLAUDE_MEM_ENABLED=true export CLAUDE_MEM_PROJECT_DIR="$HOME/.claude-mem" export CLAUDE_MEM_DEBUG=false然后执行source ~/.zshrc(按你实际的 shell 来),再重启 Claude Code。这里的变量名以你安装版本的官方 README 为准,不同版本可能会有调整,但CLAUDE_MEM_ENABLED这个总开关基本是一致的。
验证是否生效,我习惯在 Claude Code 对话里直接输入:
/claude-mem status正常情况下会看到守护进程连接成功、数据库路径、当前记忆条数等信息。我第一次用的时候一直没输出,后来发现是环境变量加在了错误的 shell 配置文件里。很多"装了不生效"的问题,本质上都出在这一步。
3.3 实操演示:一次完整的"记住-想起"实验
光看配置还不够,我建议你跟着做一轮简单实验,先建立对工具的直觉。
第一步:新开一个 Claude Code 会话,输入下面这段话:
我们项目里所有 HTTP 接口的响应包统一用
{code, data, msg}结构,字段名全部用蛇形命名,以后写接口尽量遵守这个约定,请记住。
聊完随便再让 Claude 写一行代码,然后退出会话。
第二步:确认记忆有没有写进库。在终端执行:
claude-mem list --limit 10如果刚那条"响应包统一结构"的内容出现在了列表里,说明自动持久化已经生效。
第三步:重新开一个新会话,不要给任何上下文,直接问:
我们项目接口响应结构有什么约定?
如果一切正常,Claude 会直接说出{code, data, msg}和蛇形命名规则,甚至可能补一句"根据之前会话中的记录"。到这里,整个"记住-想起"闭环就跑通了。之后你在开发过程中产生的关键决策,都会被逐步沉淀进记忆库,而不是随会话一起蒸发。
4. 配置调参与项目隔离实操
4.1 调节记忆提取的粒度
默认策略是"能记都记",但真实项目里你其实希望记忆更克制一些。打开 claude-mem 的配置文件,一般在~/.claude-mem/config.toml,里面可以调整记忆提取的行为。不同版本字段名会略有差异,但通常会有类似下面的区块:
[memory] auto_extract = true # 是否自动抽取长期记忆 min_similarity = 0.35 # 注入时的最小相似度阈值 store_raw_messages = false # 是否保存原始对话日志我自己调参时踩过一个坑:一开始把min_similarity调到了 0.6,结果新会话里几乎检索不到任何记忆,Claude 又变回"金鱼模式"。后来降到 0.35 左右,记忆开始频繁被命中。这个阈值本质上是在"召回太少"和"噪声太多"之间找平衡:太高容易漏记,太低会把一堆不相干的项目细节注入进去干扰判断。建议你用一个小项目试跑几天,观察注入内容的命中率再微调。
4.2 多项目隔离:避免上下文串味
很多人用了几周之后会遇到一个奇怪现象:做的明明是 A 项目,Claude 却突然提到 B 项目的依赖或命名规范。原因很简单——你没有做项目隔离,所有记忆混在同一个库里了。
我的做法是让每个项目拥有独立的记忆空间。有两种可行的思路:
- 指定数据目录:在启动 Claude Code 前,把
CLAUDE_MEM_PROJECT_DIR指到当前项目目录下的.claude-mem-data,各项目用自己的文件夹。 - 指定项目名:如果版本支持
CLAUDE_MEM_PROJECT_NAME,就按项目名在库里做命名空间隔离。
我自己用的是目录隔离方案。在项目根目录放一个.env文件,每次启动 Claude 前 source 一下,确保记忆归属明确。记得把.claude-mem-data加进.gitignore,否则本地记忆文件被你随手提交到代码仓库,既占空间又可能泄露业务信息。
4.3 数据备份、清理与隐私边界
因为 claude-mem 默认全本地存储,备份就特别简单:直接拷贝整个数据目录即可。我每周会把~/.claude-mem目录压缩存档一次,来回折腾代码重构的时候,这个备份救过我一次——记忆库因为一次异常操作损坏,我把备份丢回去就恢复了。
隐私方面要多说一句:claude-mem 本身不把你的数据发到任何云端,但如果你配置了远程 embedding 服务或通过云端模型做语义提取,那么部分文本仍然会经过外部 API。对隐私极其敏感的项目,建议在配置里打开纯本地模式,确认所有 embedding 生成都在本机完成。还有一个实用技巧:如果只想保留抽取后的结构化记忆、不保留原始对话痕迹,就把store_raw_messages设为false。这样库里只留整理后的要点和向量,历史原文不落盘,敏感信息残留会更少。
5. 常见问题与排查技巧实录
5.1 装完不生效?按这三步排查
我遇到的绝大多数"不生效"问题,都可以按下面这个顺序排查:
- 环境变量没加载:检查
echo $CLAUDE_MEM_ENABLED是否输出true。如果输出为空,再看是不是加错了配置文件。我最初加在.bash_profile,但终端跑的是 zsh,折腾了半小时才找到原因。 - hooks 没挂上:检查 Claude Code 的插件目录,看看有没有 claude-mem 生成的 hook 文件。如果没有任何相关文件,重新运行安装脚本,或者手动执行
claude-mem setup注册。 - 守护进程没跑起来:执行
ps aux | grep claude-mem,确认后台进程存活。有时候安装后进程没自启,手动运行claude-mem daemon start能解决。
把这三处都过一遍,大部分问题都能定位到具体环节。排查时可以打开CLAUDE_MEM_DEBUG=true,看实时日志输出流。
5.2 记忆过期、串味怎么办
长期使用后,记忆库里难免会有过时决策。项目大改方向后,旧记忆反而会成为干扰源。我的经验是:不能只依赖自动清理,要主动做减法。
系统支持两种清理方式:一种是精确删除某条记忆,比如/claude-mem forget "旧的接口规范",让它命中并移除指定内容;另一种是全部清空,直接停掉守护进程,删掉数据目录里的 SQLite 文件再重启。如果你的项目刚经历了一次大重构,我建议直接走全量清理,别一条条删。与其让一堆过期约定继续恶心新会话,不如一次性重建记忆库。
串味问题就一句话:做项目隔离。别把多项目塞进同一个数据目录。这个问题越早处理越轻松,到记忆库几百条的时候再拆,你会崩溃的。
5.3 和其他工具一起用时的冲突与性能
Claude Code 本身可以装多个插件,如果每个插件都注册了 hooks,就有可能出现互相覆盖或执行顺序问题。claude-mem 的 hook 名称一般会带自己的命名前缀,正常情况下不会跟其他插件冲突。但如果你发现记忆完全不写了,而其它功能正常,优先怀疑是不是某个插件在 hooks 链路里把消息提前截断了。
性能方面,因为记忆写入是异步的,日常对话基本无感。但有两个场景会有一点卡顿:一是长篇对话结束后的持久化瞬间;二是新会话开始时做向量检索时。如果本地嵌入模型比较重,可能会有几百毫秒延迟。我自己的做法是选轻量级嵌入模型,或者把常见知识提前写进 CLAUDE.md——让记忆库只负责承载"临时决定",而不是替代所有文档。
我实际用下来的最大体会是:claude-mem 最值钱的地方不是把每句话都记住,而是把那些在项目过程中灵光一现的约定和决策捞回来。它适合的,是真正拿 Claude Code 当主力开发工具的长期主义者。
最后再分享一个小技巧:想知道工具到底记住了什么,别只靠问 Claude,直接claude-mem list --limit 20扫一眼,最直观。那比任何调参工具都更有用。