用过 Claude Code 的人应该都有这种经历:前两天刚和它把项目背景、技术选型、目录结构聊得明明白白,过两天开个新会话,它又像初次见面一样问你"这个项目是做什么的"。这不是模型变笨了,而是 CLI 工具默认就是无状态设计——每次会话都是一张白纸,Claude 只能看到当前这个窗口里你输入的内容,以及你主动喂给它的那点上下文。
claude-mem 这个开源工具,就是专门来治这个失忆症的。它做的事情用一句话概括:自动记住你和 Claude 聊过的关键信息,并在新会话开始前把这些记忆重新塞回对话里。它免费、开源、本地优先,不需要把会话记录传到任何云端服务,所有记忆默认存在你自己机器上。
用过之后最直观的感受是:我再也不用做那些重复的"背景复述"了。以前开新会话要重新说一遍"这个项目是干嘛的、用了什么栈、有哪些约定";现在直接说"继续昨天的工作",Claude 就能把上下文接上。这对于手上同时维护好几个项目的开发者来说,节省的不只是几分钟,而是每次思考被打断的节奏成本。
claude-mem 解决的核心问题可以拆成三块:第一,上下文断裂——跨会话的项目信息连续性;第二,偏好丢失——你纠正过的表达习惯、代码风格、命名约定,模型下次照样犯;第三,决策无记录——做过的重要技术选型,过了三周没人记得为什么这么选。这些恰好是纯粹靠 CLAUDE.md 手动维护很难做好的事情,因为文档是静态的,而记忆应该是动态的、随着每次对话不断沉淀的。
1. 从"每次重新自我介绍"说起:Claude Code 的失忆症
先把这个痛点具体化。假设你正在做一个多模块的项目,昨天刚和 Claude 敲定了数据库表结构设计、API 返回格式、还有目录组织方式。今天打开一个新会话,想让它接着写某个模块。如果你不做任何额外操作,Claude 对这个项目一无所知——不知道表结构、不知道 API 约定、不知道你们昨天讨论出的技术决策。你只能靠手动粘贴上下文,或者在 CLAUDE.md 里把所有信息维护得足够完备,才能让对话"接得上"。
问题是,CLAUDE.md 这种方案本身有硬伤。它是静态文本,你每次聊完都得手动更新;而且它容易写得又长又杂,塞进上下文后反而稀释了模型的注意力。我更想要的是那种"自动沉淀、按需召回"的机制——聊过的内容自动沉淀下来,需要用的时候自动出现在上下文里,不需要的时候不占地方。
claude-mem 正好补上这个空位。它的核心理念可以概括成一句话:把 Claude Code 从"无状态工具"升级成"有记忆的协作者"。它不是简单地缓存聊天记录,而是对会话内容做结构化处理,把真正值得长期记住的信息提炼成独立条目,然后在合适的时机重新注入对话。
我在第一次配置成功、看到 Claude 在新会话里主动说出"根据之前的项目记忆,当前模块的技术栈是 Python 3.11 + FastAPI"时,确实有种"这工具成了"的感觉。对于长期用 Claude Code 干活、又不想每天反复交代背景的人来说,这个体验提升是质的。
2. claude-mem 的运作链路:抽取、归档、检索、注入
要理解它为什么好用,得先理解它的工作链路。claude-mem 本质上是由四个环节组成的一条流水线:抽取(Extract)、归档(Archive)、检索(Retrieve)、注入(Inject)。这四个环节分别解决"记什么、存哪里、怎么找、怎么用"的问题。下面挨个拆。
2.1 记忆抽取:靠模型而不是靠人
抽取是整条链路里最关键的环节,也是最容易被忽略的。很多人以为记忆工具就是"把聊天记录存下来然后全文搜索",但 claude-mem 不是这么干的。它会在每段会话结束后,调用一次模型对整段对话做结构化总结,把散落在对话里的关键信息提炼成一条条"记忆"。
我理解它的设计逻辑是这样的:全文存储有两个硬伤,一是信息密度太低,1000 条聊天记录里真正值得长期记住的可能只有 20 条;二是检索噪音大,搜一个关键词会命中一堆无关的上下文。而让模型做抽取,相当于用 AI 筛选 AI 的产出,能把噪音先过滤掉一层。
claude-mem 抽取出来的记忆大致分几类:长期事实(项目架构、技术栈、关键路径)、用户偏好("变量命名用下划线不要驼峰""日志要中文")、技术决策("为什么选 SQLite 而不是 Postgres")、以及一些待办事项和重要约束。分类之后,每条记忆会附带时间戳、来源会话 ID 和置信度相关的元信息。
有朋友问过我:每次会话结束都跑一次抽取,会不会很慢、很费钱?这取决于你抽取用的模型。如果本地有 Ollama,哪怕是 7B 级别的模型也能干这个活,跑一次几十秒,成本近乎为零;如果用云端模型,一般会限制只对最近 N 条消息做总结,不会把整个会话全量丢给模型。
2.2 记忆落地:本地文件优先
抽取出来的记忆总得有个归宿。claude-mem 比较实在的一点是坚持本地优先,默认情况下记忆库就落在你自己机器上的一个目录里。它支持两种后端:一种是 JSON 文件目录,一条记忆一个文件,方便直接翻看和手动编辑;另一种是 SQLite 单文件,适合记忆量大了以后做结构化查询和索引。我自己日常用的是 JSON 目录,因为折腾起来直观,出问题也能用文本编辑器直接修。
一条记忆在存储层面大概长这样:包含记忆内容本身(Markdown 文本)、类型标签(fact / preference / decision / todo)、创建时间、来源会话、相关文件路径等等。你可以把它理解成一张张"知识卡片",而不是一团聊天记录的泥巴。
这个设计带来的一个好处是:记忆库是可以手动干预的。Claude 抽错了一条记忆,你直接删掉或改掉那个 JSON 文件就行,不需要去翻聊天记录。和"把所有历史塞进系统提示词"的方案相比,这种结构让记忆变得可审计、可修正。这也是我后来一直坚持用它而不是自己写全套 prompt 管理的原因之一。
2.3 记忆召回:不是把所有历史都塞进去
如果说抽取解决"记什么",检索解决的就是"拿什么出来"。这里有个很容易犯的直觉错误:以为记忆越多越好,最好把全部历史都注入新会话。这恰恰是很多记忆插件让人哭笑不得的地方——上下文塞爆,模型反而什么都注意不到。
claude-mem 的检索逻辑是"按需召回"。它会对记忆库里的条目做语义索引,在新会话开始或者对话过程中需要的时候,根据当前任务关键词检索出最相关的几条记忆,而不是全量倒给你。语义检索靠的是 embedding 向量:每一条记忆都会被转成一个向量,查询时把当前问题也转成向量,然后找余弦距离最近的条目。
我在本地用的是 Ollama 里的 embedding 模型来做向量化,完全离线,速度也很快。如果你不想折腾本地模型,也可以配置成调用云端 embedding API,效果类似。检索深度和召回条数都是可配置的,我一般控制在 5 到 10 条左右——够用,又不会在系统提示词里占太多分量。
2.4 记忆注入:新会话开始前的"小抄"
最后一步是注入。claude-mem 会在新会话启动时,把之前召回的相关记忆整理成一段"简报"(briefing),注入到会话的上下文里。你可以把它想象成开会前秘书递给你的备忘小抄:不用把整本会议记录摆在桌上,只需要列出"对方是谁、上次谈到哪、有哪些关键结论"就够了。
具体到 Claude Code 的集成方式,常见做法是配置一个会话启动钩子(SessionStart hook)。每次新会话开始时,自动执行一次 claude-mem 的召回和注入命令,把生成的简报文本塞进上下文中。这样对用户来说完全无感——你甚至不需要手动输任何提示词,Claude 就已经"知道"你是谁、项目是什么了。
注入的格式也很有讲究。好的简报应该是"给模型看的便签",而不是一大段聊天记录。我见过类似项目里注入的内容风格大概是:先一行"以下是关于当前项目的已知记忆,供参考",然后列出记忆条目,最后加一句"如果与用户当前说明冲突,以用户当前说明为准"。最后这句话非常重要,防止旧记忆把新指令带偏。
3. 从零部署:安装、初始化和接线
原理讲完了,下面是实操部分。我尽量按通用流程写,因为 claude-mem 这类工具迭代很快,不同版本细节会有差异,具体命令以项目仓库 README 为准。这里主要讲清楚每个环节在做什么、需要注意什么。
3.1 环境准备:本地模型与运行时
先盘一下前置依赖。claude-mem 本身依赖一个运行时环境(具体需要 Python 还是 Node.js 看版本),以及一个用于做摘要和向量化的模型。我的建议是:先把 Ollama 装好,拉一个聊天模型用于抽取记忆,再拉一个 embedding 模型用于语义检索。
这里有个小经验:抽取模型和 embedding 模型可以分开。抽取记忆需要一定的文本理解能力,7B 以上的模型比较稳;embedding 模型则不需要太强,像 nomic-embed-text 这类就够用。如果你手里的机器跑不动大模型,也可以退一步:抽取用云端的 API,检索用本地 embedding,这样成本和隐私能取得一个相对平衡。
环境准备阶段最容易踩的坑是:忘了把模型服务做成开机自启,或者没确认 API 地址能被 claude-mem 访问到。本地模型服务默认监听某个固定端口,如果你改了端口,记得在 claude-mem 的环境变量里同步修改。磨刀不误砍柴工,这一步多花十分钟,后面省的是好几个小时的排查时间。
3.2 安装 claude-mem 与初始化记忆库
安装环节没什么玄学,把项目源码拉下来,按照 README 装好依赖,然后跑初始化命令就行。我这边一般用一个干净的目录专门放工具源码,尽量不把依赖装到全局环境里,避免和其他工具打架。
安装完成后,第一次使用前需要初始化记忆库。初始化命令会创建默认的数据目录、生成配置文件、并且在你指定的路径下建好存储后端。配置文件里面会涉及:用什么抽取模型、用什么 embedding 模型、召回条数上限、存储后端类型、记忆目录位置等。默认值一般够用,但有两项我建议第一时间改掉:一是把记忆库目录改到你的工作区之外,别让 claude-mem 把记忆库建在项目目录里,不然以后做版本管理或者换机器会很难受;二是把生成记忆条目的语言设成你习惯的沟通语言,后续阅读和管理都方便很多。
初始化完成后,可以用一条查看记忆库状态的命令验证是不是真的能跑通了。我当时踩过的一个坑是:配置里填写的 Ollama 模型名拼错了,claude-mem 不会立刻报错,而是到第一次真正抽取记忆的时候才静默失败。所以建议初始化后立刻手动触发一次"记忆抽取"或"记忆列表",确认链路是通的再开始正式使用。
3.3 接入 Claude Code:MCP 与 Hook 双重接线
这是整个部署过程中最关键的一步:让 Claude Code 真正调用到 claude-mem。目前主流做法是两条线:一是把 claude-mem 注册成 MCP(Model Context Protocol)服务,让 Claude 在对话中能主动调用它提供的记忆工具;二是配置会话开始钩子,让记忆在新会话启动时自动注入。
MCP 配置大概长这样(不同客户端配置格式略有差异,核心字段一致):
{ "mcpServers": { "claude-mem": { "command": "claude-mem", "args": ["mcp"], "env": { "CLAUDE_MEM_BACKEND": "json", "CLAUDE_MEM_DATA_DIR": "/path/to/memory-store" } } } }说白了就是告诉 Claude 客户端:这个叫 claude-mem 的服务,你通过执行claude-mem mcp命令来启动,地址和配置在这里。注册完之后,Claude 在对话中就能使用 claude-mem 暴露的工具了,比如按关键词搜记忆、添加新记忆、列出最近记忆等。
会话启动钩子的配置则负责"自动注入"这件事:
{ "hooks": { "SessionStart": [ { "matcher": "session_start", "hooks": [{ "type": "command", "command": "claude-mem recall --inject" }] } ] } }这段配置的意思是:每次新会话开始,自动执行claude-mem recall --inject,把召回的记忆整理成简报注入上下文。两条线配合起来,就能实现"对话中随时查记忆 + 会话开始自动带记忆"的效果。这里提醒一句:钩子和 MCP 的字段名在不同版本里有可能不一样,配置后务必先开一个新会话验证注入是否生效,别等真干活的时候才发现记忆根本没进来。
4. 实测体验:一个跨三天的项目会话复盘
光讲原理和配置有点干,聊一段我这边的真实使用场景吧。前阵子用 Claude Code 做了一个小工具,从立项到开发跨了差不多三天,整个过程中 claude-mem 一直开着,效果挺能说明问题。
第一天晚上,我在会话里和 Claude 讨论需求,确认了工具的核心定位、技术栈(Python + SQLite)、模块划分,还有几条编码约定,比如"所有对外接口返回统一 JSON 结构""日志统一走 Python logging 不要用 print"。聊完以后随手看了一眼记忆库,发现这些信息已经被自动抽取成了好几条 fact 和 preference,分类还挺准。
第二天白天打开电脑,我没有重复介绍项目背景,直接输入"继续昨晚的需求,先把数据库层写出来"。Claude 居然知道我们昨晚定的模块划分方案,直接按约定好的接口格式开始写。我特意问了一句"你怎么知道要用 JSON 结构",它回答说相关信息来自会话记忆里的项目约定。那一刻觉得这个记忆链路是真的在工作。
第三天的时候,我换了一个全新的会话,想让它根据前两天的核心逻辑写一段整体说明。由于记忆库里已经沉淀了若干条"技术决策"类型的条目,Claude 甚至能说出"当时为什么选 SQLite 而不是 Postgres,是因为不需要并发写入和多进程访问"这种只有上下文连续才能得出的结论。也就是说,决策过程本身也被记住了,而不只是结论。
我用一张表总结一下开启前后的差异,比较直观:
| 场景 | 开启前 | 开启后 |
|---|---|---|
| 新会话开场 | 需要复述项目背景、技术栈、约定 | 直接说"继续昨天的活" |
| 代码风格一致性 | 每换会话都可能回退 | 约定作为记忆注入,持续生效 |
| 技术选型回顾 | 凭印象,容易记错原因 | 决策条目直接可查 |
| 上下文窗口占用 | 靠手工粘贴,越多越乱 | 按需召回,占用可控 |
当然,这三天里它也出过一些幺蛾子,比如把一次闲聊中提到的"也许可以试试 XX 方案"自动归类成了技术决策,导致后面两个会话都以为我们定了那个方案。这种误抽取问题我放到下一节细说,但它提醒了我一个事:记忆工具的注入内容必须写得足够"像建议而非命令",否则 AI 会把旧记忆当成硬性约束。
5. 用了一段时间后,我踩过的一些坑
这部分算是我认为最有价值的内容。一个记忆工具好不好用,往往不是看它功能多强,而是看它会在什么地方让用户心态崩溃。我踩过几个比较典型的坑,挨个说。
5.1 记忆污染:Claude 把闲聊和正经结论混在一起
最让我头疼的问题是记忆污染。所谓污染,就是记忆库里混进了不该成为长期记忆的内容——比如随口一提的想法、中途推翻的旧方案、情绪化的表达。claude-mem 的抽取模型没有"主次判断"能力,它倾向于把看起来信息量大的句子都当成记忆,于是"也许可以""说不定"这类试探性表述很容易被固化。
我一度被"也许可以试试 XX"害得不轻:Claude 连续两个会话都拿这条记忆当既定结论用。后来我的处理办法有三个:第一,重要结论在对话里尽量用明确语气说死("我们确定用 XX 方案"),给抽取模型一个明确的信号;第二,养成定期翻记忆库的习惯,把可疑条目及时删掉;第三,在注入简报的提示词里加一句"记忆条目仅供参考,如与当前讨论冲突,以当前讨论为准"。这三招下来,污染的影响基本可控。
5.2 本地 embedding 模型的选择与检索质量
语义检索的质量直接决定记忆召回得准不准。一开始我图省事用了默认的 embedding 模型,发现检索结果经常张冠李戴——搜"数据库选型"能召回到"日志格式规范",因为它们在某一条记忆里同时出现过。后来换成专门的 embedding 模型,召回质量明显提升,但这个提升不是免费的:模型文件好几个 GB,内存占用也上去了。
这里给个实用建议:如果你的记忆库以技术内容为主,检索质量比速度更重要,可以首选通用或技术领域表现好的 embedding 模型;如果你只是几百条小规模记忆,其实用关键词深度检索也够,没必要为了向量化引入额外复杂度。另外,检索召回条数别贪多。我之前调到 20 条,结果注入简报又长又杂,模型反而抓不住重点,调回 8 条反而更准。
5.3 隐私与存储清理:记忆库里那些不该留的东西
本地优先这个设计我其实挺喜欢,但它有个副作用:记忆库会积累一些你并不想长期保存的敏感信息。比如我在某个会话里贴过一段数据库密码相关的配置,虽然只是演示用,但 claude-mem 不会区分"这段对话有没有价值",它可能就把里面的关键短语抽成了记忆。
所以我的习惯是:每隔一两周,打开记忆库目录扫一遍,把涉及密钥、密码、token、个人信息的内容手动删掉。如果你用的是 SQLite 后端,就通过管理工具做删除。另外,记忆库目录的权限也要留意,别让它被其他进程或服务意外读取。安全性上,claude-mem 默认不上传数据到云端,但"本地存储"不等于"数据安全",该做的访问控制还是要做。
5.4 注入长度与 token 成本的控制
最后一个坑是关于"度"的问题。记忆注入不是越多越好,上下文窗口是有限的资源。如果每次会话都注入十几条长记忆,加上系统提示词和工具定义,留给真正任务的空间就被压缩了。更麻烦的是,注入内容太碎会分散模型注意力,让它频繁去记忆里找答案而不是直接思考。
这个问题的解法在配置层面:一是控制召回条数,我建议 5 到 10 条;二是给每条记忆设置最大长度,超过长度的在注入前做截断或摘要。如果你用云端模型按 token 计费,还得关注每次会话产生的注入成本。我实测下来,把记忆条数控制在 8 条以内、每条记忆压缩成两到三行时,性价比是最高的——召回准确率和上下文占用之间有一个比较舒服的平衡点。
6. 最后分享三个实用小习惯
文章最后聊三个我到现在一直在用的小习惯,不算什么大道理,但对记忆工具的使用体验影响很大。
第一个习惯是"会话结束前主动收口"。以前我聊完就关终端,后来发现记忆里全是散乱的中途想法。现在我会有意识地在大任务告一段落后,用一两句话总结当前结论,比如"好,那就定下来用 XX 方案,明天开始写核心模块"。这种明确的收口语句,会极大提高 claude-mem 抽取出的记忆质量。
第二个习惯是"名字要起好"。如果终端支持会话别名或者多目录配置,我会把每个项目或任务的会话名称固定下来。这样记忆库里的来源会清晰很多,检索时也能按项目维度过滤。随手翻记忆库的时候,看着项目名加日期的整齐条目,比一坨无差别会话记录舒服太多。
第三个习惯是"记忆像代码一样需要 review"。我现在每周花五分钟浏览一眼记忆库的变化,删掉过时条目、修正错误分类、合并重复信息。这五分钟花得很值——它保证了注入给模型的记忆始终是高质量的。毕竟工具再聪明,也需要用的人偶尔管一管。claude-mem 给我最大的感触是,它把"模型会遗忘"这件事从一个让人抓狂的缺陷,变成了一个可管理的常态。