claude-mem:为Claude Code打造跨会话长期记忆的开源工具实战指南

发布时间:2026/10/11 3:38:52
claude-mem:为Claude Code打造跨会话长期记忆的开源工具实战指南
如果你平时用 Claude Code 写代码一定会有这种体验昨天刚把某个模块的接口约定聊清楚今天开新会话它又全忘了。claude-mem 这个开源小工具就是专门解决这个“跨会话失忆”问题的——它在 Claude Code 和本地数据库之间加了一层自动记忆层把那些值得沉淀的信息从对话里捞出来存好下次开局再自动塞回去。我最初注意到它是因为一个很现实的痛点我带了一个发给团队内部用的工具项目前后三周改了十几轮需求。每次新开会话都得把“这个项目技术栈是什么”“字段命名规则是什么”“上次还没改完的部分在哪”重新交代一遍。交代完常常已经过去大半小时token 也花了不少。后来我把 claude-mem 接入到日常流程里情况才真正改变。这篇文章适合三类人一是每天跟 Claude 打交道、被重复沟通耗时间的开发者二是想给团队或自己的长期项目建立“项目记忆库”的人三是单纯好奇一个本地记忆系统怎么做才不鸡肋的工具党。我会把原理、安装、配置、实战场景和排查方法都摊开讲尽量让你照着操作就能落地。1. 一切的原点为什么 Claude 会“失忆”1.1 会话窗口不是长期记忆大语言模型的机制决定了它的“记忆”只存在于当前上下文窗口里。窗口再大也是有限的一张桌子东西放不下就会被挤掉而一旦会话结束整张桌子都会被清空。下一次新会话模型面对的是一个空白的开始它对“你是谁”“你在做什么项目”“你有哪些偏好”一无所知。这不是产品缺陷而是架构使然。用一个生活比喻你请了一个特别能干的临时助理但这个助理每天下班后会失忆。你每天早晨都要重新告诉他你的咖啡口味、办公室钥匙在哪、今天要跟进的事。业务能力强归强但协同成本也真的高。Claude 的任务能力、代码生成能力很强但跨会话的项目状态、个人偏好这些长期信息它默认是不保留的。更麻烦的是很多人会把这些“记忆负担”转嫁到上下文里——例如把一整个项目说明文档塞进提示词或者在对话中途反复强调“之前说过了”。这些办法能撑一时但上下文窗口一满前面说过的重要信息反而被挤掉模型开始答非所问。1.2 大家都在用的“土办法”为什么不够用在接触 claude-mem 之前我见过不少人在社区分享自己的手动方案大致有三类手动维护一份项目备忘录每次新会话开始时贴进去。能用但备忘录很容易过期。今天改了一个决策你很可能忘了更新它明天上下文变得很长你又不确定贴进去的是不是最新版本。把上一轮对话记录直接贴回去。这能解决一部分“连续感”但对话记录越长token 成本越高而且夹杂大量无关内容反而稀释了模型注意力。把重要信息写进代码注释或仓库 README。这思路是对的但太碎片化而且不是所有信息都适合写进仓库里——例如你自己的代码风格偏好就不太适合出现在公共文档里。这些方法不是不能用而是不可持续。它们本质上是把“记忆”这件事变成人的责任而不是工具的责任。而 claude-mem 的思路刚好相反把记忆的提取、存储、检索、注入全部自动化你只需要在关键时刻说一句“记住这个”剩下的事情它来做。2. 设计拆解一个本地记忆系统应该长什么样2.1 选型思考为什么是 SQLite 而不是向量库我第一次看 claude-mem 的设计时第一反应是现在做记忆系统不都是搞向量数据库加 embedding 吗怎么这个工具偏偏选了 SQLite追问下来才发现这个选择恰恰是它务实的地方。单个开发者或一个小团队的项目记忆就算每天积累几十条跑一年也就是几千到几万条记录。这个量级下SQLite 的全文索引配合关键词搜索速度是毫秒级的根本不需要动用向量检索。加上 SQLite 本身是单文件数据库备份、迁移、查看都极其方便——你甚至可以直接用 sqlite3 命令打开数据库文件看看里面到底存了什么。这是向量库不容易给到的透明感。我做了一个简单对比帮助你想清楚自己的场景维度SQLite 全文索引向量数据库JSON 文件手动维护检索质量中上依赖关键词与标签高能处理模糊语义低基本靠遍历单机部署成本极低无外部服务中高通常需独立服务最低数据透明性高可直接查看低向量是黑箱中写入并发强支持事务中弱容易损坏适合数据规模千到十万级百万级以上千条以下当然SQLite 并不是没有短板。如果你要记的东西是几万条长文本而且你经常用“我想不起来具体词但大致意思是……”这种方式提问那纯关键词检索确实会吃力。但 claude-mem 的定位是个人记忆助手不是通用搜索引擎。日常被记住的内容大多数都能用“实体 标签 关键词”描述清楚也就是说它根本不需要走到向量那一步。2.2 记忆模型三类记录两种状态claude-mem 的记忆不是只存“对话原文摘要”那种粗粒度的东西。它把记忆按用途拆分成了三类这样做是为了在注入阶段做差异化的优先级管理。事实型fact项目的技术栈、目录结构、已有模块、明确的技术决策。这类记忆是“稳定的硬约束”适合长期保留优先级最高。偏好型preference用户的语言风格、代码风格、工具习惯、沟通偏好。这类记忆不容易过期跨项目也基本通用适合作为全局规则反复注入。过程型procedure当前正在进行的任务、待办事项、上次进行到一半的修改。这类记忆时效性强项目结束后基本就不再需要了需要定期清理。三条记忆记录一个核心字段是重要性分数从 1 到 5 不等。你手动添加的记录默认可以设成 4 或 5而自动从对话中抓取的记录初始分数往往偏低只有被反复命中才会逐步上调。这个设计其实是模仿人脑的遗忘曲线信息越重要、被提到的次数越多就越不容易被忘记很久没被用到的东西慢慢就会淡出上下文。另外每条记录还有生命周期状态默认是 active超过一段时间没有被调用会被标记为 stale再之后会被自动归档。这个 TTL 窗口长度可以在配置里调默认值大概在一个季度左右。它的作用就是避免记忆库无限膨胀最终变成一锅粥。2.3 注入与防止“记忆过载”有了数据库之后下一步关键问题就是什么时候把哪些记忆塞回给 Claude以及塞多少合适。claude-mem 的做法是在新会话启动阶段从数据库里检索出一批与当前项目相关的记忆整理成一段带标记的文本注入到 Claude 的对话上下文里。检索阶段不是把所有记忆都倒出来而是先做一次打分。打分主要看三个维度关键词和当前会话主题的匹配度、记忆新鲜度、重要度分数。分数低于阈值的直接不参与注入。注入的量也需要控制。如果每次开局都塞上千字的背景说明反而会挤占本应留给实际任务的上下文空间。我自己的经验是把单次注入的字数上限控制在 1500 到 2500 字左右优先保证事实型和偏好型记录过程型只挑最近一两条带上效果最舒服。另外一个被很多人忽略的点是去重。同一个信息如果你在对话里反复确认了三次每次新会话注入时都弹出来这既不省 token也容易让模型出现“明明已经确认过还要再确认”的尴尬。claude-mem 会对相似记录做合并处理合并依据是实体和摘要的哈希相似度。实际使用中你基本不會看到同一条规则以三种变体同时出现。3. 手把手落地安装、初始化、挂接 Claude Code3.1 环境准备与安装开始之前你手上需要有可用的 Node 运行环境并且已经装好了 Claude Code 命令行工具。claude-mem 安装本身很简单以常见发行方式为例一条全局安装命令即可搞定npm install -g claude-mem装完之后用一个自带的版本命令验证claude-mem --version有个小提示不同版本仓库的安装方式可能有差异有的发行版是直接 clone 仓库后执行npm install npm run build。如果你在安装阶段卡住先去对应 README 的 install 章节确认一下为准不要硬套命令。还要提醒一句如果之前装过旧版本先卸载干净再重装。这个工具的数据库结构更新比较频繁旧版本残留的配置项可能和新版不兼容表面上装好了实际跑起来会有各种奇怪问题。3.2 初始化与目录结构安装完成后在任意目录执行初始化命令claude-mem init初始化实际上做三件事创建数据库文件、生成默认配置文件、验证当前环境的 hook 是否可用。执行成功后会在用户主目录下生成一个.claude-mem文件夹结构大致如下~/.claude-mem/ memory.db # SQLite 数据库所有记忆都存这里 config.json # 主配置文件 logs/ # 运行日志排查问题时很有用config.json 是后续调优最经常动的地方。里面几个关键字段我摘出来给你看{ maxInjectChars: 2000, minImportance: 1, ttlDays: 90, enableHooks: true, excludePaths: [node_modules, .git], redactPatterns: [api[_-]?key, sk-[a-zA-Z0-9]] }maxInjectChars控制每次注入的最大字符数minImportance决定低于多少重要度的记录不参与注入ttlDays是记忆从 active 转为 stale 的过期天数excludePaths用于排除特定目录避免无关项目的记忆互相干扰redactPatterns是敏感内容脱敏规则这个我后面会细说。如果你跟我一样喜欢把配置放在版本管理里建议改完 config.json 后进 init 之前先备份一遍原文件。虽然它不常坏但配置出错导致的“诡异行为”比数据库出错更难排查。3.3 通过 Hooks 实现自动记忆安装和初始化只是准备工作真正让 claude-mem“活过来”的是与 Claude Code 的 hook 机制对接。所谓 hook就是在特定事件发生时自动执行外部命令的钩子。claude-mem 要在四个时机介入{ hooks: { SessionStart: [claude-mem session start], UserPromptSubmit: [claude-mem prompt], Stop: [claude-mem session stop], SubagentStop: [claude-mem subagent stop] } }解释一下这几个 hook 各自的作用SessionStart新会话启动时执行负责检索并准备记忆注入内容。UserPromptSubmit每次用户提交消息时执行负责从对话流中提取潜在的记忆点。Stop一轮回复结束后执行把真正值得记住的信息写入数据库。SubagentStopClaude 的子任务返回时执行只做轻量整理不触发高成本的重度提取。这里有个细节记忆写入不是在对话过程中实时发生的而是在对话告一段落后批量处理。这样设计是有意的。实时写入太频繁会拖慢交互响应而且容易把中间被打断的半截话也记进去。停在结束时再处理既保证了数据完整性也不会频繁占用磁盘 IO。hook 配置可以直接手动写入 Claude Code 的配置文件不过更推荐用 claude-mem 自带的命令自动完成挂接claude-mem hook install自动挂接的优点是它会帮你保证路径正确、权限到位省去手动折腾的时间。执行完可以通过claude-mem hook status查看当前每个 hook 的启用状态。3.4 验证整个链路是否跑通配置完成后别急着开始干活先把链路整体验证一遍。我习惯的做法是第一步打开一个新会话随便发一句“今天继续昨天那个订单模块的事”。正常的话你会看到回复顶部出现一段以记忆标记开头的注入内容里面列出了相关项目信息和上次进度。如果没有先检查claude-mem hook status再看一下日志目录里最新的输出。第二步运行统计命令看数据库里有没有写入数据claude-mem stats这个命令会返回记忆总数、按类型划分的条数、最近写入时间。看到行数大于零说明写入通道是通的。第三步手动加一条测试记忆然后新开会话试试能否被检索出来claude-mem add --kind fact --tags test 测试记忆这个项目的数据缓存目录是 /var/cache claude-mem search 缓存目录如果三步都通了说明安装和挂接都没问题可以进入日常使用了。4. 把它用起来三个可以照搬的实战场景4.1 场景一跨会话维护“项目边界清单”我遇到过最多的情况是 Claude 在项目里待久了会“飘”——它生成代码时经常绕过你之前定下的边界条件。比如你说过“这个模块不要动它是给线上服务用的”但它下次看到相关代码还是顺手给改了几个字段。这种“边界条件”就是典型的事实型记忆完全值得显式写进记忆库claude-mem add \ --kind fact \ --tags projectorder-service,modulepayment \ --importance 5 \ payment 模块对接了内部支付网关修改字段前必须同步更新测试桩数据且不允许直接改数据库表结构写入时把 importance 设成 5意味着新会话注入时它基本不会被过滤掉。之后每次你在 order-service 项目里开会话Claude 都会在开局就看到这条声明再想踩线就会收到自己的“红线提醒”。这个场景给我最大的感受是记忆不要用“大而全”的思路要用“痛点导向”的思路。不是把所有项目信息都塞进去而是在项目里出现第一次越界、第一次返工的时候当场把规则写进去。这样记下来的每条记忆都对应一个真实踩坑点价值密度比自动抓取的对话摘要高得多。4.2 场景二让你的代码风格保持一致Claude 的代码风格默认会偏“标准教程风”但每个人的项目风格其实有自己的规矩。有人喜欢用any有人严格禁用any有人要求所有函数写 docstring有人觉得只有公共 API 才需要写有人习惯 4 空格缩进有人偏好 2 空格。这些偏好如果只在某一句话里提过过两天它就会忘记。但作为偏好型记忆它们可以长期稳定生效。进入 claude-mem 的数据库只需要一条命令claude-mem add --kind preference --importance 4 \ 代码风格TypeScript 文件一律使用类型别名而非 interface禁止 any函数超过 50 行必须拆分偏好型记忆的微妙之处在于它不像事实型那么硬。如果你同时记了一堆风格规则注入到上下文里模型会倾向把所有规则当硬约束来执行。所以我的建议是偏好型记忆每条尽量只讲“一件事”面太宽的规则可以拆成两三条再存。另外如果你在某次对话里教过 Claude 某套规范但没来得及存还可以从历史对话记录里反向提取claude-mem search 编码规范 claude-mem search 命名风格查出来之后再决定哪些值得固化保存哪些只是一次性需求。这种做法特别适合刚开始用 claude-mem 的人能把之前零碎的交流沉淀下来而不必在记忆库还没建起来时逐条手动补录。4.3 场景三多项目隔离与定期清理claude-mem 默认是全项目共用一个记忆库但这其实很容易出问题——A 项目中记下来的某些规则跑到 B 项目里可能完全不适用甚至还会指导 Claude 做错误的事。解决方法是给记忆打项目标签并在检索时用标签过滤。配置里可以开启项目隔离模式让记忆只出现在对应项目的上下文中。实际操作中每个新项目初始化时我都会确认当前项目名已经被自动识别或者手动补一条带projectxxx标签的规则进去。即使做了项目隔离记忆库也还是需要定期打理。我会每过几周做一次清理动作# 看看哪些记忆长期没有被命中和使用 claude-mem list --stale # 清理状态为 stale 的过时记录 claude-mem clear --stale # 彻底删除某条特定记忆 claude-mem forget record-id清完这一轮之后数据库里的内容会明显变精简注入时生成的文本也更紧凑。定期清理不仅是节省 token更重要的是减少记忆库“干扰噪声”——记忆越少越精模型反而越容易抓重点。4.4 场景四换机器时的记忆迁移这个场景不一定天天遇到但等你要换电脑、或者把工作环境从个人机器迁到团队共用机器时就会意识到本地数据库的一个优势它就是个普通文件迁移成本极低。配合一个自动化任务定期导出备份claude-mem export /path/to/backup.json在目标机器上安装好 claude-mem 后执行导入claude-mem import /path/to/backup.json导入之后建议马上claude-mem stats检查一下条数是否一致。如果导出的记录里有大量过期的过程型记忆旧消息里带的会话 ID 和本地新会话对不上这没关系导入后它们在检索时会被识别为 stale稍加清理就行。5. 常见问题与排查技巧5.1 记忆一直没有生效这是最多人遇到的问题配置好了但新会话开头完全没看到任何记忆注入。我按出现频率排了几个原因症状可能原因处理方法新会话没有任何注入Claude Code 的 hook 没有触发检查claude-mem hook status确认各个 hook 处于 active 状态注入内容为空context 文件路径不一致确认 Claude Code 的 system prompt 里读取的是 claude-mem 实际生成的绝对路径部分记忆消失记录被判定为 stale 或重要性过低调低minImportance或手动把该记录的重要性改成 4~5手动添加了却查不到标签过滤不匹配检查当前项目的 project 标签是否和记录里的 tags 匹配我遇到过一次比较隐蔽的情况电脑重启之后Claude Code 以错误的 PATH 启动了导致 hook 里的 claude-mem 命令根本找不到。表面上 hook 状态正常但实际上所有命令都静默失败了。这种情况去~/.claude-mem/logs/里翻一下最近日志通常立刻就能看到报错。5.2 数据库锁冲突与文件损坏SQLite 本身很稳定但在多个进程同时写入时偶尔会遇到database is locked的报错。claude-mem 默认启用了 WAL 模式大部分情况下能避免读写互相阻塞。但如果你同时开着多个 Claude Code 会话而且每个会话结束都触发大量写入偶尔还是会撞锁。遇到SQLITE_BUSY类的报错不用太慌通常等一下重试就行。真正需要小心的是别随便把 memory.db 拷到别的机器上然后用旧版本的 claude-mem 打开——版本不一致可能改坏 schema。正确做法是先用claude-mem export导出成 JSON再在目标机器上导入跨版本永远走导出导入路径。备份时也尽量避免直接复制 db 文件而是用 SQLite 自带的方式做在线备份sqlite3 ~/.claude-mem/memory.db .backup /path/to/backup.db5.3 上下文膨胀记忆太多反而坏事另一个常见问题是记忆库越用越满新会话一注入就是一大段历史既费 token又容易把模型带偏。Claude 本来是在做当前任务结果满脑子是三个月前的“历史背景”反而忽略了当下问题。我踩过这个坑有两周里我把大量“也许有用”的信息都记了下来结果每次会话都变得拖沓、回复离题。后来我做了三个调整把maxInjectChars从默认值下调到 1600 左右把过程型记忆的 TTL 调短到 45 天对偏好型记忆只保留确实反复出现过的规则。调整之后上下文里留下的几乎都是当前项目真正用得上的内容。另外一个技巧是临时开一个不注入记忆的“干净会话”。claude-mem 提供开关在会话开始前关掉当前项目的记忆注入功能。这种会话适合处理一次性小任务比如“帮我看看这段代码哪里有语法问题”本来就不需要历史上下文参与。5.4 隐私与敏感信息防护记忆库把所有对话精华都集中到了一个文件里等于把隐私风险也集中了。这要提前想清楚。首先是默认行为所有数据都存本地不上传任何服务这一点没问题。但在团队共用机器上建议给.claude-mem目录单独设置权限别让所有账号都能读到。申请使用上我的原则是密钥、密码、内网地址、真实姓名这些敏感内容绝对不要用记忆记录宁可每次重新说明也不让它沉淀进数据库。如果确实要在团队环境里用又担心某些信息被不小心记下来可以用配置里的脱敏规则把符合特定模式的字符串在写入时自动替换成占位符相当于给记忆库加了道保险{ redactPatterns: [ sk-[a-zA-Z0-9]{16,}, -----BEGIN PRIVATE KEY----- ] }遇到需要反映真实项目运维的内容比如某个服务端口被占用、某条命令会清空临时文件这些都可以放心地加进事实型记忆里——只要不含个人私密数据和对团队共享的备忘信息放在一起其实价值更高。结尾从一个老用户的实践顺序说起如果你问我上手 claude-mem 之后最快的路径是什么我会说先不要想着搞一套完整记忆体系从最小的痛点开始。我第一次用的时候只记了三条规则项目技术栈、严禁改动的模块列表、代码注释要用中文。光靠这三条就已经让我每周省下不少重复交代的时间。用顺了再逐步把偏好、过程、进度这些信息补进来。还有个小技巧值得一试把claude-mem add绑定成一个顺手执行的快捷键或者自定义命令。我后来养成的习惯是每次和 Claude 对话结束时静下来想一想如果刚才说的某件事下次又需要就立刻补一条记忆。积少成多之后这个工具才真正变得不可替代。我也在它身上做过一些“返工”一开始配了很高的注入量结果模型老是回顾过去反而耽误新任务后来优化了标签和阈值效果立刻好了很多。你大概率也会经历类似的调试过程不用怕麻烦所有配置都在一个 JSON 文件里多试几轮就能找到适合自己节奏的参数。这套实践下来我觉得 claude-mem 最值得借鉴的地方不是“它记住了多少”而是“它知道哪些不用记”。这个想法今天依然是我调各种 AI 工具的核心思路。