最近一段时间一直在折腾一件事:让Claude Code在隔了一个晚上之后还能记得我昨天说过“这个模块用Python重写”以及“测试文件统一丢到tests目录”。中间试过各种“外置记忆”方案,最后真正解决问题的,是一个叫claude-mem的开源项目。
claude-mem是一个专门给Claude Code做记忆层的工具,核心能力可以用两句话概括:在会话进行中自动记录关键信息,在新会话里按需把旧记忆检索出来。它不是靠插件市场里那些静态提示词技巧,而是通过hooks加MCP的方式,在对话生命周期里做“捕获—提炼—存储—查询”的闭环。这篇文章我会把它的工作原理、安装配置、数据形态、以及我实际用下来踩过的坑都梳理一遍,适合正在用Claude Code做真实项目、又苦于每个新会话都要重新交代背景的人。哪怕你刚接触命令行AI助手,照着后面的步骤走一遍,也能跑通整个记忆链路。
1. 先从“健忘”说起:Claude Code的记忆短板到底在哪
1.1 会话隔离是AI编程助手的天然特性
很多人第一次用Claude Code时会觉得很惊艳,可一旦关掉终端重新打开,很快就会发现一个让人抓狂的现象:它完全忘了我们之前聊过什么。这不是产品做漏了,而是“会话隔离”这个架构特性决定的。每个会话都是一个独立的上下文窗口,模型在回答你的问题时,能看到的只有当前会话里的历史消息、当前工作目录下的文件内容,以及通过工具拿到的信息。新会话的消息列表是空的,模型自然也就无从知道“上次”发生了什么。
打个比方,这就像你给一个临时工发任务:每次开工前他手里只有你刚递过来的那张纸条,前面几天的讨论记录他统统看不到。他能干得很好,但前提是你得把背景重新讲一遍,或者把背景写成一个他随时能读的文档。放在Claude Code里,这个“随时能读的文档”通常就是项目里的说明文件,或者你手动粘贴的历史背景。问题是,靠人手动维护这些背景,本身就是一个额外负担,而且很容易漏。
1.2 Claude Code已有的“记忆”手段与不足
Claude Code本身并不是完全没有跨会话记忆的“替代方案”,常见的有这么几个:
- 项目说明文件:项目根目录下放一个说明文件,会话启动时会被注入上下文。适合记录长期稳定的项目约定,比如技术栈、目录规范、提交信息格式。
- 会话恢复参数:可以用参数恢复上一次会话。这个能找回完整对话历史,但本质上它还是“那一个会话”,不是跨会话的记忆系统。
- 内置命令与配置:通过斜杠命令和配置文件,可以把一些固定的规则、偏好放进会话上下文里。
这些方案的共同局限在于:它们默认“记忆应该由人来记录和整理”。规则变了,你得记得去改说明文件;对话里出现的临时决定,散落在某个会话的角落,过几天就找不到了;多个项目之间切换的时候,静态规则还好说,动态上下文几乎等于零。也就是说,Claude Code原本提供的是一套“人写规则、它读规则”的机制,缺的是“对话过程中自动涌现出来的临时事实”这一块。
1.3 claude-mem补上的是“动态、自动、可查询”这块
claude-mem的目标恰好是补上这块动态记忆。它不需要你手动维护,而是通过监听会话生命周期,把对话里出现的偏好、决策、关键信息自动提取出来,存到一个本地记忆库里。下次开新会话时,它可以基于MCP协议向Claude Code暴露一组查询工具,让模型在新对话里也能“想起”之前记下来的内容。
这就把记忆从“人写规则”变成了“对话即记录”。你不需要在对话里额外说一句“请记住这件事”,只要正常聊天、正常讨论方案,它就会在后台做提炼和归档。对于我这种经常同时维护好几个项目、又懒得写文档的人来说,这个设计思路正好打中痛点。
2. 两个核心机制:hooks负责“记”,MCP负责“查”
2.1 靠hooks在合适时机“截获”对话内容
claude-mem之所以能做到自动化,首先依赖Claude Code的hooks机制。所谓hooks,可以理解成会话生命周期里预设的一些“事件节点”,当某个事件发生时,外部命令就会被触发。claude-mem主要挂靠在两个事件上。
第一个是会话开始事件。每次新会话建立的时候,它会先做一点初始化工作,比如建立本次会话的临时记录文件。第二个是会话结束事件。当一次对话结束,它会把这次会话的消息抓取下来,发给模型做一个提炼操作,把对话里的关键事实抽取出来,写入记忆库。Stop事件的触发时机很关键,因为对话结束后才有完整的上下文可供提炼;如果边聊边记,反而容易把中间过程的“试探性结论”当最终结论存下来。
另外要说明的是,claude-mem并不是把原始对话全盘落盘。直接存原始文本当然也可以,但那样查询效率低,而且很多闲聊内容根本没有保存价值。它做的是“提炼后存储”:给你一段对话,抽出一句有事实含义的话。比如对话里说过“这个服务不需要Docker,直接用systemd的unit文件跑就行”,提取出来的记忆大致是“部署方式:systemd,不用Docker”。这种记忆才有长期参考价值。
2.2 提取与存储:为什么用半结构化文本而不是向量库
接下来一个很多人会问的问题:为什么记忆要用“摘要文本加元信息”的半结构化方式,而不是搞一个向量数据库做语义检索?
先说提取阶段。把对话内容变成事实摘要,这一步通常需要调用一次大模型。也就是说,claude-mem在会话结束时消耗的不是一次普通计算,而是一次带有“总结归纳”性质的调用。提取出来的内容会被打上会话ID、时间戳、项目标识,再追加到存储文件里。这里的核心是“事实”而不是“原文”,所以后续查询更像是在翻工作日志,而不是在搜索聊天记录。
再说存储设计。个人工具的场景下,记忆条目的规模一般不会大到非向量库不可。用本地文件加SQLite索引的方式,好处非常明显:文件容易备份、容易查看、便于脚本处理;SQLite负责按项目、按时间、按关键词做检索,性能完全够用。向量检索更适合海量模糊语义搜索,但在我实际使用的体量下,用关键词加元信息过滤已经能覆盖绝大多数需求,维护成本反而低很多。
2.3 MCP服务器:让新会话能主动“想起”过去
MCP这个名字听起来很专业,简单理解就是一套标准化的“模型上下文协议”,让外部数据源和工具能以统一的方式暴露给模型。claude-mem在以MCP服务器形式运行的时候,会向Claude Code声明自己提供哪些能力,比如有一个工具叫“搜索记忆”。新会话里,当模型觉得用户的问题可能和过去的选择有关时,它会自行决定调用这个搜索工具,去记忆库里检索相关条目。
这个设计有个很妙的点:它不会给会话上下文增加额外负担。记忆不会在每次会话开始时就全部塞进来,而是按需查询。查询也不是把整条记忆原文丢给模型看,而是返回匹配的条目摘要。这比“启动时注入一大堆历史记录”的做法清爽得多,既控制了上下文的token消耗,又能让检索结果更贴近当前问题。
3. 从零到一:安装、配置与首次验证
3.1 环境准备和安装方式
开始之前先确认几件事:Python版本要3.10以上,Claude Code本身要更新到支持hooks和MCP的较新版本,还有一个可用的git环境。claude-mem本身是Python项目,所以装起来并不复杂。
我自己优先推荐通过Claude Code的插件市场安装,命令很简单。安装完成之后,插件系统会自动把相关配置写进对应配置文件。如果你不喜欢用插件市场,也可以手动克隆仓库后安装:
# 方式一:通过插件市场安装 > /plugin marketplace add claude-mem > /plugin install claude-mem # 方式二:手动安装 git clone <项目仓库地址> ~/.claude-mem-repo cd ~/.claude-mem-repo pip install -e .这里有一个值得强调的点:如果你选择手动安装,最好用pip install -e .这种可编辑模式,而不是普通安装。因为项目还在快速迭代,可编辑模式可以让你随时拉起最新代码,不用重复执行安装命令。插件市场方式则省心很多,配置和升级都由插件系统代劳。
3.2 在Claude Code配置里挂上hooks
不管用哪种方式安装,最终都要确保Claude Code能认出claude-mem提供的hooks和MCP服务。配置集中在用户的settings.json里,常见路径是~/.claude/settings.json,也可以在项目里放一个.claude/settings.json做项目级覆盖。下面是我本机的配置片段:
{ "hooks": { "SessionStart": [ { "hooks": [ { "type": "command", "command": "python -m claude_mem hooks --event SessionStart", "timeout": 30 } ] } ], "Stop": [ { "hooks": [ { "type": "command", "command": "python -m claude_mem hooks --event Stop", "timeout": 300 } ] } ] }, "mcpServers": { "claude-mem": { "command": "python", "args": ["-m", "claude_mem.mcp"], "env": {} } } }注意看两个timeout的区别。SessionStart只是初始化,几秒钟足够,所以给了30秒。Stop阶段要调用模型做一次提取总结,耗时明显更长,我给了300秒,这个数字在项目大的时候也不要卡太死,宁可宽裕一点也不能让hook超时后静默失败。
命令行里的python -m claude_mem是最稳妥的调用方式。有些人习惯写npx claude-mem或直接写claude-mem,但如果你是用pip安装的,这两种写法都可能找不到命令,最后的效果就是hook没有执行,连个报错都不弹。这也是我踩过的一个坑,后面详细说。
3.3 配置验证:两个会话完成一次“记忆接力”
配置好之后,怎么确认它真的在干活?最简单的验证方法是我称之为“记忆接力”的测试。
第一步,打开一个新会话,正常聊几条消息,然后明确说一句有事实含量的话,比如“这个项目的配置统一用JSON格式,不要用YAML”。第二步,正常退出会话。第三步,重新打开一个会话,直接问“我之前对配置格式有什么偏好”。如果一切正常,Claude Code会通过MCP调用claude-mem的查询工具,返回类似“项目配置统一使用JSON格式”的条目。
这个测试看起来简单,但有一条链路要全部打通才可能通过:hooks要正确触发,Stop要成功执行提炼,记忆要写入本地存储,MCP服务器要能启动,查询工具要能被模型识别并调用。任何一环断了,表现都是“新会话里什么都想不起来”。所以第一次跑通的时候,收益感会非常强——你会明显感觉到,那个新会话不再是一张白纸了。
4. 可调参数与存储细节:记住的内容以什么形态存在
4.1 常用环境变量和运行参数
claude-mem的可调项不少,但真正影响日常体验的就那么几个。下面是我常用的几个环境变量:
| 环境变量 | 默认值 | 作用 |
|---|---|---|
CLAUDE_MEM_ENABLED | true | 总开关,设为false会完全禁用记忆功能 |
CLAUDE_MEM_STORAGE_DIR | ~/.claude-mem/ | 记忆库存储目录 |
CLAUDE_MEM_SEMANTIC_MEMORY | true | 是否允许在会话结束时调用模型做语义提炼 |
CLAUDE_MEM_SCOPE | project | 记忆作用域,项目级或全局级 |
CLAUDE_MEM_EVENTS | SessionStart,Stop | 需要监听的事件列表 |
这里需要解释一下CLAUDE_MEM_SEMANTIC_MEMORY。关闭它之后,claude-mem就不再做摘要提炼了,可能会退回更轻量的关键词截取模式。但代价是记忆质量显著下降。我个人的建议是普通项目开着它,只有在处理敏感内容、不希望对话内容被发给模型离线提炼时再关掉。还要注意,它依赖调用模型进行总结,这个调用成本是真实存在的,如果你每天会话很多,要留意额度消耗。
4.2 记忆库目录和文件结构
默认情况下,记忆库会创建在用户目录下的.claude-mem目录里。你装好之后可以主动去看一眼,而不是等出了问题时再翻。一个典型的目录结构长这样:
~/.claude-mem/ ├── main/ │ └── claude-mem.jsonl ├── review/ │ └── claude-mem.review.jsonl ├── archived/ │ └── ... └── .claude-mem.sqlite3main目录里的claude-mem.jsonl是当前生效的记忆条目,每行一个JSON对象。review目录里的文件则有点类似“待审核区”,某些情况下语义提炼的结果会先落到这里,由更高层级的归档逻辑决定是否转正。SQLite文件主要承担索引和查询职责,负责提供比JSON文件更快的检索能力。
一条典型记忆条目长这样:
{ "session_id": "abc123", "timestamp": "2025-06-18T21:30:00+08:00", "project": "demo-service", "kind": "fact", "content": "部署方式选择systemd,不使用Docker" }这种格式的好处是便于脚本处理。比如你想清理掉某个日期之前的记忆,直接读文件过滤时间戳就行,不需要连数据库。SQLite和JSONL双轨并存,既保留了人可直接阅读的文本,也保留了高效查询的索引,这也是我刚才说“半结构化文本”的原因。
4.3 项目级记忆隔离的工作方式
claude-mem默认按项目作用域管理记忆。什么意思呢?就是你在/path/to/project-a目录下产生的记忆,只会归到project-a的名下;切到/path/to/project-b时,查询记忆不会混进来。这一点很重要,否则你在前端项目里说“我们不用TypeScript”,结果到后端项目里它也在那儿瞎附和。
实际使用中有一个坑:如果两个项目目录同名,比如都叫server,但位于完全不同的父目录下,部分版本的工具可能会把它们识别成同一组记忆。解决方式是在会话里给项目一个明确的标识描述,或者干脆用自定义存储目录把不同项目彻底隔开。记忆隔离做得好,多项目并行才不会乱。
5. 实际使用中收益与踩坑:几周下来我发现了这些
5.1 哪些场景收益最明显
用了大概三周之后,我对“什么东西应该交给claude-mem”有了更清晰的感受。收益最大的场景集中在下面几个:
第一个是断点续作。前一天分析一个内存泄漏问题,分析到一半下了班,第二天开新会话不需要重新把整段分析完整给出来,直接说“接着看昨天的内存泄漏”,它就能从记忆里拉出相关结论,节省了大量上下文重建时间。
第二个是多项目并行。我一天可能要切三四个项目,每个项目的历史背景完全不同。以前切项目要重新粘贴项目背景,现在它能在对应项目的记忆里找到方向,切换成本低了很多。
第三个是方案讨论后的沉淀。有时候我们会在对话里折腾半天,终于确定了一个技术方案。这个“最终决定”过去很容易被丢掉,因为它不在任何文档里,只存在于那次对话中。现在它会自动沉淀成一条事实记忆。下次谁问“这个方案当时是怎么定的”,都能给出一句明确答案。
5.2 我踩过的几个坑,附解决办法
坑一:Python版本过旧导致安装失败。我第一次装的时候机器上还是Python 3.8,安装依赖时直接报错。换成Python 3.11之后一切正常。现在的建议是直接上3.11以上,不要用3.10以下的版本纠结兼容性。
坑二:hooks命令写错,静默失败。前面提到过,我一开始在配置里写的是npx claude-mem,但项目是用pip安装的。结果就是每次会话开始和结束时,那个hook都在后台悄悄失败,日志里什么都没有。排查方法很简单:手动在终端里跑一遍对应命令,如果直接报“command not found”,那就是命令路径不对。
坑三:Windows路径带空格。如果用户名里带空格,比如C:\Users\Zhang San\...,配置文件里的command字段必须加引号。否则Claude Code解析命令时会把路径切断,导致hook启动失败。这个问题在macOS上很少见,但Windows用户很容易踩。
坑四:和其他MCP服务器配置冲突。如果你同时配了好几个MCP服务器,新会话启动的时候偶尔会因为资源标识冲突而报错。解决办法是在mcpServers配置里给claude-mem改一个不冲突的资源前缀名,或者调整加载顺序。这个不是claude-mem独有的问题,但只要接触多个MCP工具,迟早会碰到。
坑五:语义记忆误记敏感信息。开着语义提炼之后,某次高敏感项目的对话里,它把一段涉及密钥来源讨论的内容也记进去了。虽然只是来源讨论,不是密钥明文,但也足够让人警觉。处理方式就是给那个项目单独关闭CLAUDE_MEM_SEMANTIC_MEMORY,或者设置独立的存储目录,隔离升级。
5.3 和项目说明文件的分工
可能有人会问:既然claude-mem能自动记忆,那CLAUDE.md这种东西是不是可以删了?我的结论是:不能,而且要明确分工。
| 分工 | 项目说明文件 | claude-mem |
|---|---|---|
| 内容类型 | 长期稳定、有明确规则的约定 | 动态决策、临时事实、对话中涌现的信息 |
| 更新方式 | 手动维护 | 自动记录 |
| 生效范围 | 当前项目,每次会话可用 | 默认项目级,可扩展全局 |
| 适合记录 | “统一用空格缩进”“提交信息以fix开头” | “这次重构选了SQLite”“用户不推荐某某方案” |
长期规则放在项目说明文件里,稳定而且可控;临时事实交给claude-mem,省心且自动。两条腿走路才是比较合理的用法。如果你把动态事实硬写到说明文件里,过几天就会堆积一堆过时内容;如果你把长期规则交给自动记忆,每次查询还要承担模型唤醒和检索的成本,反而比静态文件低效。
6. 一些边界和我的日常使用习惯
6.1 当前版本的局限
先泼一盆冷水。claude-mem不是万能的,它有几个明显边界。会话结束时做语义提炼需要调用模型,这导致每次对话结束都会有一笔额外的调用消耗,对话量大的时候体感很直接。记忆质量也依赖所用模型的总结能力,模型理解偏了,提取出来的事实就是歪的。本地存储默认明文,敏感项目需要小心处理权限和开关。还有,它的检索本质上是“关键词加元信息”的过滤,不是深层语义推理,所以当你用一些特别抽象的问法时,它可能什么都查不到。
6.2 我目前的日常使用组合拳
结合这些特性,我总结出一套自己的使用节奏:
- 项目开工前,先把该写的长期规则写进项目说明文件,形成静态骨架。
- 日常对话里不做任何额外操作,正常讨论方案,让
claude-mem自动抽事实。 - 每周找时间翻一下记忆目录里的JSON文件,顺手删掉已经过期、没有保留价值的条目。
- 电子表格、日志、密钥相关的高敏感项目,单独设置存储目录,必要时关闭语义提炼。
这套组合拳跑下来最大的感受是:我不再需要煞费苦心地给AI写“记忆提示词”,也不用担心哪天漏写一条背景导致它做出南辕北辙的事情。记忆变成了一种被动沉淀,我只是偶尔抽空整理一下,剩下的时间都在专注做正事。
6.3 一个朴实的结论
claude-mem这个东西,本质上不是给AI模型“加脑子”,而是给自己加了一个不用刻意维护、会自动更新的口述工作日志。它解决的不是“模型够不够聪明”的问题,而是“上下文留不下来”的问题。对像我这样同时经手多个项目、又经常忘记上周决定的人来说,它的价值在于:我不需要“记得去记录”,它会自动把那些容易丢掉的决策碎片接住,然后在需要的时候把它们找回来。