ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

claude-mem:为Claude Code打造跨会话长期记忆的命令行工具

claude-mem:为Claude Code打造跨会话长期记忆的命令行工具 在跟 AI 编程助手打交道的过程中我遇到的最尴尬场景不是模型写错代码而是它忘了自己十分钟前说过什么。尤其是用 Claude Code 做长任务时会话一关之前梳理的架构约束、命名习惯、踩坑记录全部清零。你不得不把同样的话对着终端再念一遍第三遍的时候就会开始怀疑人生。claude-mem 就是冲着这个痛点来的我给这个命令行工具跑了快两个月今天把它的设计思路、实现细节、实际坑点和完整上手流程一次说清楚。1. 项目整体拆解claude-mem 到底解决什么问题1.1 核心需求解析先说人话claude-mem 是一个给 Claude Code 增加长期记忆能力的开源命令行工具。它的工作方式是在 Claude Code 会话关闭之后把每一次会话的关键内容抽取出来存进本地 SQLite 数据库。当下一次会话开始时它会自动检索与当前任务相关的历史记忆注入到 Claude 的上下文里让这个助手“想起”你们之前聊过的约定和结论。它的使用场景非常精准就三类人最需要长期维护同一个代码库的开发者需要 AI 保持对项目架构、命名规范、技术栈偏好的跨会话记忆。做技术调研或文档梳理的人经常在多个终端窗口里来回切换每个窗口都开过一次新会话之前的分析结论总是丢。用 Claude Code 跑自动化任务或批量重构的玩家希望每一步都基于前面已经确定过的决策而不是每轮重新从零开始。我不建议只会聊天式问代码片段的轻度用户装它因为这类场景不需要长期记忆反而会白白增加 token 消耗。claude-mem 的定位非常细分它就是“编程会话的私人记忆外挂”。1.2 方案选型背后的思考为什么选 SQLite 而不选 JSON 文件、Redis 或者向量数据库开发者的取舍很有意思我拆开讲。首先Claude Code 本身在会话中会产生大量结构化信息比如会话 ID、时间戳、文件路径、代码片段、决策结论。这些数据天然适合按字段存储和按时间过滤。SQLite 单文件、零部署、不需要额外起服务这是单机工具的绝对优势。你用 Docker 或者二进制包安装它会在用户目录下生成一个claude-mem数据库文件所有记忆都落在本地不经过第三方服务器这对代码隐私来说是硬性要求。其次检索逻辑不是简单地全文搜索。claude-mem 用了语义化的召回策略它会把历史记忆转换成向量表示再结合关键词过滤。这种“向量检索 结构化过滤”的混合方案比单纯用 grep 做关键词匹配要可靠得多。举个例子我上次跑完一个 React 项目的重构这次新会话里提到“hooks 拆分”它能把两周前那场关于useFetch和useAuth职责边界的对话捞出来而不是被大量包含“fetch”字样的日志噪音淹没。第三工具的设计刻意避开了把记忆塞回 Claude Code 原生配置的做法。Claude Code 自己有 CLAUDE.md 文件但这玩意儿更像项目说明书写多了会让每次请求的背景信息臃肿不堪。claude-mem 用的是动态注入只在合适的时候把合适的记忆片段放进去。这个思路在很多 RAG 系统里见过但落地到终端工具的并不多见。1.3 影响范围与生态定位用了一两个月之后我的感受是 claude-mem 已经不单单是一个记忆工具它更像是 Claude Code 的“第二大脑”。在这个生态里CLAUDE.md 管“静态知识”比如项目规范、架构目录结构、常用命令。终端会话上下文管“即时知识”就是当前这一步需要的信息。claude-mem 管“动态知识”是所有历史对话中沉淀下来的、跨会话仍然有效的决策偏好。这三层各司其职互不冲突。而且因为它开源越来越多人在上面加功能。有人加了多项目记忆隔离有人加了记忆导出合并还有人把它跟 MCP 协议打通让其他支持 MCP 的客户端也能复用这套记忆库。目前项目在 GitHub 上已经有相当热度核心代码用 TypeScript 写的可读性不错二次开发门槛不算高。2. 核心实现机制与数据流详解2.1 记忆的采集与存储claude-mem 的记忆采集不是实时的它采用“会话结束后静默处理”的模式。可以这么理解Claude Code 的每次会话在关闭时会留下结构化日志claude-mem 通过读取这些日志抽取当前会话的标题、目标和关键决策然后写入 SQLite。数据库里主要有几张核心表projects记录项目路径和项目 ID解决多项目隔离问题。sessions记录每一次会话的元数据包括开始时间、结束时间、关联项目、使用的模型。memories核心记忆表存放抽取出的结论性文本、置信度、来源会话 ID、时间戳、向量化表示。processed_sessions去重表记录哪些会话已经被抽取过避免每次扫描都重复处理。实际上手的时候你会发现 claude-mem 对会话日志的解析做了去噪处理。不是所有对话都会被存下来只有包含决策语义的段落才会被保留。比如讨论“到底用 pnpm 还是 yarn”这种有明确结论和理由的对话会被标记为高价值记忆而“帮我看看这个报错”“好我读一下”这种过程性对话会被过滤掉。这个过滤逻辑是内置 prompt 加规则双重驱动的也就是说它自己也会打电话给大模型来判断一段内容是否值得记住虽然这会产生少量额外 token 消耗但换来的是记忆库的干净度。2.2 记忆的召回路向量检索与过滤召回路是 claude-mem 最核心的工程环节直接决定它好不好用。每次新会话启动或者会话中用户切换到新任务目标时claude-mem 会执行一次检索过程流程如下。第一步把当前对话的最近上下文内容做向量化。这个向量化不是本地跑的而是通过 API 调用的方式生成。默认配置下它会把最后几条消息拼接生成一个代表“当前关注点”的查询向量。第二步用这个查询向量去 SQLite 的 memories 表里做相似度检索。SQLite 本身不直接支持向量索引claude-mem 的做法是把向量存成 JSON 数组字段查询时全表扫描做余弦相似度计算。这个方案在小数据量几千条记忆以内下性能完全够用单次查询也就几十毫秒。如果你硬要塞几万条记忆进去可能得换成 sqlite-vec 扩展但目前的默认策略对绝大多数个人项目都是合理的。第三步对召回结果做二次过滤。这里有几个硬性规则只保留当前项目下的记忆、过滤掉时间太久远且置信度低的记忆、剔除重复内容。最后保留 top N 条结果按照“对话主题相关性”和“时效性”的加权得分排序。默认的 top 参数是 4 到 8 条太多会让上下文窗口膨胀太少则容易丢关键信息。我实测过它的召回质量。同一周内跑过两次关于数据库迁移的任务第二次开新会话时只输入了一句“继续处理订单表迁移的事”它把上一次会话中确定的“外键不需要加索引”“数据保留策略按双月归档”这两条结论都带回来了准确度比期望值高不少。但如果隔了一个月、中间又掺杂大量其他项目记忆时召回精度会明显下降这个问题后面我会细讲。2.3 记忆注入的格式设计claude-mem 把记忆注入 Claude 上下文时采用了一个很聪明的“伪 Markdown”格式。它不会说“以下是你之前会话的记忆”而是生成一段类似系统指令的文本例如[Memory Context] You previously worked on this project with the following decisions: - Prioritize pnpm over npm for this repository. - Use feature-based directory structure under src/modules. - The order table migration requires archive logic for data older than 60 days.它把这些历史决策直接伪装成用户背景信息喂给模型。这样做的核心好处是Claude 会把它们当作既定事实参与推理而不是当作“外部指令”去刻意遵守。两者之间的区别很大前者是自然融入后者容易让模型频繁提及记忆内容产生一种莫名骄傲的啰嗦感反而干扰主任务。注入的位置也有讲究。claude-mem 允许你配置记忆插入时机——默认是每次会话启动时注入一次后续根据对话轮次再判断是否二次召回。如果你当前任务本身是高度独立的比如“把这个接口的单元测试补完”历史记忆没太大作用那它就会少注入甚至不注入防止污染当前上下文。这个动态闸门逻辑在配置里叫memory_injection_policy可选值是always、on_session_start和on_request。我自己的配置是on_request因为某些探索性任务根本不需要历史记忆每轮都注入反而浪费窗口。2.4 数据生命周期管理记忆不能只进不出否则数据库会变成垃圾场。claude-mem 提供了几个维度的生命周期管理机制。时间衰减默认对超过 90 天且被召回次数为 0 的记忆标记为低价值检索时排在最后。项目隔离不同项目的记忆互不串门避免 A 项目的技术选型污染 B 项目。手动清理提供命令行指令直接删除指定记忆或按项目全清。自动去重相似的记忆会被合并合并时保留置信度更高和时间较新的那条但这个功能默认是关闭的因为相似度判定需要额外调用一次模型接口如果不是记忆爆炸一般不建议开。实际使用中我倾向于每两周跑一次手动整理。因为 claude-mem 只能自动判断“它觉得重要的”但有些内容只有你知道过时了。比如项目已经从 Webpack 迁移到 Vite那旧记忆里的“禁止使用 splitChunks 手动分包”就作废了。你不在命令行工具里把它清掉它就会一直阴魂不散地注入到每一次会话中。3. 实操配置与命令速查3.1 安装与初始化claude-mem 有两种主流的安装方式我直接给结论优先选二进制安装其次是 npm 全局安装。前者不会污染 Node 环境升级也更简单。在 macOS 上使用 Homebrew 的话一条命令就能装上brew install claude-mem其他平台可以从 GitHub Releases 页拿对应平台的压缩包。下载后解压到任意目录用claude-mem --version验证安装成功即可。npm 方式适合已经在 Node 生态里的人装完就能跟 Claude Code 的 hook 机制配合npm install -g bsmi021/claude-mem这里要注意一个细节claude-mem 依赖 Claude Code 的 hook 回调。首次安装完成后需要运行一次初始化命令来生成配置文件和数据库目录claude-mem init这条命令会在用户目录下创建~/.claude-mem/文件夹里面包括claude-mem.dbSQLite 数据库和config.json配置文件。初始化完成后建议检查一下配置文件是否指向了正确的 LLM API 端点。因为记忆抽取和向量化这两个环节都需要调用模型接口如果 API Key 没有正确配置工具会静默失败——不报错但不写记忆。这个“静默失败”非常坑我第一次就是因为配置了个无效的环境变量跑了一天发现数据库大小是 0KB。3.2 与 Claude Code 的 hook 集成claude-mem 要真正工作必须挂到 Claude Code 的 hook 上。在 Claude Code 的设置文件里找到 hooks 配置段加上这样一段{ hooks: { Stop: [ { matcher: *, hooks: [ { type: command, command: claude-mem record --session-id $SESSION_ID --force } ] }, { matcher: !*, hooks: [ { type: command, command: claude-mem record --session-id $SESSION_ID } ] } ], PreToolUse: [ { matcher: Task(.*), hooks: [ { type: command, command: claude-mem retrieve --session-id $SESSION_ID --query \$QUERY\ --inject } ] } ], UserPromptSubmit: [ { matcher: *, hooks: [ { type: command, command: claude-mem retrieve --session-id $SESSION_ID --query \$PROMPT\ --inject } ] } ] } }这里面最关键的钩子是Stop事件它会在会话结束时触发记忆抽取。UserPromptSubmit事件负责在用户提交新提示时做一次检索召回。--inject参数的意义是把召回结果直接追加到这次提交的提示文本之后。特别提醒$QUERY和$PROMPT这两个内置变量在 Claude Code 里分别代表工具调用的意图描述和用户原始输入。如果你配置错误比如写成了$QUERY但实际该用$PROMPT工具不会崩但是召回内容会毫无相关性看起来就是往上下文塞了一堆没用的话。3.3 常用命令速查我整理了一份高频命令表覆盖日常使用绝大部分场景命令作用典型使用场景claude-mem status查看当前记忆库大小、会话数、记忆条数排查为什么没有记忆被写入claude-mem search --query 关键词手动搜索历史记忆快速验证某条记忆是否已经被保存claude-mem record --session-id xxx手动触发一次会话抽取hook 没触发时补救claude-mem retrieve --query 任务描述手动执行一次召回并打印结果测试召回质量不实际注入上下文claude-mem delete --id 123删除指定记忆清理过时决策claude-mem project --name demo --clear清空指定项目的全部记忆项目重构后整体重置claude-mem config --show查看当前配置项排查 API 端点或模型参数问题有个小技巧手动编码时如果你想确认某次会话是否成功写入记忆直接跑claude-mem query --query 上次讨论的结论就能搜到不需要登录网页端翻 Claude 的日志。3.4 配置项调优建议配置文件里几个值得动参数的地方我逐个说。{ extract_model: claude-3-5-haiku, embedding_model: text-embedding-3-small, top_k: 6, similarity_threshold: 0.78, min_confidence: 0.6, memory_injection_policy: on_request, project_auto_detect: true }top_k控制每次检索返回多少条记忆。我的测试结论是4 条太保守经常漏掉关键信息8 条会让上下文开头变得臃肿6 条是比较平衡的值。如果你的任务多是大型重构建议调到 8如果是写脚本或调试4 就够。similarity_threshold是召回相似度阈值范围 0 到 1。默认值 0.78 在多数场景没问题但如果你发现召回结果经常带着大量无关内容把它调到 0.82 或 0.85精准度会明显改善。代价是有些边缘相关的记忆会被过滤掉需要你根据自己的容忍度来平衡。extract_model默认用轻量级模型做抽取这样成本低、响应快。但如果你发现记忆内容经常缺失关键决策可以升级成更强的模型效果会好很多毕竟抽取的 prompt 本身并不复杂大模型和小模型的差异主要体现在长文本期中后段的遗漏率上。3.5 初始化后的验证流程装完不要急着开始干活务必先跑一遍完整的验证流程确认三件事数据库在写入、召回应答正常、注入内容不破坏原提示。验证写入跑一次短会话随便聊几句技术选型退出后执行claude-mem status看记忆数是否上涨。验证召回执行claude-mem retrieve --query 刚才聊的技术选型看能否看到刚才的对话结论。验证注入重新开一个会话输入同一话题在界面上方的调试信息中查看是否出现[Memory Context]字段。如果这三步都通过了工具就算正式上岗。4. 常见故障与避坑经验4.1 hook 触发了但记忆库没有新数据这是遇到频率最高的问题绝大多数情况出在record命令没有拿到有效的会话 ID。Claude Code 的 hook 环境里$SESSION_ID不是什么时候都有值。在Stop事件里它通常没问题但在某些自定义终端或 IDE 插件环境中变量可能为空字符串。排查方法很简单在 hook 配置里暂时把 command 改成echo session$SESSION_ID /tmp/claude-mem-debug.log跑一次会话后看日志里有没有值。没有值的话你需要换一种方式拿到会话 ID——比如通过claude-mem current-session命令自动探测或者直接改用--project参数归档不依赖会话级联。另一个常见原因项目路径没有匹配上。claude-mem 默认只处理 Git 仓库内的路径。如果你的目录不是 Git 仓库它可能会直接忽略写入操作。找到配置里的project_auto_detect把它关掉然后手动指定项目名claude-mem record --project my-project --session-id xxx4.2 召回的旧记忆明显过时这个问题靠参数调优解决不了根治办法是建立“记忆维护习惯”。我自己的节奏是每隔两周固定做一次记忆清理。你会看到数据库里堆积了大量三个月前的技术栈闲聊它们在相似度检索时依然能命中但已经不具备参考价值甚至会误导模型。清理不需要一条条删。高效的做法是claude-mem search --query 已废弃之类的方式先看一批快速确认后claude-mem delete --id批量删除。如果废弃的内容太多直接按项目清理重新开始积累。我踩过的最大一个坑是这样的一个项目从 Vue 2 升到 Vue 3 之后我忘了清理旧记忆结果 Claude Code 每次提到响应式相关的任务时都会把旧会话里“不要在 Vue 2 里用 composition-api 的某些选项”的结论注入进来。它不至于导致代码写错但严重干扰讨论节奏每次看着它引用一个不存在的限制都得手动打断纠正反而比没有记忆更拖后腿。4.3 token 消耗明显上升claude-mem 不是零成本的。每次记忆抽取需要调用一次抽取模型每次检索需要调用一次向量化模型。如果你把memory_injection_policy设成always那每一轮对话都会触发一次召回注入token 消耗会比裸用 Claude Code 高出不少实测大概多 15% 到 25%。想控制成本我建议做三件事把注入策略改成on_session_start或on_request不要每次提问都召回。降低抽取频率将Stophook 里的--force参数去掉只让它对包含深层讨论的会话做抽取。使用便宜模型做抽取和向量化默认配置已经选了轻量级模型这个不要改。4.4 多设备之间的记忆同步问题claude-mem 默认数据存在本地单机上换电脑不会同步。如果你跟我一样在家用 Mac 办公、在公司用另一台机器记忆库就是分裂的。解决办法不算完美但够用把~/.claude-mem/claude-mem.db这个文件纳入云同步盘。我用的是坚果云也有用 iCloud 或自建 NAS 的。需要注意两点一是不要在两台设备上同时跑会话否则 SQLite 会因并发写入锁库二是同步盘会有历史版本如果误删数据还能找回算是意外收获。如果你对这个方案不放心可以加一个定时导出任务sqlite3 ~/.claude-mem/claude-mem.db .backup ~/sync/claude-mem-$(date %Y%m%d).db安全要求高的话别把原始数据库直接丢云盘里面涉及真实代码决策和路径信息泄露也是麻烦事。4.5 与多项目切换的冲突Claude Code 同时打开多个项目时claude-mem 的自动项目识别大概率会失灵。因为它的判断依据是当前终端的工作目录如果你在/Users/you/project-a下运行但询问的是 project-b 的问题记忆检索就会全从 project-a 里出。想稳住切换场景把project_auto_detect关掉手动为不同任务指定项目名。在 hook 命令里加上--project参数虽然每次都要多敲两下但胜在记忆边界清晰。我甚至建议一个仓库只开一个终端标签不要混用让目录切换频率降下来记忆关联的准确率会提升到接近满分。4.6 Mac 上 Homebrew 升级后 hook 失效Homebrew 升级 claude-mem 后二进制路径偶尔会变。你配置在 hook 里的claude-mem命令如果用的是绝对路径升级后容易失效。解决办法是在配置文件里统一改用动态命令command: $(which claude-mem) record --session-id $SESSION_IDwhich claude-mem每次执行时重新解析路径就可以避开 Homebrew 的符号链接迁移问题。这个经验是我有一次升级后另一个工具全挂才发现的。5. 私有化部署与进阶扩展5.1 用代理网关切换模型供应商默认配置直接调用官方 API国内直连延迟较高且某些网络环境下访问不稳定会话抽取任务本身不赶时间但每次几千毫秒的等待累积起来也会拖慢整体节奏。我自己是把模型调用统一切到了代理网关它在传输层面做优化速度提升非常明显。配置方式是在 config.json 里修改 base URL{ api_base: https://your-proxy-endpoint.example.com/v1 }选代理网关的时候注意确认它对 Anthropic 的接口形式兼容起步阶段先跑一次claude-mem status确认抽取链路通不通。5.2 用 MCP 协议暴露记忆库给其他客户端claude-mem 已经实现了对 MCP 协议的支持这意味着它可以把记忆库作为 Memory 工具开放给任意支持 MCP 的客户端使用。配置方式claude-mem mcp --project your-project --transport stdio拉起后客户端能够直接调用记忆搜索工具等于把 Claude Code 专属的记忆能力扩展到了通用 AI 编程环境。这个方向我很看好因为记忆库本身应该属于用户而非某个特定模型。5.3 定制抽取 prompt如果你觉得默认的记忆抽取质量不行可以在配置目录下建一个自定义 prompt 文件覆盖掉默认抽取模板mkdir -p ~/.claude-mem/prompts cat ~/.claude-mem/prompts/extract.txt EOF You are a memory extraction engine. Read the conversation and output a JSON array of memory objects. Each object should contain: - id (string) - content (string, the decision/insight itself) - confidence (float 0-1) - tags (array of strings) DO NOT extract: greetings, code snippets without conclusions, temporary debugging state. EOF改完重启 Claude Code 生效。自定义 prompt 能显著提高抽取质量特别是针对特定领域的项目。比如我做过一个数据管道项目通过在 prompt 里增加“区分临时表名和最终表结构”的指令让记忆库里的表名信息密度大幅提升。5.4 记忆库的备份与迁移数据库文件本身非常轻巧通常几十 MB 以内整库备份成本极低。我习惯在每个迭代周期结束时跑一条备份命令claude-mem export --project your-project --format json backup.json这不仅用于备份也可以做二次分析——把记忆数据导入表格或 Notion生成项目知识图谱辅助写周报和复盘。这个能力用起来之后你就不再只是给 AI 加了个记忆而是给自己也加了一本随手的项目决策流水账。6. 个人实测心得体会用 claude-mem 跑了两个月最大的感受是它改变的不是 AI 的能力而是你的工作习惯。刚装上的头一周你会觉得没什么特别因为短会话里记忆本来就不容易丢。但到第二周、第三周当你开始依赖“它应该记得”这件事时价值才真正显现出来。有一件小事我记得特别清楚。一个跨了十天的 API 设计讨论中间换过三次终端、经历过几次大版本回滚但最后一次会话里我只提了一句“继续那个限流方案的设计”Claude 直接把十天前的限流阈值参数、缓存策略和异常处理逻辑全部接了回来接着往下写代码。那种感觉就像把一个特别熟的同事拉回了会议室不用重新同步前情提要。当然它不值得盲目吹。记忆抽取本身受制于会话日志质量如果对话全程是碎片化的“改这里”“改了没有”抽出来的记忆也是碎的交杂着大量类似关键词的历史记忆时召回精度会往下掉。而且记忆一旦污染清理成本比记录成本高得多。我现在的做法是重大决策会话结束后花三十秒主动跑一下claude-mem search --query 今天确定的方案确认记忆入库且没有噪音。这个习惯成本极低但能保证核心决策绝对不会丢。在 AI 编程工具越来越强的当下跨会话记忆能力决定了一个工具到底值不值得依赖而 claude-mem 这种轻量方案至少让我对 Claude Code 的每次重启不再恐慌。
返回列表