如果你用过 Claude Code,大概率经历过这么一种抓狂时刻:昨天把某个模块的架构梳理得明明白白,今天开个新会话,它转头问你“这个项目是干嘛的”。不是它变笨了,而是 Claude Code 的每次会话本质上都是无状态的,上下文一关就彻底清零。为了补上这块短板,开源社区出现了一个叫 claude-mem 的工具——它专门给 Claude Code 做长期记忆,自动记录对话里值得沉淀的信息,并且在下次会话开始时把相关记忆重新注入进去。如果你每天泡在 Claude Code 里、跨好几天推进同一个功能,或者经常在多项目之间来回切换,那这篇文章就是写给你看的。我会从它的设计思路讲起,带你完整过一遍安装、配置、日常使用,再把我踩过的坑和调优经验全部摊开。
1. 为什么需要 claude-mem:Claude Code 的失忆症与记忆外置方案
1.1 会话无状态带来的麻烦
Claude Code 的会话机制决定了它默认就“不记人”。每次你启动一个新会话,它面对的是一个全新的上下文窗口,之前聊过的技术决策、写过的命令、确定过的代码风格,全都不会自动带过来。平时跑个三五分钟的短会话还好,可一旦任务是“昨天拆了一半、今天接着拆”的活,问题就立刻显形了。
我举几个我实际遇到过的场景。第一个是隔天续接:头天我让 Claude 设计了订单模块的表结构,约定了主键用雪花 ID、金额字段用 decimal、所有表都带 created_at 和 updated_at。第二天打开新会话,问它“昨天那个订单表建好了吗”,它完全没印象,我只能把建表规范重新敲一遍,它才在全新上下文里重新开始工作。第二个场景是多项目切换:上午在日志系统里和 Claude 聊 Kafka 消费分组的策略,下午切到数据迁移项目,它又开始问你“这个项目是做什么的”,每个项目都要重新做一次 onboarding。第三个场景是决策反复:同一个问题,上次已经定了“用 A 方案”,这次没有上下文,它可能又给你推荐 B 方案。
这些问题的根源,不是 Claude 能力不行,而是上下文没有持久化。我自己算过一笔账,如果靠手动往提示词里粘贴前情提要,一次要烧掉两三千 token;不贴的话,回答质量明显下降,甚至可能给出和上次方案冲突的建议。claude-mem 的思路就是把这个“前情提要”自动化:它记录对话、提取重点、存到本地,下次会话需要的时候再自动取出来,相当于给 Claude Code 装了一个外置记忆硬盘。
1.2 从 RAG 到对话记忆:claude-mem 的思路
如果你接触过 RAG(检索增强生成),会发现 claude-mem 的底层逻辑跟它是一脉相承的:不把所有信息都塞进上下文窗口,而是先存到一个外部存储里,等到需要的时候再检索相关的片段注入进去。区别在于,RAG 检索的对象通常是文档、网页这类静态知识,而 claude-mem 处理的是动态的对话历史、任务进度、项目决策,这些信息天然带时序性,还经常要处理“新结论推翻旧结论”的情况。
所以 claude-mem 不是简单地把聊天记录存下来再原样拼回去,而是走了一个“提取-存储-检索注入”的循环。一次会话从开始到沉淀记忆,大概要经历这么几步:
- 你新建一个会话,输入第一句话,claude-mem 的注入钩子被触发,先从记忆库里检索和当前任务最相关的记忆片段,拼在对话最前面。
- 你和 Claude 正常对话,每次它调用 Bash 等工具时,claude-mem 顺手记录一条操作日志。
- 会话自然结束,claude-mem 把整段会话交给一个提取模型,让它阅读并抽取出值得长期保留的信息。
- 提取结果经过分类、去重、加时间戳后写入记忆库。
- 下次新会话开始,又回到第一步,检索时会把更新过的记忆捞出来。
有人可能会问:Claude Code 不是已经支持 CLAUDE.md 这种项目提示文件了吗,这跟 claude-mem 有什么区别?区别很明显。CLAUDE.md 是静态的,写完之后不会自己变,更像一份手动维护的项目说明书;而 claude-mem 是自动运行、自动更新的动态记忆,它记录的是“项目里刚刚发生了什么”这种高频变化的信息。两者可以配合用:CLAUDE.md 告诉 Claude 项目背景和规范,claude-mem 告诉它最近进度和最新结论。
2. 核心功能拆解:记忆的提取、存储与注入
2.1 三类记忆如何分工
claude-mem 把记忆分成了几个不同层级,这也是我觉得它设计里最讲究的地方。它没有把所有东西一股脑塞进一个“记忆池”,而是按生命周期和用途做了明确的切分。
第一类是核心事实(core facts),保存的是最稳定的那部分信息:你的工作偏好、项目的关键约束、技术栈选择、团队约定。这类记忆基本不会变,适合长期保存,每次注入的时候优先级最高。第二类是长期记忆(long-term),记录的是任务级别的信息,比如“当前正在重构用户模块的鉴权逻辑”“上周确定用 Redis 做缓存队列”。这类记忆是跨会话续接任务的关键,没有它,Claude 就不知道你手上正进行到哪一步。第三类是短期记忆(short-term),更像是工作台状态,记录这两天正在处理的细节,比如“订单接口的异常处理写了一半,还差超时重试”。短期记忆时效性强,但过两周基本就没用了。第四类是词汇表(vocabulary),专门记录项目里的专有名词和惯用说法,能避免 Claude 在后续会话里反复问“这个 XXX 是什么”。
这种分层最大的好处是:注入的时候可以按优先级取舍。核心事实基本每次都带,长期记忆按项目相关性带一部分,短期记忆只在确实和当前任务有关时才带,词汇表作为补充词典。如果所有信息都一视同仁地当成“记忆”存下来,那检索和注入的质量很快就会失控,最后变成什么都记,等于什么都没记住。
2.2 存储选型:Markdown 优先还是 SQLite 优先
claude-mem 默认把记忆存成 Markdown 文件,放在~/.claude-mem/目录下,每个项目一个独立命名空间。我刚开始觉得这个设计有点“原始”,用久了才发现它非常有道理:文本格式是透明的,任何时刻你都可以打开文件,直接看看 Claude 到底记住了什么、有没有记错。用户对记忆工具最大的诉求,往往不是“存得好不好”,而是“记的东西我可不可控”。Markdown 文件能看能改,还能用 git 做版本管理,哪天记忆被动过手了,一查 diff 就知道。
我贴一份我机器上的记忆目录结构,大概长这样:
~/.claude-mem/ ├── core-facts/ │ └── my-project.md ├── long-term/ │ └── my-project.md ├── short-term/ │ └── my-project.md └── vocabulary/ └── my-project.md如果你的记忆量非常大,跑了几百个会话、积累了上万条记忆,纯文件检索的性能会开始吃紧,这时候可以考虑切换到 SQLite 存储。claude-mem 支持通过配置指定存储后端,SQLite 在检索和去重方面更高效。我的经验是:个人项目用 Markdown 完全够了,几十个会话级别的记忆量,文件检索的延迟几乎感知不到;如果是团队级共享,或者准备长期高强度使用,建议上 SQLite,顺手还能做点自定义查询。
这里补充一个我常用的玩法:因为记忆文件是纯文本,你可以用任何文本工具去挖掘它。我偶尔会写个脚本扫描所有记忆文件,统计高频出现的库名和技术术语,看看项目这段时间的技术倾向是什么。这种操作在 SQLite 里要写 SQL,在 Markdown 文件里反而一个 grep 就搞定了。
2.3 注入机制:如何做到“记得住又不喧宾夺主”
记忆注入是整套机制里最容易翻车、也最值得调优的环节。claude-mem 通过 Claude Code 的 UserPromptSubmit 钩子,在每次用户输入提交之前,把检索到的记忆整理成一段“记忆上下文”,拼到对话最前面。关键问题在于:拼多少、拼哪些,直接决定了效果。
如果注入太少,Claude 还是处于半失忆状态,你问它“那个接口写完了吗”,它看到的记忆里根本没有对应条目。如果注入太多,会挤占宝贵的上下文窗口,甚至让 Claude 把注意力分到无关记忆上,回答质量反而下降。claude-mem 默认的做法是设置一条注入上限,比如最多 800 token,然后按“相关度分数”从高到低选取记忆片段。相关度怎么算?提取记忆时,它会为每条记忆生成关键词和标签;注入时,把当前提示词和记忆标签做匹配,同时考虑时间衰减——太遥远的记忆即使相关,分数也会往下调。
注入拼出来的内容,实际效果大概是下面这样一段(我用缩写形式示意):
[Memory Context] - (core) 项目 my-project 使用 TypeScript + FastAPI,数据库 PostgreSQL - (long-term) 正在重构用户模块鉴权逻辑,改用 JWT,替换 session - (short-term) 昨日已完成异常处理中间件,待实现超时重试 [End Memory]一个很重要的调参心得是:与其焦虑注入条数,不如先做减法。我会定期清理记忆库里的废话记忆,比如“用户今天说开始写文档”这种一次性的状态,过了两三天就不再注入。控制记忆质量,比单纯调大 max-tokens 参数有效得多。后面我会专门讲这块的实操。
3. 实操接入:把 claude-mem 装进你的工作流
3.1 安装与初始化
安装前提是机器上已经有 Node.js 环境和 Claude Code 命令行环境。然后三步走:用 npm 全局安装 claude-mem,用自带的 install 命令自动配置 hooks,最后用 doctor 命令做一次全身体检。
npm install -g claude-mem claude-mem install claude-mem doctorinstall 命令做的事,是修改你的 Claude Code 配置文件(默认是~/.claude/settings.json,也可以放到项目的.claude/settings.json里做项目级配置),把需要的 hooks 写进去。doctor 会检查当前配置是否生效、记忆目录能不能正常读写、提取模型能不能被调用、hooks 配置是否完整。跑完 doctor,如果各项检查都通过,基本就可以直接用了。
安装完成之后,我建议先随手跑一个短会话做验证。随便让 Claude 写个几行 Python 脚本,然后结束会话,运行claude-mem history --limit 20,看看刚才的对话有没有被记录成记忆条目。如果 history 是空的,别急着开始大批量工作,回配置文件检查钩子路径和调试日志。
3.2 hooks 配置说明与关键参数
先看一份完整的 hooks 配置,这是我实际在用的版本,去掉了一些非关键字段:
{ "hooks": { "UserPromptSubmit": [ { "hooks": [ { "type": "command", "command": "claude-mem inject --max-tokens 800" } ] } ], "PostToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "claude-mem capture --tool \"$TOOL_NAME\"" } ] } ], "Stop": [ { "hooks": [ { "type": "command", "command": "claude-mem remember" } ] } ] } }每个 hook 都有明确分工。UserPromptSubmit 里的 inject 负责在对话开始前把记忆注入进去,--max-tokens 800控制注入内容的最大长度,我一般设在 600 到 1000 之间。PostToolUse 里的 capture 会在 Claude 执行完 Bash 工具后记录一条操作日志,--tool "$TOOL_NAME"是为了把当前调用的工具名也记进日志。Stop 里的 remember 是核心,在一次会话自然结束时,对整段会话做提取总结,生成新的记忆条目。
还有几个环境变量很值得在配置文件里预设,我把常用参数整理成了一张表:
| 变量 | 作用 | 推荐设置 |
|---|---|---|
| CLAUDE_MEM_DIR | 记忆存储目录 | 云盘同步目录或项目工作目录 |
| CLAUDE_MEM_MODEL | 负责提取记忆的模型 | 默认与 Claude Code 一致,不建议随意调低 |
| CLAUDE_MEM_MIN_SCORE | 注入记忆的相关度阈值 | 0.3 到 0.5 之间 |
| CLAUDE_MEM_DEBUG | 是否输出调试日志 | 排查问题时设为 1 |
这里最想提醒的是CLAUDE_MEM_DIR。把记忆目录从默认的~/.claude-mem改到云盘同步目录或者项目工作目录,一旦换机器,记忆不会丢。我周围不少同事都是因为没提前改这个,重装系统之后记忆库全部归零,那种从头再来的滋味真的很痛苦。
3.3 日常使用:查看记忆、检索历史、维护记忆库
日常用到的高频操作,无非三个:查看记忆历史、检索某条记忆、编辑记忆文件。
# 查看最近 20 条记忆 claude-mem history --limit 20 # 全文检索记忆 claude-mem search "Redis 队列" # 查看记忆库统计 claude-mem statssearch 是我用得最多的命令。跨会话续接任务前,先搜一下“上次进行到哪了”,比翻聊天记录快得多,也比直接问 Claude 靠谱,因为 Claude 在无上下文的新会话里什么都想不起来。history 适合快速回顾这一天的对话沉淀了什么内容。stats 能告诉你当前记忆库里有多少条核心事实、多少条短期记忆,方便你判断是不是该做一次大清理了。
记忆库维护这件事,真不是可做可不做的。我给自己定了一个节奏:每完成一个里程碑,就打开~/.claude-mem/目录,把过时的短期记忆删掉,把关键决策整理进长期记忆区。文件是纯 Markdown,编辑起来非常顺手。频率不用太高,每周一次或者每个项目节点一次都行,但一定要坚持。一台长期不清理的记忆库,最终会变成噪声场,这个说法一点不夸张。
4. 常见问题与调优实录
4.1 记忆冲突与污染
我踩过的第一个坑是记忆冲突。项目刚起步那阵子,我在一个会话里说“缓存用 Redis”,隔两天又在一个新会话里说“把缓存放内存里就行”,两条都被存成了核心事实。结果第三个会话里,Claude 一会儿建议用 Redis,一会儿建议用内存,把自己绕晕了。这个问题的根源在于,claude-mem 只是忠实地记录了两条互相矛盾的记忆,并没有自动判断哪条更新、哪条作废。
处理办法分两种。一种是事后补救:用claude-mem search找到旧记忆,直接编辑 Markdown 文件,把它删掉或者标注为“已废弃”。另一种是治本的做法:重要决策,在会话里明确告诉 Claude“记录一下:缓存统一用 Redis,之前提的内存方案作废”。理论上 Careful 模型在提取时会尽量保留最新信息,但它无法替你判断你的话是不是在推翻旧结论,所以关键决策最好直接给它一个“覆盖”信号。
4.2 注入内容过多挤占上下文
第二个高频问题,是注入记忆太多把上下文撑爆。症状很典型:会话开始后,Claude 明显变“钝”,经常答非所问,token 消耗肉眼可见地上升。这时候第一步不是急着调参,而是先去看注入的是不是一坨噪声。用claude-mem inject --dry-run或者打开调试日志,看看它到底选了哪些记忆片段进对话。我见过最夸张的一次,检索器把二十多条半年前的记录全捞了出来,跟当前任务一点关系都没有。
定位问题之后,调参方向就很明确:把--max-tokens下调,把相关度阈值CLAUDE_MEM_MIN_SCORE抬高,限制注入条数。但这些只治标,治本还是在记忆维护——把过期的、一次性的、细节过多的记忆删掉,让记忆库里留下的每条都“值得被注入”。我现在给自己定的规矩是,超过两周没有更新、且不属于核心事实的记忆,全部清理掉。记忆不是越多越好,质量才是关键。
4.3 隐私与安全边界
claude-mem 把记忆存本地,这把双刃剑要看你怎么用。方便是真的方便,但如果你在会话里让 Claude 处理过敏感信息,比如数据库连接串、内部 API 密钥、客户数据,这些信息很可能被提取模型写进记忆文件,等于在本地又多了一个泄露风险点。我的建议是,在需要处理高敏感信息的会话里,不要依赖自动记忆,甚至可以临时把 remember 这个钩子禁用掉,等敏感内容处理完再开回来。
另外要特别留意多项目的记忆隔离。claude-mem 默认按项目命名空间区分记忆,但如果两个项目用了同一个目录名,或者你在错误的项目目录里启动了 Claude Code,记忆就可能串门。换目录之前先确认当前项目路径,确保记忆进的是正确的命名空间。这个坑踩过一次之后我才真正意识到:记忆工具其实很考验使用者的目录卫生,项目路径规范了,记忆才规范。
4.4 高频踩坑速查表
| 现象 | 可能原因 | 处理方法 |
|---|---|---|
| 注入记忆后 Claude 变钝 | 注入过多、检索到无关记忆 | 调低 max-tokens、抬高 min-score、清理无效记忆 |
| hooks 不触发 | 安装后没重启 Claude Code | 重启会话,运行 claude-mem doctor 检查配置 |
| history 为空 | 提取模型调用失败 | 检查 API 调用状态、模型配置、调试日志 |
| 记忆串项目 | 项目路径不匹配 | 确认当前目录,清理错误的命名空间记忆 |
| 记忆矛盾 | 新旧信息未覆盖 | 手动编辑记忆文件,新决策主动标注“作废旧方案” |
5. 进阶玩法与实践心得
5.1 让 claude-mem 成为团队的共享记忆
单个开发者的记忆库已经很好用了,但用久了你会发现自己其实可以把它推到团队层面。最简单的做法,是把~/.claude-mem/目录放进一个共享的 git 仓库,每个成员各自运行 claude-mem,但记忆文件统一同步。这样团队里任何一个人和 Claude 讨论过的技术决策、踩过的坑、确认过的约定,其他人后面打开会话时都能自动继承。唯一要注意的是,共享记忆库的命名空间必须统一规范,否则大家会一起串门。
这种做法特别适合“几个新人同时上手一个老项目”的场景。新人遇到不清楚的问题,与其反复问人,不如先在记忆库里搜一遍,很可能之前某个会话里已经记录过答案了。从某种角度说,这相当于给项目攒了一份自动生成、持续更新的活文档,而且这份文档的维护成本远低于手写 Wiki。
5.2 我的使用节奏与调参心得
最后分享几个实操心得,都是我拿 token 换来的。
第一,remember 的触发时机很重要。它挂在 Stop 钩子上,只有会话自然结束时才会触发提取。如果你用 Ctrl+C 强行中断会话,这次会话的记忆很可能就丢了。我现在的习惯是,每次阶段性工作做完,哪怕只是跟 Claude 说一句“今天先到这儿,记得记录进度”,让对话正常收敛,再关掉终端。这个动作成本极低,但能保证记忆不丢。
第二,负责提取的模型值得单独调优。默认情况下 claude-mem 会用和 Claude Code 相同的模型,质量稳定但费用偏高。如果你长期开着自动记忆,API 开销会明显增加。我的折中方案是保留 Claude 系模型做提取,但把日常会话切成更小的任务块,减少每次需要提取的总量。反正记忆是持续积累的,会话短一点,提取出的记忆反而更干净、更聚焦。
第三,每周固定给记忆库做一次“体检”。我会把近期记忆梳理一遍,删除无效条目,合并重复条目,给新决策补上时间标签。整个过程不超过十分钟,但它能让记忆库长期保持高信噪比。这个习惯坚持了大概两个月之后,我再也没遇到过“Claude 记了一堆东西,关键时刻全想不起来”的尴尬情况。