1. claude-mem 是什么:为什么我会为它写一篇博客
1.1 一句话定义:给 Claude 装上“第二大脑”
如果你在 Claude Code 里反复说过“记住这个端口号”,然后新开一个会话它又一脸茫然,claude-mem 就是为这个痛点来的。简单说,这是一个给 Claude Code 增加长期记忆能力的 MCP 工具,它把你在终端里和 Claude 的对话记录、技术决策、个人偏好和项目状态自动保存到本地数据库,等到下一次会话开始时,再把那些真正相关的记忆自动捞回来,塞给模型参考。
我最早看到这个项目名的时候,第一反应是“又一个记忆插件”。但真正上手之后,发现它解决的问题比想象中更底层。Claude Code 默认是“会话隔离”的,每个新终端窗口都是一张白纸。这本身是为了安全,因为不残留上下文,但代价就是你得一次又一次地重复背景信息。你昨天刚跟模型敲定了项目的架构方案、数据库选型、错误码规范,今天重新打开终端,它什么都不记得。你只能把一大段背景重新贴到提示词里,或者写进一个 AGENTS.md 文件让模型每次加载。AGENTS.md 能解决固定知识,但解决不了“上次那个临时调试结论”“你当时为什么排除了 Redis”“部署脚本里留了哪个隐藏参数”这类动态信息。
claude-mem 这一类工具,本质上是在给模型做一个可检索的长期记忆层。它不试图扩大上下文窗口,也没有那个本事,而是把信息放到模型的外部,等需要时再定向注入。这个思路跟 RAG(检索增强生成)非常像,只不过它处理的不是文档,而是你和 AI 的交互记录。
1.2 它和普通插件、脚本的本质区别
市面上有不少记忆工具,常见做法是“手动记录模式”:你在对话里跟模型说“记住 xx”,模型就把它写到一个文件里,下次再读。这个方案当然能用,但问题在于依赖模型“自觉”。模型确实能记住一些东西,可它不知道哪些信息值得长期存,也不知道什么时候该忘,更不会自动从一段长长的对话里提炼出结构化条目。
claude-mem 的不同之处在于,它工作在模型之外,是一个独立的 MCP 服务。MCP(Model Context Protocol)是 Anthropic 推动的一种标准接口,相当于给 AI 客户端插了一排外接设备。claude-mem 把自己伪装成一个带记忆功能的“外接硬盘”,Claude Code 在对话过程中会主动向它读写数据。它捕获的信息包括用户消息、助手回复、工具调用结果,甚至你手动标记的重点片段。采集之后,它会做清洗、筛选、向量化,再落到本地数据库里。检索的时候不走关键词硬匹配,而是做语义相似度搜索,所以哪怕你换了种问法,它也能把藏在记忆底下的相关内容翻出来。
插件和脚本解决的是“某一次记忆”,claude-mem 解决的是“持续的记忆生命周期”。有写入、有索引、有查询、有注入、有清理。它不是模型脑子里的一个插件,而是模型外面的一套独立系统。这套系统的设计思路,恰恰是所有把大模型接入真实工作流的人都需要认真理解的。
2. 为什么要做长期记忆:Claude Code 的“金鱼记忆”痛点
2.1 会话隔离到底有多烦
我刚开始用 Claude Code 的时候,最强烈的感受是:这家伙很强,但太健忘。有一次我给一个老项目补测试用例,上午刚和它讨论完项目里某个模块的奇奇怪怪的历史原因,下午因为终端崩溃重启,新会话里它居然建议我重构那个模块,理由还是“这个模块设计很奇怪”。我当时的内心:上午不是跟你讲过了吗?这个模块奇怪是因为接了个遗留系统啊。
这种对话隔离对日常问答没什么影响,但用来做长期项目就很痛苦。你每开一个新会话,都要先重新建立“我们正在做什么、已经做到哪一步、有哪些约束”这个心智模型。你可以把信息全写在提示词里,但提示词有长度限制,而且写太多容易把模型带到沟里。你也可以维护一个设计文档,但设计的演变过程、当时的权衡、为什么否掉某个方案,这些细节几乎不会写进最终文档。这些恰恰是需要记忆的地方。
你可以说,每次开会话前花两分钟复制一段项目背景就够了。但如果一天要开十几个会话,每个会话都要重复同样的事,累积下来的浪费非常可观。更糟糕的是,你不可能保证每段背景描述都完全一致。今天的描述和昨天的有出入,模型的行为就会飘。记忆工具的核心价值不是“方便”,而是让 AI 的上下文保持连续性和一致性。
2.2 上下文窗口不是记忆,而是“临时工作台”
很多人把上下文窗口理解成模型的记忆容量,这其实是个误解。上下文窗口更像是一张白板,写在上面的东西模型暂时都能看到,但白板一擦(会话结束)就全没了。你往提示词里塞的东西再多,也只是在这张白板上写字,并没有真正变成模型的长期知识。
Claude Code 甚至会在一个会话内自动压缩历史消息,把老内容总结进一个摘要。这个机制很实用,但代价是细节会丢。比如两天前某个工具返回的一条关键错误信息,就算它还留在摘要里,也早就被压缩得一干二净。真正重要的信息,应该跳出上下文窗口,落进一个独立的、持久的存储空间。
这里可以类比人的记忆方式。你不会把今天中午吃了什么、下午改了哪个文件、晚上提交了什么代码全都清晰地记一辈子。你能记住的是“哪些东西对我长期有用”和“哪些东西值得反复拿出来用”。AI 也一样,上下文窗口应该只负责当前这个任务集,而长期记忆应该由外部系统管理。这也解释了为什么所有 AI 记忆工具都强调“检索”,而不是“全量保存”。全量保存只会把模型淹没在海量信息里,无关信息越多,检索到关键信息的概率越低,模型输出质量越差。
2.3 记忆的三个粒度:临时、短期、长期
要理解 claude-mem 的设计,先要分清记忆的粒度。
第一层是会话内临时记忆。这是上下文窗口的自然能力,模型能记住当前这个会话里你说过的所有内容,但前提是内容没有超出窗口被压缩掉。这一层最适合放“当前任务”的临时细节,比如这次要改哪几个文件、刚才测试输出是什么。
第二层是跨会话的长期记忆。这层要解决的是“你上次告诉我的事实和偏好”。比如“这个项目使用 pnpm,不要用 npm”“数据库迁移脚本必须经过 review 才能执行”“我倾向于保持文件结构扁平”。这些信息不会经常变化,也不依赖当前具体任务,但每次会话都需要。它们适合放进 AGENTS.md,也适合被 claude-mem 这种工具自动捕捉、自动注入。
第三层是工作区或项目级的可检索记忆。这层更像一个庞大项目知识库,信息量极大,不可能全量注入。正确做法是把所有交互记录都保存下来,建好索引,然后等用户提问或新任务发起时,按相关性召回一小部分。claude-mem 的定位很清晰:第二层和第三层它都要做,并且把第二层的“自动注入”和第三层的“按需检索”结合到了一起。这个思路是对的。如果你只用自动注入,那就只能放少量高确定性事实;如果你只有按需检索,模型又不知道什么时候该去查。两者配合,才是完整记忆方案。
3. 核心原理拆解:记忆是怎么被记录、检索和注入的
3.1 整体架构:采集、存储、检索、注入四段式
claude-mem 的架构可以拆成四条链路,理解了这四条链路,你就理解了它所有配置项的作用。
第一条是采集链路。它作为 MCP 服务挂在 Claude Code 旁边,每当消息循环发生一次交互,它就能拿到事件数据。Claude Code 的每条用户消息、助手回复、工具调用结果,都会经过 MCP 层的通知。claude-mem 在这时截获内容,判断有没有值得保存的东西。
第二条是存储链路。截获的内容要变成可检索记忆,不能只是存一堆原始日志。常见的实现是把文本切成片段,做嵌入(embedding)计算,再把向量和原文一起存入本地数据库。轻量级方案会用 SQLite 加向量检索插件,也可以直接用独立的向量数据库。
第三条是检索链路。每次 Claude Code 准备开始一轮新对话,或者用户发消息要求“回想相关内容”,claude-mem 会把触发文本也做嵌入,然后拿这个向量去记忆库里搜索最相近的片段。搜索不只是“哪个词出现过”,而是“哪些内容跟当前话题语义相近”。
第四条是注入链路。检索到记忆后,还要把结果拼到模型的输入里,通常加在 System Prompt 后面,形成一段“记忆提示”。这段内容不能让模型当成普通对话,也不能让它过度服从记忆里的错误结论,所以注入时通常会有专门指令约束。四条链路依次跑通,才算完成一次完整的记忆生命周期。
3.2 写入端:不是所有内容都值得记
很多人的直觉是:把所有对话记录都保存下来,这最简单。但 claude-mem 真正有趣的地方在于“筛选”。保存所有信息很容易,但会让数据库变成垃圾场,检索时全是噪音。
以我找到一个比较通用的实现为例,写入端会先做两层过滤。第一层是事件级别过滤:不是每条消息都触发保存。例如连续的问候、模型复述题目、知识性提问这类内容通常不保存。第二层是内容级别提取:从有保存价值的消息中抽取关键词、实体、决策句。常见的做法是先用规则判断,比如出现了“记住”“注意”“以后都用”“不要用”这类标记性词语;再用模型本身做一次摘要或分类。这两层下来,真正入库的往往是“技术选型结论”“项目约束”“用户偏好”“错误排查经验”这四类。
写入频率也需要控制。Claude Code 一次会话可能产生几十轮消息,每轮都做嵌入计算会拖慢体验。实际项目里,claude-mem 通常会做批处理和异步写入,对话过程中先攒着,等闲置时再统一处理。这个设计在实时性和性能之间做了取舍。
判断“是否值得记”这件事,本质上是可以用规则做得很好的。比如“这个端口是 3100,别搞错”就直接存下来;“今天天气不错”就没必要存。复杂一点的偏好,比如“我喜欢更简短的回答”,则可以用一类正则匹配“我喜欢/我习惯/我觉得”等句式。但规则总会有漏,所以不少实现还会让模型定期扫描对话,把规则漏掉的重要内容二次提取。这有点像你临时看一眼聊天记录,把里面重要的事挑出来贴到笔记软件里。
3.3 检索端:如何找到“那一条”记忆
写入做好之后,检索质量就成了体验的分水岭。为什么很多记忆插件“记得住但想不起来”?因为检索太弱,只用了字符串匹配。你存下“项目使用 pnpm”,下次问“我们用什么包管理器”,关键词不重叠,匹配不到,就白记了。
claude-mem 这类工具能有效检索,靠的是向量嵌入。将文本转成浮点向量,计算余弦相似度或内积相似度。查询时,把当前问题或提示词也转成向量,然后在库里查最接近的几条。这个方案对同义表达非常宽容,“包管理器”和“pnpm”虽然不是一个词,但在语义空间里距离足够近,能被召回。
不过向量检索不是万能的。它会忽略精确的一一对应关系。比如你问“那个在 8080 端口的服务是什么”,向量搜索可能召回几条包含“服务”和“端口”的信息,但偏偏漏掉包含正确端口号的那条。比较好的实现是“混合检索”:先用关键词或 BM25 做一次强匹配,再用向量检索做语义扩展,最后把两边的结果融合去重。如果你要基于 claude-mem 做二次开发,混合检索是必须优先考虑的设计。
检索结果的处理也很讲究。不只是挑 Top-K 条返回,还要做去重和排序。同一条信息可能在不同会话里被保存了五次,如果直接都注入,模型反而被绕晕。常见做法是合并相似记忆,保留最近一次的内容和时间戳。季节性强、时效性强的信息(比如“今天下午五点要发布”)还需要根据时间做衰减,否则三个月后模型还在提醒你发布一个早已过期的版本。
3.4 注入端:以怎样的姿势塞进上下文
检索到记忆之后,最粗笨的做法是把所有结果一股脑加进 System Prompt。这样做有风险:如果记忆条数太多,会占用大量上下文,挤压真正任务的处理空间;如果记忆与当前任务无关,模型会被带偏,开始引用不相干的旧习惯。
所以注入端要做三件事。控制数量:常见做法是每个会话只注入 5 到 10 条高相关记忆,并且每条记忆只保留一小段摘要,不确定是否相关的记忆不注入。控制位置:记忆应该放在 System Prompt 末尾,与用户任务保持分隔,这样模型会把它当背景知识而不是直接指令。控制指令:注入时会告诉模型“以下内容来自以往对话,如果与当前任务相关可以参考,如果不相关请忽略”。这个“可参考可不参考”的措辞非常重要,给模型留了判断空间,而不是让旧记忆强制覆盖当前任务。
有些实现还会做“主动记忆提示”:在用户提交问题前,claude-mem 先生成一段“记忆检索报告”,问模型“当前任务是否需要查询历史记忆”。这样可以减少每次检索的开销,只在必要时才进行完整搜索。这个设计对长会话特别有价值,因为不是每一轮都需要记忆,大部分时候当前上下文足够。
4. 实操上手:从安装到日常使用
4.1 环境准备与安装
要跑 claude-mem,电脑上基本要有 Node.js 和 Python 环境,具体看这个工具的主实现语言。多数同类项目喜欢用 Python 跑语义检索相关的库,MCP 服务则通过标准输入输出与客户端通信,所以对环境要求不高,普通开发机上都能跑。
安装命令一般是这样:如果你用的是 npm 发布版本,npm install -g claude-mem;如果是源码安装,就要先把仓库 clone 下来,再执行pip install -r requirements.txt。我个人更推荐用 npm 或 pip 安装现成版本,因为这种工具迭代快,源码安装后要手动跟踪更新,很容易被新版本的不兼容配置坑到。
装完之后先别急,跑一下版本号命令确认安装成功,再找到配置文件的位置。claude-mem 的数据通常存在用户目录下的一个隐藏文件夹里,比如~/.claude-mem/,里面放着 SQLite 数据库、索引文件和日志。确认这个目录可写、有足够磁盘空间,就算环境准备完成了。
4.2 配置 MCP 服务:让 Claude Code 找到它
claude-mem 和 Claude Code 之间不是靠“粘贴 API Key”完成对接的,它走的是 MCP 协议。要在 Claude Code 里启用它,通常需要改项目根目录下的.mcp.json文件,或者用户级配置文件。
一个典型的 MCP server 配置长这样:
{ "mcpServers": { "claude-mem": { "command": "claude-mem", "args": ["serve"], "env": { "CLAUDE_MEM_CONFIG": "/path/to/config.json" } } } }如果你在项目级配置,Claude Code 只会在启动当前项目时加载 claude-mem;如果你在用户级配置,所有项目都会加载。我建议先只配置到项目级,跑熟悉了再考虑全局启用。改完配置后,必须重启 Claude Code,MCP server 才会被识别和拉起。启动后在客户端里看到 claude-mem 已连接,说明对接成功。
4.3 验证记忆是否真正生效
配置好之后,怎么确定它真的在干活?你可以先用一个测试对话:告诉 Claude Code“记住,这个项目部署时要用make deploy命令,不要直接跑 docker compose”。然后退出会话,重新打开终端,再问“这个项目怎么部署”。如果 claude-mem 生效,Claude 的回答里就应该出现make deploy,并且可能会顺带说“根据你之前的对话记录”。
如果没有任何反馈,先排查两个地方。第一,打开~/.claude-mem下的数据库文件,用 SQLite 工具查一下是否有新写入的记录。第二,查看 MCP 服务日志,确认 Claude Code 是否真的能调用到 claude-mem 的方法。很多情况下配置没问题,但环境变量没传给 MCP server,导致服务启动后读不到正确配置,静默失败。
还可以用 claude-mem 自带的命令行做一次手动搜索。比如claude-mem search "deploy command",如果命令行能搜到记忆,说明存储和检索链路都通,问题只出在注入侧;如果命令行也搜不到,那就要查写入链路了。
4.4 日常使用习惯建议
claude-mem 不是装完就万事大吉的。它跟人一样,记忆库需要整理。我自己的使用习惯是每个星期花五分钟清理一次。
第一,定期翻看最近记忆,删除那些已经失效的决策记录。比如项目从 pnpm 切到 npm 之后,旧的“不准用 npm”记忆就是有害的,必须删掉。第二,对重要的记忆内容主动补充标签。有些实现支持给记忆分组或打标,这就相当于给记忆建立分类目录,检索精度更高。第三,如果你发现同一信息被记了很多次,手动去重比等系统自己合并更可控。
日常对话里,也不要完全依赖自动捕捉。关键信息我倾向于用显式标记,比如直接说“claude-mem 记住:本项目的环境变量统一放.env.local”。显式标记能显著提高写入准确率,自动捕捉虽然省事,但它不一定分得清你是在陈述事实还是随口一提。
5. 我踩过的坑:数据量、隐私与幻觉
5.1 数据量膨胀:从几百条到几百兆
记忆工具跑一段时间后,最容易遇到的问题是数据量失控。我有一次跑了两个多月,发现~/.claude-mem目录占了快六百兆。打开数据库一看,里面存了大量重复内容、调试日志、几乎没什么信息量的普通对话。
数据量膨胀带来的直接后果是检索变慢,每次搜索都要扫描几万条向量,响应时间从几十毫秒涨到几秒钟。更麻烦的是,存得太多之后,相似的内容互相干扰,检索结果变得不稳定。我自己的解决方法是配置“保存频率”和“最小长度阈值”:只保存超过一定字数的内容,并且对同一主题做去重。如果工具本身提供“压缩旧记忆”的能力,就配置成每个季度把三个月前的记忆汇总成一个摘要,原始内容删除。
这里有一个值得注意的原则:记忆不是存得越多越好,而是要有“遗忘机制”。人脑也会遗忘,AI 记忆系统如果不设计遗忘,最后只会被无用的历史淹没。
5.2 隐私边界:别把密钥喂给记忆系统
很多本地记忆工具都会强调数据保存在本地,不会上传到云端。但“本地保存”并不等于“安全”,更不等于“适合被注入给模型”。我在一次写测试用例时,让 Claude Code 读取了.env文件来分析环境变量配置,结果 claude-mem 把一串数据库密码也当成了记忆内容存了下来。后来一次不相关的对话里,它居然把这段密码引用进了回答中,幸好只是个人项目,没有泄漏。
这种情况必须提前设防。第一,仔细阅读工具的过滤规则,看它是否支持敏感信息屏蔽。大部分实现都会有敏感词正则或者 ignore 文件,类似.gitignore,你要认真配置,把api_key、password、token、.env路径等全部排除。第二,遇到密钥类内容,在对话里干脆不要让模型看到,写进本地文件后再引用路径就够了。第三,定期检查记忆库里的内容,看看有没有漏网的机密信息。
隐私问题不一定只是密钥,还有你可能不想让模型记住的个人情绪、吐槽、或者是公司内部的敏感业务信息。适合放记忆库的,永远是那些“即使我公开也不会有问题”的内容。凡是带一句“这个不要存”的对话,都要提醒自己:最好别让它进记忆。
5.3 记忆污染:过期信息反而坑了模型
比没有记忆更糟的,是不能用的旧记忆。
我遇到过这样一个场景:项目之前用的是数据库 A,后来因为性能问题迁移到了数据库 B。迁移完成之后,旧的记忆没有清理,某个模型看到“当前项目用的是 A”就直接照着旧方案写代码,反而害我排查了半天。这类错误其实比“模型不知道”更隐晦,因为从表面看它好像很懂项目,给出回答也很自信,实际上信息是过期的。
应对记忆污染有几个层次。短期靠“时间衰减”,在注入时对记忆按时间排序,超过一定天数的记忆默认不注入。中期靠“冲突检测”,当你发现记忆内容与实际状态矛盾时,主动删除或修改旧条目。长期靠“记忆验证”,定期用当前项目状态反向抽查记忆库,比如检查代码库里实际用的依赖版本,然后清理掉不一致的历史结论。
另外,模型在引用记忆时不一定能区分“陈述事实”和“我的偏好”。如果你在记忆库里存了很多“我不喜欢用 YAML,太啰嗦”,新来的会话可能会把它当成硬性规则,拒绝所有 YAML 写法。注入端的 prompt 设计要强调“这些都是历史记录,不是命令”,如果你发现模型过度服从记忆,应检查是不是记忆提示的措辞不够明确。
5.4 常见问题排查速查表
根据我自己和其他使用者反馈,整理了一个常见问题表:
| 症状 | 可能原因 | 排查思路 |
|---|---|---|
| 新会话完全没注入记忆 | MCP server 未启动或配置未生效 | 检查 .mcp.json,重启 Claude Code,查看 claude-mem serve 日志 |
| 手动搜索能搜到,但对话里不出现 | 注入提示被误删或上下文被清空 | 检查注入配置开关,确认没有超过 token 上限 |
| 检索结果明显不相关 | 向量库中混入噪音,或存储过滤太松 | 清理数据库,启用去重,调高写入阈值 |
| 中文效果差 | 嵌入模型对中文支持不足 | 换用更适合中文的嵌入模型,或加入词典/关键词补偿 |
| 数据库增长太快 | 保存了所有消息/频繁嵌入重复内容 | 调低保存频率,启用摘要压缩,配置 ignore 规则 |
| 配置后 Claude Code 卡顿 | MCP server 同步检索拖慢主线程 | 开启异步模式,降低检索频率 |
我不是针对某个版本写的故障字典,但这类工具的通病基本都集中在这几个点。遇到问题时先从“读写链路是不是通”入手,再排查过滤规则,最后看注入提示词。
6. 延伸思考:长期记忆功能的边界与未来发展
6.1 记忆颗粒度与隐私的平衡
用 claude-mem 越久,我越会思考一个问题:记忆到底应该细到什么程度?如果要让 AI 完全了解你的习惯、风格和项目,理想状态是把所有交互都存下来,但这并不可行。一是存储和检索成本兜不住,二是隐私风险陡增,三是模型会变得过度依赖历史记忆,不再认真看当前任务。
更合理的分界线是:只记那些“影响长期行为”的信息。例如你对代码风格的要求、你惯用的目录结构、你不想让 AI 碰的命令、你在某个项目里的架构决策。这些信息大概率会多次复用到,值得长期保存。至于某一次具体的调试过程、某个报错的临时解决方案,即使再有价值,也应该在短期内可检索,但不该被自动注入。把自动注入的范围压缩到最小,把按需检索留给更大的数据库,这个念头能让记忆工具既强大又不烦人。
6.2 从记忆到“个人知识库”,让 AI 越用越懂你
我在实际使用中的体会是:claude-mem 这类工具,远不止是“让模型记住我说过什么”。它真正迷人的地方在于,可以把一个人的工作经验、决策风格和踩坑记录沉淀成一个持续进化的本地知识库。你不需要写文档,不需要刻意整理,只要正常对话,记忆就会自然沉淀下来。等到几个月后,你会发现自己不必再向 Claude 解释“我为什么讨厌把测试用例写死在配置文件里”,因为它从你的历史对话里已经学会了。
这个方向再往下走,就是“可编程记忆”和“结构化记忆”。未来的记忆工具可能不只是存文本,还会把所有技术决策抽象成实体关系图,比如“服务 A 依赖数据库 B”“这个接口负责什么”“这个函数因为兼容性不能用新语法”。到那时候,模型对新任务的启动速度、判断准确率、以及对历史上下文的利用效率,都会比现在高一个量级。
claude-mem 虽然是早期阶段,但它验证了一个很重要的点:模型本身不重要,围绕模型的记忆层才决定了你能走多远。让模型从“永远不会记住你”变成“越用越懂你”,这正是所有个人工作流自动化值得投入的方向。如果你正在用 Claude Code,并且被重复交代背景这件事折磨过,我建议你认真尝试一下 claude-mem 这类记忆层工具。装好之后先跑一个真实项目,把 AGENTS.md 里的静态规则和记忆库里的动态经验配合起来用,两周之后再回头看看,你会惊讶于自己少说了多少废话。