在Claude Code里干活超过一个月的开发者,大概率都会遇到一个逼疯人的瞬间:昨天还在跟AI并肩排查了半天的内存泄漏,今天开个新会话,它又一脸茫然地问我项目的启动命令是什么。这个痛点催生了 claude-mem —— 一个专门给 Claude Code 补上长期记忆的开源工具。它能监听你的对话、自动提取值得记住的信息、跨会话把"相关的过去"重新送到AI面前。如果你重度依赖 Claude Code 干活,或者手上有一两个需要长期维护的中大型项目,这篇文章值得你花十分钟读完。
我会从它的设计动机、记忆分类、接入步骤、背后的检索原理,到我这几个月的真实踩坑经验,一次性讲清楚。不吹不黑,用的时间长了,你自然知道它值不值得装。
1. 为什么我给Claude Code装了一个"外置大脑"
1.1 无状态会话的真正代价
Claude Code 的每次会话本质上都是一张白纸。不是它不聪明,而是 Anthropic 在隐私和简洁性上做了取舍:默认不跨会话保留任何上下文。这个设计带来的体验问题,用过的人都知道:
- 大型项目里,每次开新会话都要重新交代一遍项目背景和技术栈。
- 修过的 bug、调通的配置、确认过的技术选型,换个会话就全部清零。
- 就算在同一个会话里连续聊,上下文一旦拉长,早期的重要决定也会被慢慢挤出窗口。
我印象最深的一次是帮朋友排查线上的接口超时。我们从中间件链路一路查到数据库连接池,再查到网关超时配置,花了整整三个小时才定位到根因。第二天他想让我顺带把修复方案理一下,新会话里的 Claude 居然问我"这两个服务之间是什么关系"。三个小时的心智积累,一夜之间归零,那种感觉真的非常沮丧。
有人会说,那用 CLAUDE.md 不就行了?手动维护一份项目说明,让 Claude 启动时读一下。这确实有用,但它只解决静态知识,记不住你昨天刚做的决定;而且维护它需要额外的心智负担,改动代码后忘了同步文档,CLAUDE.md 就会慢慢和项目脱节。本质上,CLAUDE.md 是"人肉维护的数据库",一旦项目复杂起来,它就跟不上节奏了。
1.2 claude-mem的定位:给AI配一个档案管理员
claude-mem做的事情,简单说就是驻留在 Claude Code 背后,持续监听你和 AI 的对话,把值得记住的信息提取出来,存进本地的向量数据库。等到下一次会话启动时,它会根据当前项目的上下文,自动把相关的记忆重新塞回 Claude 的视野里。
好消息是你不需要手动整理。它更像是给 AI 配了一个档案管理员,而不是让 AI 多了一个需要你喂养的笔记本。哪些信息值得归档、归档到用户级还是项目级、下次聊天要调出哪几份档案,由它来判断。你只管正常干活,剩下的记忆工作交给它。
为什么我不自己写个脚本?其实我一开始真的写过:把关键信息拼进 system prompt,维护一个项目档案文件。但随着项目变大,档案文件变得又臭又长,提示词空间被占掉一大截,还得自己决定每次带哪部分。claude-mem 把"应该带哪部分记忆"这个决策从人变成了检索逻辑,这一步很关键,它让记忆管理真正自动化了。说到底,这种设计天然适合我这种"懒但不笨"的开发者:不想手动维护记忆文件,但希望 AI 像一个连续干了半年的老员工,记得我的偏好和项目的历史。
2. claude-mem到底在记录什么:三类值得留下的记忆
2.1 项目知识、用户偏好、代码约定
用得久了你会发现,claude-mem 并不是把所有对话都存下来,而是按类型筛选。虽然它的界面上不一定分得这么细,但我按自己这几周的使用观察,把记忆大致归成了下面几类:
| 记忆类型 | 典型例子 | 粒度 |
|---|---|---|
| 项目知识 | 项目用 Node 20 + TypeScript,启动命令是 pnpm dev | 项目级(workspace) |
| 用户偏好 | 习惯用断言优先的测试风格,喜欢看简洁的函数实现 | 用户级(user) |
| 代码约定 | 错误处理统一用 Result 返回,禁止裸 throw | 项目级 |
| 决策记录 | 为什么不用 PostgreSQL 而选了 SQLite | 项目级 |
| 防复发提醒 | 上次因为忘记改时区导致调度错乱,这次要提醒 | 用户级/项目级 |
这个分类不是随便分的。项目知识决定了 Claude 能不能在项目里正常干活,用户偏好决定它能不能顺着你的风格来,决策记录则是为了防止它在一个月后推翻你当初深思熟虑的选择。我和同事交流时一致认为,价值最高的其实是决策记录和防复发提醒——这两类恰恰是 CLAUDE.md 最难维护的,因为它们是"动态发生"的信息,靠人肉更新永远慢半拍。
2.2 什么信息才"值得"入库:记忆提取的取舍逻辑
记忆提取的取舍逻辑,我总结有三条观察:
- 重复出现才算偏好。偶尔一次的"这次用下 pytest"不会被当成长期偏好,但出现第三次、第四次时,它就会倾向于沉淀下来。
- 带否定词和修正意味的语句往往是金矿。"不要用全局变量""别用XXX库"这种预防性表达,天然适合做成防复发记忆。
- 用户明确说"记住""以后都这样"这类指令时,优先级最高,通常会直接进入确认流程。
这三条也是它敢做自动提取的底气——它更像一个分类器,而不是录音机。大部分日常对话会被过滤掉,只有高信号的信息才会进入候选记忆,这也是为什么用久了之后,记忆库不会被无意义的闲聊灌满。
2.3 入库前的确认机制:让AI先"问你一声"
候选记忆并不会立刻写死。claude-mem 在准备入库时会发出一个确认请求,通常是询问你要不要记住某条信息,你确认就入库、拒绝就丢弃。这个设计一开始我觉得有点打断节奏,后来才意识到它是一道非常重要的闸门:
- 防止大模型错误提取造成噪音记忆。
- 让你对 AI 到底记住了什么保持知情权。
- 每次确认的瞬间其实都是在做一次"反馈训练",你确认得越多,它提取的准确率会越高。
如果你实在懒得每次点确认,也可以配置成自动接受模式,但我个人强烈不建议一上来就这样。先用两周手动确认模式,你会对什么样的记忆真正有价值形成一个很直观的直觉,之后再决定要不要放开。
3. 三分钟接入:安装、配置MCP、跑通第一个记忆周期
3.1 环境准备:一个运行时、一份Claude Code
claude-mem 是 JavaScript/TypeScript 生态的项目,我当前使用的环境很简单:
- Node.js 20 以上或 Bun,两者都可以运行。
- 已经安装并且登录过 Claude Code。
- 操作系统 macOS 或 Linux;我也在 WSL 里试过,正常。
安装只需要一条命令:
npm install -g claude-mem装完以后先跑一次自检。这一步非常重要,它能提前暴露绝大多数配置问题:
claude-mem doctor它会检查你的 Claude Code 版本、会话日志目录、数据库初始化状态以及 MCP 配置是否就绪。我第一次跑就发现了会话日志目录权限不对的问题,改完再跑就比较顺畅了。需要留意的是不同版本的子命令可能有差异,建议先执行claude-mem --help确认当前版本支持哪些操作。
3.2 两种接入方式:MCP模式和CLI模式
claude-mem 支持两种接入方式。我的建议是优先用 MCP 模式,因为它能让 Claude 在对话中直接调用记忆工具,体验最顺滑。
在 Claude Code 的配置文件里添加 MCP server 注册信息(也可以用claude mcp add命令动态注册),大致配置如下:
{ "mcpServers": { "claude-mem": { "command": "/usr/local/bin/claude-mem", "args": ["--mcp"] } } }注意我这里写的是绝对路径。这个细节后面会展开说,很多时候 MCP 连接失败就是因为它没走你的 shell 环境变量,找不到可执行文件。
如果不想动 MCP,也可以直接用 CLI 模式:启动 Claude Code 时带上--memory参数。这个 flag 会让 Claude 在启动时加载 claude-mem 已经生成的记忆上下文,但没法在对话过程中实时调用记忆工具。我自己的习惯是:平时开发用 MCP 模式,跑一次性脚本、临时调研时用 CLI 模式,省去额外进程的开销。
3.3 跑通第一个记忆周期:三个步骤验证
接入完之后,怎么确认它真的在工作?我建议做一次完整的冒烟测试,走一遍生命周期:
- 在项目目录里启动 Claude Code,确保 MCP server 已经连接成功。
- 随便聊几句项目相关话题,比如"这个项目用什么包管理器",然后人工回答"pnpm"。
- 中途明确说一句:"记住:这个项目统一用 pnpm,别用 npm。"
- 退出这个会话,重新开一个新会话,直接问它"这个项目的包管理器是什么"。
如果一切正常,新会话里的 Claude 会直接给出 pnpm,而且大概率会补充一句"根据我的记忆"。这一步跑通了,说明监听、提取、存储、召回整条链路都是好的。如果它没答上来,不要急着怀疑记忆功能,先回到下一节的排查思路检查配置。
3.4 常用的记忆管理命令
接入并跑通之后,下面几个子命令是我使用频率最高的:
claude-mem stats # 查看记忆总数、类型分布、数据库大小 claude-mem search "启动命令" # 手动搜一条记忆,验证召回效果 claude-mem forget <id> # 删除一条错误记忆 claude-mem ui # 启动本地面板,可视化浏览全部记忆claude-mem ui是我特别喜欢的部分。它会在本地开一个网页,把所有记忆按项目和类型列出来,你能直观地看到 AI 到底记住了多少东西,还能直接在页面上编辑和删除。我做定期巡检时基本都靠它,不用在终端里一条条翻。
4. 记忆背后的工程链路:日志监听、结构化抽取与向量召回
4.1 入库链路:从JSONL会话日志到结构化记忆
Claude Code 每次对话都会在本地落一份 JSONL 会话日志,路径大概是~/.claude/projects/<项目哈希>/目录下。claude-mem 会监听这些日志文件的变更,每当有新的对话内容产生,它就把增量段落抓出来送去抽取。
抽取这一步会用到 LLM。大模型读一段对话,判断里面是否有值得保留的信息,如果有,就输出一条结构化的记忆对象,基本是这样的结构:
{ "type": "coding_convention", "scope": "workspace", "content": "统一使用 pnpm,不用 npm 和 yarn", "source": "session-xxx", "timestamp": "2025-06-11T15:23:00Z" }接下来,这条对象会被向量化,连同原文一起存进本地的 SQLite 向量库。向量化这一步存在的意义,是为了之后能按语义找记忆,而不是只做关键词匹配。如果你把整个链路拆开看,它其实是一个微型的数据管线:采集、清洗、结构化、索引,跟做搜索系统是一个套路,只不过数据源是你的 AI 对话。
4.2 召回链路:新会话启动时,如何"想起"该记得的事
新会话启动时,claude-mem 大致会做这几件事:
- 读取当前项目信息和当前会话的初始上下文。
- 把这段上下文向量化,作为查询条件。
- 在向量库里检索语义最相近的若干条记忆。
- 把命中记忆压缩成一小段摘要,注入到 Claude 的 system prompt 里。
这个过程和搜索引擎很像,但关键点在于它是"语义相近"而不是"关键词相同"。举个例子,查询上下文里只出现了"启动"两个字,而库里有一条"用 pnpm dev 启动开发服务器"的记忆,两者在字面上几乎没有重叠,但语义高度相关,语义检索就能把它捞出来。
这也是我没法用grep或普通文本搜索替代它的原因。在记忆类需求里,用户几乎不会用和存储时一模一样的关键词来触发检索,自然语言天然需要语义匹配这一层。召回率和精确率直接决定 Claude"想起来"的准度,纯关键词匹配在对话场景里太脆弱了。
4.3 为什么召回需要"限额":上下文是稀缺资源
一个容易忽略但很关键的细节是,记忆不能无限注入。上下文窗口是稀缺资源,如果每次启动都塞几十条历史记忆进去,AI 会被大量历史信息刷屏,反而抓不住当前对话的重点。
claude-mem 的召回策略是有预算的:它会尽力选出最相关的 N 条,并且压缩成长度可控的摘要,一般只占 system prompt 的一个小角落。这个平衡点很难拿捏。召回太保守,AI 想不起来;召回太激进,AI 全程在回忆往事不干活。我实测下来,比较理想的状态是每次会话召回三到五条核心记忆,长度控制在半屏以内。宁可少而准,不要多而杂,这是记忆类工具的通则。
4.4 排查链路:为什么记忆库一直是空的
如果你跑完冒烟测试发现新会话里什么记忆都没有,先别急着卸载。按我踩过的坑,绝大多数情况下都是下面这几类问题,按顺序排查基本能解决:
- 先看日志目录。确认 Claude Code 确实在本地写了 JSONL 会话文件,某些受限环境可能关闭了对话记录。
- 再跑
claude-mem stats看记忆数量。如果库里永远为零,大概率是抽取或向量化环节静默失败了。 - 检查向量化配置。如果你把 embedding 指向了外部 API,但 key 没配好或者网络不通,入库时就会悄悄失败,表面上没有任何报错。
- 检查 MCP 连接。在 Claude Code 里输入
/mcp,看 claude-mem 这个 server 是不是绿色的 connected 状态,如果显示失败,就把可执行路径改成绝对路径再试。
我碰到过最诡异的一次,就是用了相对路径claude-mem启动 MCP,终端里一切正常,但 Claude Code 的子进程环境里根本找不到这个命令,导致连接反复失败。改成绝对路径之后,一下就通了。这种问题很隐蔽,因为你的 shell 和 Claude Code 的子进程环境不是一回事。
5. 和官方功能、CLAUDE.md放在一起的正确分工
5.1 官方/remember、CLAUDE.md和claude-mem的边界
Claude Code 官方后来也加入了记忆能力,/remember命令可以把指定内容写进项目记忆文件。很多朋友问我:都有官方功能了,还用得着 claude-mem 吗?我的回答是:两者的定位完全不同,用在哪、怎么用,决定了它们的价值。
| 维度 | CLAUDE.md | 官方 /remember | claude-mem |
|---|---|---|---|
| 维护方式 | 手动 | 手动 | 自动 |
| 内容类型 | 静态铁律 | 静态指令 | 动态经验 |
| 检索方式 | 全量读取 | 全量读取 | 语义召回 |
| 跨会话能力 | 有 | 有 | 有 |
| 维护成本 | 高 | 中 | 低 |
CLAUDE.md 和/remember适合放"铁律",比如架构决策、部署流程、禁止事项,这些内容需要确定性,不能靠大模型去"猜"。claude-mem 适合放"动态知识",比如今天刚改的模块约定、你个人的编码习惯、一次踩坑后的教训。官方方案像你手动整理的笔记本,claude-mem 像 AI 自己帮你整理的档案柜。
两者不仅可以共存,还可以配合:静态铁律进 CLAUDE.md,动态知识交给 claude-mem,定期巡检时再把成熟稳定的内容"升级"写进 CLAUDE.md,完成一次知识固化。我自己是这么维护的,效果比单独用任何一个都好。
5.2 团队协作中的记忆边界问题
这里必须提醒一个容易被忽略的点:claude-mem 的记忆是跟着本机走的。你的数据库在本地,换台机器、换个同事的电脑,记忆就完全没有。所以它目前更适合个人效率场景;如果团队里要做共享记忆,你得自己搞定数据库同步,或者约定大家各自维护 CLAUDE.md。
我还见过有人直接把整个~/.claude-mem目录提交到代码仓库里,想实现团队共享。这里明确不建议这样做——记忆文件里是对话内容的提炼,可能包含敏感的业务信息甚至密钥描述,泄漏风险比代码本身还高。记忆的隐私边界一定要想清楚。
5.3 清理与遗忘:AI也需要"断舍离"
记忆库不是越大越好。用了几个星期后我发现,库里面会出现两类垃圾:一类是过时的决策,比如项目已经从 CommonJS 迁移到 ESM 了,库里还留着"别用 ESM"的旧约定;另一类是大模型误提取的低质量记忆,比如把一次性的任务指令当成了长期偏好。这两类垃圾都会污染召回结果。
我现在的节奏是每两周做一次巡检,打开claude-mem ui,把明显过时的条目删掉,把仍然成立但表述模糊的条目手动改清楚。这个维护成本比 CLAUDE.md 低得多,但它确实存在——自动记忆不等于可以完全放手不管。
6. 实测体验、踩坑清单与配置优化建议
6.1 从"感觉不到"到"回不去了"的转变
要说真实体验,最诚实的话是:刚接入头两天,我几乎感觉不到它的存在。库里空空如也,召回自然什么都捞不到,一切行为和没装之前一样。真正的转折出现在我连续使用了一周之后。
那会儿我在一个跟了两周的项目里重新开了新会话,随口问一句"上次定的接口错误码规范是啥来着",Claude 直接复述出了我当时和它一起确认过的约定。那一刻的感觉确实是"它居然还记得"。从那个节点开始,我再也没法回到无记忆状态下的 Claude Code 了。尤其那种体感不是某个单一功能带来的,而是整体协作默契度上升了一个台阶。
6.2 踩坑清单:MCP路径、embedding静默失败、确认节奏
实操中最大的几个坑,按头铁程度排序:
- MCP 连接失败。现象是
/mcp面板里 claude-mem 是红的,或者对话中记忆工具不可用。根因极可能是子进程环境找不到可执行文件,把 command 改成绝对路径就能解决。 - embedding 静默失败。如果你接了外部向量化接口,key 没配好或网络不稳定时,记忆入库会悄悄失败,
stats里永远是零。遇到这种情况先看日志,再检查 embedding 配置,最后考虑切回本地模式。 - 确认弹窗打断心流。用得越频繁,越觉得每一条候选记忆都要点确认很烦。我的解法是前两个星期用全量确认,之后把"用户偏好"这一类改成自动接受,只对"决策记录"保留人工确认,因为决策类记忆一旦记错,影响最大。
成本方面,默认本地模式的额外开销可以忽略;如果接了云端的 embedding API,按我的对话密度估算,一个月大概是几美元到十几美元不等,看用量。隐私上也不用太担心,默认的记忆存储和检索都在本地完成,对话内容不会因为装了这个工具就多一份外传;只有你主动选择云端 embedding 时,才需要评估一下摘要数据的出向流转。
6.3 给刚开始用的人的三条建议
- 先保持默认配置跑两周,不要一上来就调召回条数和向量模型。默认值对大多数项目是合理折中,你还不了解自己的使用模式前,乱调只会让问题更复杂。
- 认真对待前期的确认环节。每一次"记还是不记"的判断,都是在给它的提取模型做反馈,这也是整体准确率会越用越高的根本原因。
- 有意识地做记忆巡检。每周花五分钟看一次记忆面板,删掉过时条目。这个习惯比你调十个参数都管用。
最后还想补充一个使用心态:记忆不是魔法,它只是把你和 AI 说过的每一句重要的话认真留了底。真正让协作变顺的,是你自己表达得越来越清晰、越来越知道什么样的信息值得沉淀。claude-mem 负责的是把这份"值得"变成可检索的资产,你负责的,是持续往这个资产池里投喂高质量的信息。装好它,然后认真干活就行。