claude-mem:为Claude Code打造长期记忆的终端AI扩展工具

📅 发布时间:2026/10/8 19:15:47
claude-mem:为Claude Code打造长期记忆的终端AI扩展工具
1. 项目整体设计与思路拆解1.1 为什么需要 claude-mem 这类记忆工具用过 Claude Code 或者经常和 Claude 聊天的人应该都有同感单次会话里它能记住你交代的上下文但一旦关闭终端、开启一个新会话之前聊过的内容就像被格式化了一样什么都不剩。你需要重新解释项目背景、重新说明偏好设置、重新强调哪些文件不要动。如果只是几句话还好可当你在一个大项目里调试了三四个小时积累了大量决策背景和排查记录之后这种“失忆”带来的重复劳动真的让人抓狂。claude-mem 的出现就是解决这个问题的。它是一个开源的“记忆扩展”工具专门给 Claude Code 这类终端型 AI 助手补齐长期记忆能力。它不是简单的聊天记录备份而是有选择性地把会话内容结构化存储到本地 SQLite 数据库中并且能自动生成会话摘要。你新开一个会话它可以基于历史记忆自动为你提供相关上下文从而让 AI 的行为更连续、更“懂你”。这个项目适合谁来用呢首先是重度使用 Claude Code 写代码、做运维、搞数据分析的开发者其次是那些需要在多轮对话中维持项目背景的技术团队甚至包括喜欢在终端里用 AI 做研究、写文档的人。如果你只是偶尔问 ChatGPT 一句“怎么给列表去重”那 claude-mem 对你的价值不大但如果你每天都在终端里靠 AI 干几个小时的活那它就是刚需工具。从底层逻辑上看claude-mem 的核心思路非常简单把对话历史存下来然后在需要的时候把它重新注入给模型。但这件简单的事要做好关键在于“怎么存”、“存什么”、“何时注入”。这些设计决策直接决定了工具是否好用也是我接下来要展开分析的重点。1.2 核心工作流程与存储方案claude-mem 的工作流程可以拆成三个阶段拦截、归档、注入。拦截阶段发生在你使用 Claude Code 的每一次会话中。claude-mem 以钩子hook方式接入 Claude Code 的事件流监听每条消息、每次工具调用、每个文件读写。它不会盲目记录所有原始数据而是经过筛选后只保留对长期记忆有价值的信息比如用户的关键指令、项目决策、代码变更点、遇到的错误和解决办法。归档阶段是它的核心。抓到的会话信息会被写入本地 SQLite 文件并且按结构化格式存储。归档不只是存原文它还会调用 Claude 对会话做一次摘要生成把冗长的调试过程提炼成几行“结论性记忆”比如“用户偏好使用 pnpm 而不是 npm”“项目的 API 网关超时已从 30s 调整为 120s”这类干净又具体的条目。这些摘要才是 claude-mem 后续用来注入上下文的“弹药”。注入阶段则发生在你新开会话时。claude-mem 会先检查当前项目的会话历史抽取与当前工作会话相关的记忆然后以系统提示或上下文块的形式注入到 Claude 的输入中。这样Claude 从一开始就“知道”你之前做过什么、你习惯怎么做避免了重复解释的尴尬。存储方案上claude-mem 选择 SQLite 而不是 JSON 文件或传统的 MySQL这个选型很聪明。SQLite 是单文件数据库零配置、零服务进程天然适合开发者在本地使用同时它支持结构化查询你可以用 SQL 精确检索“三天前关于数据库优化聊了什么”这是纯文本 JSON 很难做到的。更关键的是SQLite 的事务支持保证了写入的原子性哪怕你正在疯狂发送消息也不会出现记录损坏的问题。-- claude-mem 底层存储的核心表结构示意 CREATE TABLE conversations ( id INTEGER PRIMARY KEY AUTOINCREMENT, project_path TEXT NOT NULL, started_at TEXT DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE messages ( id INTEGER PRIMARY KEY AUTOINCREMENT, conversation_id INTEGER REFERENCES conversations(id), role TEXT NOT NULL, content TEXT NOT NULL, created_at TEXT DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE memories ( id INTEGER PRIMARY KEY AUTOINCREMENT, content TEXT NOT NULL, source_conversation_id INTEGER, created_at TEXT DEFAULT CURRENT_TIMESTAMP );从实际使用体验来说这个设计带来的直接好处是检索效率高、扩展性好。即便你积累了几个月、几千条会话记录查询依然毫秒级响应。而且 SQLite 文件可以直接备份到网盘或同步工具换机器时把文件拷过去就能无缝恢复历史记忆这个便捷性在后面的实操章节我会再提到。2. 核心细节解析与实操要点2.1 安装与初始化全流程claude-mem 的安装方式并不复杂前提是你的机器上已经有 Go 环境或者通过预编译二进制安装。我实测下来最稳妥的方式是直接从 GitHub Releases 下载对应平台的二进制文件放到/usr/local/bin或者任意 PATH 目录下然后执行一次初始化命令。# 使用预编译二进制安装以 Linux/macOS 为例 wget https://github.com/your-repo/claude-mem/releases/latest/download/claude-mem-linux-amd64 mv claude-mem-linux-amd64 /usr/local/bin/claude-mem chmod x /usr/local/bin/claude-mem # 初始化配置 claude-mem init初始化命令会在你的 home 目录下创建claude-mem配置文件夹里面包含配置文件和一个初始化的 SQLite 数据库文件。它还会自动检测你是否安装了 Claude Code并给出钩子配置提示。如果你使用的是 Claude Code 的插件机制它甚至会尝试自动帮你把钩子写进配置里省去手动编辑的步骤。这里我要强调一个容易踩坑的点claude-mem 通过钩子机制与 Claude Code 交互而 Claude Code 的钩子配置路径在不同版本里会有差异。早期版本是写在~/.claude/settings.json里后来迁移到了项目级.claude/settings.json和用户级~/.claude/settings.json并存的结构。claude-mem 初始化时会把钩子的PreToolUse、PostToolUse、Stop等事件写入这些配置中如果多个配置源同时存在可能会发生钩子事件被重复触发或漏触发。我建议的做法是先执行claude-mem init然后打开~/.claude/settings.json检查钩子配置是否完整同时确认项目目录下没有覆盖性的.claude/settings.json文件。如果只在一个终端会话里用 Claude Code保持最简配置就行如果团队协作还涉及到钩子配置是否需要提交到 Git 仓库的问题这个我会在后面的常见问题部分展开。2.2 记忆归档与摘要机制claude-mem 最有价值的部分在于它的摘要机制。它不会把原始对话全文一股脑倒进长期记忆因为那既不经济也不符合语言模型的输入限制。它的设计是“层层压缩”先对单轮对话生成短摘要再对多次会话生成阶段性总结最后在需要时只释放最顶层的总结性记忆。你可以想象成一个书籍归档系统原始手稿放在仓库底层目录卡片放在中间层而最上层只有一本书的一句话简介。当你需要查找某个细节时可以通过摘要中的线索反查原始会话记录而不是要求模型消化整本“书”。从实现层面看claude-mem 在生成摘要时会向 Claude 发送一个专用提示词要求它提炼出“可移植的、去上下文化的、面向未来复用”的信息。所谓“去上下文化”就是不要把“在刚才那个函数里”这种指代模糊的话写进摘要而是明确写成“在utils/date.ts的formatDate函数中”。这个细节非常关键因为如果摘要写得太笼统新会话里的模型根本不知道你在指什么注入再多次也白搭。在我自己的项目里我会定期检查生成的记忆条目发现部分摘要把一些过于动态的内容也记住了比如临时调试用的输出值“临时将超时时间改为 5000ms”这种记忆如果不经过过滤反而会污染后续会话的上下文。好在新版 claude-mem 支持通过配置项控制摘要的详细程度和过滤规则我通常会把summary_max_tokens调低一点让摘要更极简、更偏向结论而非过程。另一个需要了解的操作是claude-mem compact。当你的历史对话积累得足够多时Claude Code 的上下文窗口会出现拥挤这时候 claude-mem 会自动触发压缩把旧轮次对话压缩成摘要释放窗口空间。这个过程是不可见的但它会保留所有摘要供日后查询相当于给会话做了一次“瘦身但不失忆”。2.3 上下文窗口管理策略用过 Claude 的朋友都知道模型有固定的上下文窗口长度比如 200k tokens。理论上窗口很大但实际使用中塞进去 200k tokens 之后不仅成本高而且模型注意力会被稀释响应质量明显下降。所以管理上下文窗口不是“能用就行”而是“精打细算”。claude-mem 的策略是把上下文分成两类核心记忆和参考记忆。核心记忆是与当前任务强相关的信息比如你当前项目里正在重构的模块的决策记录这部分必须放在模型可见的上下文里参考记忆是那些“可能有用但不紧急”的历史信息它们只保存在 SQLite 中当检测到当前会话触发某些关键词时才按需注入。这种分层策略实现的是一种“上下文按需调度”效果。举个例子你在新会话里提到“继续优化数据库查询”claude-mem 会检索之前所有关于“数据库优化”的记忆条目把它们整理成一段摘要注入到 Claude 的上下文中但如果你今天聊的是“写一个前端动画”它就不会把数据库相关的历史记录塞进来避免上下文被无关信息污染。从我的使用感受来看这种调度机制比“把全部历史都塞给模型”要高效得多。每次会话开始时claude-mem 会输出一行“Loaded N memories from previous sessions”让你能直观看到这次注入了多少历史记忆。如果 N 值异常大说明检索规则可能过于宽泛如果 N 始终为 0则说明钩子配置或路径匹配出了问题。具体排查方法我放到第四章。3. 实操过程与核心环节实现3.1 与 Claude Code 的集成配置如果你已经安装好 claude-mem那么接下来最关键的一步就是确保它和 Claude Code 的集成生效。由于 claude-mem 以事件钩子的方式工作它的配置本质就是向 Claude Code 的 settings 文件里注入一段 hooks 规则。以我的环境为例我的用户级配置文件~/.claude/settings.json里最终长这样{ hooks: { PreToolUse: [ { matcher: Bash, hooks: [ { type: command, command: claude-mem hook PreToolUse } ] } ], PostToolUse: [ { matcher: Bash, hooks: [ { type: command, command: claude-mem hook PostToolUse } ] } ], Stop: [ { hooks: [ { type: command, command: claude-mem hook Stop } ] } ] } }这段配置的意思是在执行 Bash 工具之前、之后以及会话停止时自动调用claude-mem hook相关命令让 claude-mem 拿到事件并执行归档工作。配置写好后你可以通过一条测试命令验证钩子是否生效claude-mem test-hooks它会模拟一次 Claude Code 交互检查各个钩子是否能正常被调用并向 SQLite 写入记录。如果输出显示每个事件都是OK说明集成成功。如果出现FAIL多半是环境变量问题比如CLAUDE_MEM_DB_PATH指向的路径不存在或者 claude-mem 二进制不在 Claude Code 子进程的 PATH 中。常见解决方案是把claude-mem软链到/usr/local/bin同时把数据库路径显式写到配置里避免依赖 shell 环境。3.2 常用命令与配置参数解析claude-mem 提供了一组 CLI 命令常用程度各有不同。我把它们整理成一张速查表方便大家对照使用。命令作用典型场景claude-mem init初始化配置和数据库首次安装后使用claude-mem hook供 Claude Code 钩子调用的内部命令无需手动调用claude-mem doctor检查环境配置和钩子状态诊断集不成问题时claude-mem list查看当前项目的历史记忆列表快速回顾最近决策claude-mem show id查看某条记忆的详情和原始来源追溯某个结论的依据claude-mem search 关键词全文搜索记忆内容查找历史解决方案claude-mem stats查看数据库统计信息评估记忆量增长情况claude-mem compact压缩当前会话历史上下文窗口不足时配置参数方面最核心的是CLAUDE_MEM_DB_PATH它决定 SQLite 文件存放在哪里。默认情况下claude-mem 会把数据库存储在~/.claude-mem/memory.db但这个位置对多项目隔离不友好。我建议为每个项目设置独立的数据库文件做法是在项目的根目录下创建一个.env文件写上CLAUDE_MEM_DB_PATH.claude-mem/memory.db这样不同项目的记忆不会互相污染备份和迁移也更加灵活。还有几个值得关注的配置项CLAUDE_MEM_ENABLED总开关设为false时可以临时禁用记忆功能适合排查问题。CLAUDE_MEM_MAX_MEMORIES单次会话最多注入的记忆条数默认 20如果感觉上下文被塞得太满可以调小。CLAUDE_MEM_SUMMARY_INTERVAL摘要生成的触发间隔比如每 10 条消息生成一次摘要保持摘要不过期。这些参数都可以在配置文件中定义也可以作为环境变量动态设置。我个人习惯是环境变量与配置文件结合使用init生成的配置文件负责全局默认值项目级.env负责覆盖该项目的偏好。3.3 数据管理与检索技巧当 claude-mem 运行了一段时间后你的 SQLite 数据库里会积累大量记忆。这时候管理和检索就成为新的问题。先说管理。定期清理是必要的因为不是所有记忆都有长期价值。我通常每周跑一次这个清理流程先执行claude-mem list看看最近记忆再用claude-mem search定位过时内容最后直接用 SQL 删除无效条目。虽然 claude-mem 没有提供delete命令但 SQLite 本身就是文件数据库直接删记录完全可行。# 查看数据库里有多少条记忆 claude-mem stats # 检索包含“数据库优化”关键词的历史记忆 claude-mem search 数据库优化 # 直接通过 sqlite3 删除过时记忆谨慎操作 sqlite3 ~/.claude-mem/memory.db \ DELETE FROM memories WHERE content LIKE %临时% AND created_at date(now, -30 day);再说检索。claude-mem 的搜索命令基于 SQLite 的LIKE查询虽然简单但足够应对大部分场景。如果你对检索有更高要求比如支持语义搜索那可以借助一些外部方案把memory.db定期导入向量数据库再用 embedding 做相似度检索。不过对于绝大多数 CLI 使用场景claude-mem search配合grep管道过滤已经完全够用。我实际用下来最舒服的一个操作是在终端里定义一个别名一键搜索当前项目的所有记忆。alias memclaude-mem search这样直接mem nginx 超时就能看到之前调 nginx 配置文件时留下的一切结论省去翻聊天记录的大量时间。这种工作流一旦建立起来你会慢慢把它当成自己的“第二大脑”用惯之后就再也回不去了。4. 常见问题与排查技巧实录4.1 记忆不生效钩子配置失效排查很多人安装完 claude-mem 后遇到的第一个问题就是“我明明正常和 Claude 聊天为什么新会话里它什么都不记得”这个问题 90% 出在钩子配置没有真正生效上。第一个要核查的是 Claude Code 的配置文件。因为 Claude Code 会合并用户级和项目级配置文件如果你的项目里恰好有一个.claude/settings.json它可能会覆盖掉用户级配置里的 hooks导致 claude-mem 的钩子没有被加载。排查方法其实很简单直接在 Claude Code 会话里执行claude-mem doctor这个命令会打印出当前检测到的配置路径、数据库路径、钩子事件列表以及最近一次归档的文件记录。如果显示类似hooks: Not found那就基本确定是配置被覆盖或者路径不对了。解决办法也很直接要么把 claude-mem 的 hooks 配置也复制到项目级.claude/settings.json中要么干脆删掉项目级配置文件里你不需要的覆盖项。最一劳永逸的做法是写一个初始化脚本在项目模板中默认包含 claude-mem 的 hooks 声明这样新项目拉起来就有记忆功能不会漏配。另一个容易被忽略的点是环境变量 PATH。Claude Code 的钩子命令是在一个受限的 shell 环境里执行的如果你的claude-mem命令装在类似~/.local/bin这种非标准路径而该路径又没有存在于钩子执行的 PATH 环境中就会静默失败。解决方式是把 claude-mem 的完整路径硬编码到 hooks 配置里而不是依赖 PATH 解析{ type: command, command: /Users/yourname/.local/bin/claude-mem hook PostToolUse }4.2 SQLite 数据库冲突与路径问题当你在多个目录之间切换项目时容易遇到数据库“串台”或“找不到库”的问题。我最初把CLAUDE_MEM_DB_PATH设置为某个绝对路径后在另一个项目里也用了同一个数据库结果两个项目的记忆混在了一起搜索出来的内容牛头不对马嘴。虽然 claude-mem 本身会记录project_path字段但在注入上下文时它会根据当前工作目录过滤记忆不过一旦数据库路径指向同一个文件不同项目的会话记录仍然会被写入同一个库中这就会带来两个麻烦一是数据量膨胀导致查询变慢二是跨项目会话的上下文信息仍然会被注入干扰模型判断。为了避免这种混乱我强烈建议每个项目都单独设置一个数据库路径。做法很简单在你的项目根目录创建.env文件# 项目根目录/.env CLAUDE_MEM_DB_PATH/absolute/path/to/your/project/.claude-mem/memory.db同时还需要留意 SQLite 文件的并发写锁问题。当 Claude Code 同时触发多个钩子时比如PreToolUse和PostToolUse在同一瞬间被触发SQLite 默认的 journal 模式在极端情况下会报database is locked错误。如果遇到这个报错可以在连接参数里指定更宽松的 busy timeout或者绕开这个问题的最简单方法是把数据库路径改到本地固态硬盘上千万不要放到网络共享盘否则锁频发到你怀疑人生。4.3 注入记忆过多导致上下文污染问题记忆功能在带来便利的同时也带来了一个隐性副作用如果 claude-mem 注入的记忆条数过多、内容不够精炼反而会把当前会话的核心任务冲淡。举例来说在一次会话里claude-mem 注入了 30 条记忆其中 25 条都是关于旧模块的细节而你这会儿正想让它集中精力写一个新功能模型就会在你提供的庞杂背景中迷惑回答的准确性和专注度都会下降。我遇到过很明显的例子我让 Claude 帮忙写一个 Python 脚本结果它因为继承了太多“项目历史偏好”的记忆反而在脚本开头加了跟任务无关的框架代码。后来我调整了CLAUDE_MEM_MAX_MEMORIES参数从默认的 20 降到了 8问题立刻缓解。在新会话开始时我会直接告诉 Claude“只关注我当前描述的任务不要自动引入历史记忆中的代码风格。”这句话给当前会话设定了边界效果比一味依赖记忆参数调整更直接。调整记忆注入策略可以这样操作# 设置单次会话最多注入 8 条记忆 export CLAUDE_MEM_MAX_MEMORIES8如果你发现某条记忆总是被错误触发更精细的做法是利用 claude-mem 的配置过滤规则。例如在~/.claude-mem/config.toml中设置黑名单关键词凡是内容中包含“临时”或“debug”的记忆条目都不会被注入这样能有效防止临时调试信息混入正式上下文。4.4 常见问题速查表为了节省大家排查时间我把最常遇到的问题整理成了下面这张速查表每一行都是我在实际操作中踩过的坑或者观察到的典型情况。问题现象可能原因解决方案新会话完全不记得旧内容钩子配置未被加载运行claude-mem doctor检查并修复 hooks 配置记忆写入总是报 database is locked多个钩子并发写同一个 SQLite 文件将数据库迁移到本地 SSD并检查是否放在网络挂载盘注入的记忆太多响应跑偏CLAUDE_MEM_MAX_MEMORIES太大调小参数例如改为 8claude-mem 命令不存在安装目录不在 PATH 中使用完整路径配置 hooks或软链到/usr/local/bin项目之间的记忆串台多个项目共用同一个数据库每个项目设置独立的CLAUDE_MEM_DB_PATH记忆内容包含临时调试信息摘要生成时未过滤动态内容在配置中设置过滤关键词排除“临时”等噪声这张表不能覆盖所有问题但大多数初学者遇到的坑基本都能在里面找到对应解法。等到你熟练使用之后还可以结合自己的使用习惯把更适合自己的记忆检索、注入策略慢慢打磨出来让 claude-mem 真正长成你最顺手的个人知识库。我在实际项目中已经连续使用 claude-mem 两个多月最大的感受是它并不是一个“装上就能用”的工具而是需要你花一点时间调教——把它的存储路径、注入数量、过滤规则都调整得贴合自己的工作流之后它才真正从一个“会记事的笔记本”变成“能自动递上资料的第二大脑”。如果你准备深度依赖它我建议从一个小项目开始试验先跑一两天用claude-mem stats和search看看它记住了什么、漏掉了什么再不断调整自己的表述习惯和对配置参数的预期。这样逐步磨合远比一开始就全量启用、然后被海量记忆淹没要舒服得多。