1. 先说说那个让所有Claude Code用户抓狂的场景
最近一段时间,Claude Code在开发者圈子里讨论度很高,但真正长期用它干活的人,多半都会撞上一堵墙:它没有跨会话记忆。
今天上午刚在终端里花四十分钟把项目背景、技术栈选型、代码规范、还有那两个关键目录的作用交代清楚,下午因为电脑重启或者开个新任务,Claude Code就完全忘了这回事。你问它"我们之前定的API命名规范是什么",它会礼貌地告诉你"我没有过去对话的记录"。这种体验有多崩溃,用过的人应该都懂。
我也是在这个痛点里泡了大半个月,才翻到了 claude-mem 这个开源项目。简单说,它是一个专门给 Claude Code 做的记忆管理工具,能在会话结束后自动提取关键信息,分类保存,并在下个会话开始时把相关的记忆重新注入给 Claude。这篇文章不打算写成官方README的翻译,我会从实际使用的角度,把它的原理、配置、坑和一个完整的工作流都过一遍。
先说清楚了:claude-mem 适合两类人。一类是拿 Claude Code 当主力开发助手的重度用户,另一类是团队里希望把"项目隐性知识"沉淀下来的工程效率负责人。如果你只是偶尔问一句"这段代码怎么优化",那它对你来说确实有点大材小用。
2. claude-mem到底做了什么:把会话里的关键信息沉淀成可检索的结构化记忆
2.1 记忆捕获的完整链路:Hook触发、LLM提取、分类、存储
理解 claude-mem,先要理解 Claude Code 的 Hook 机制。它允许你在特定生命周期事件(比如会话开始、每次响应结束)触发外部命令,claude-mem 就是靠这两个 Hook 完成记忆捕获的:
- SessionStart:会话刚启动时,claude-mem 读取已有的记忆并注入给 Claude;
- Stop:每次 Claude 停止输出时,claude-mem 把本次的会话日志抓下来,送给提取引擎处理。
提取引擎本身也是一个 LLM 调用。它会读取这次会话的完整文本,按照预设的记忆类型筛出值得长期保留的信息,然后调用分类器给每条记忆打标签,最后写入存储后端。整个链路可以概括为四个动作:抓取、提取、分类、存储。
我自己刚接触的时候有个误解,以为 claude-mem 是做"全文搜索式记忆",就是像给 ChatGPT 挂个向量数据库那样。后来看代码才发现完全不是,它是摘要式记忆——不是把原始对话存下来,而是让 LLM 提炼出精华,存的是结构化的短句和关键字段。这个区别很重要,后面讲上下文污染的时候还会提到。
2.2 记忆类型体系:从code到preferences
记忆之所以要分类,不是为了好看,是为了让注入有据可依。claude-mem 默认支持以下几类记忆:
| 类型 | 捕获内容举例 | 典型用途 |
|---|---|---|
| code | 项目架构约定、核心依赖、接口设计 | 新会话直接遵循代码风格 |
| design | 架构决策、技术选型理由、权衡取舍 | 避免重复讨论同一决策 |
| files | 文件路径、目录职责、命名规律 | 快速定位文件,减少试探 |
| git | 分支策略、提交规范、常用命令 | 让 Claude 更符合团队 Git 习惯 |
| projects | 项目目标、当前阶段、待办方向 | 保持上下文连续 |
| people | 角色分工、沟通偏好 | 多人在同一仓库协作时减少重复介绍 |
| preferences | 代码风格、工具链、格式要求 | 让输出更贴合个人习惯 |
| system | 系统级环境信息、常用路径 | 减少环境相关误判 |
你就把记忆类型想象成一个档案柜,每类记忆是一层抽屉。提取引擎拿到对话后,先决定这条信息属于哪个抽屉,再决定值不值得归档。比如你说了一句"这个项目用 Vitest 不用 Jest",在 claude-mem 看来这就是一条code类型的记忆;如果你说"我在这个仓库里用 pnpm,别给我推荐 npm",那就进了preferences。
2.3 检索注入:它是怎么知道该把哪段记忆塞给Claude的
只存不取,就没有意义。claude-mem 在 SessionStart 阶段做的是相关性检索,不是全量注入。
它会先看当前会话的上下文条件——最常见的是当前工作目录和 Git 分支——然后从存储中筛选出匹配的记忆。比如你当前在frontend/目录下操作feature/login分支,那它就会倾向注入跟前端文件和登录模块相关的记忆,而不会把后端订单系统的决策一股脑塞进来。
注入方式也不是直接改写你的输入,而是通过生成一份动态的 CLAUDE.md 片段,或者写入系统提示词,让 Claude 在"潜意识"层面知道这些约定。这样做的好处是,你的输入框干干净净,不会看到一大堆记忆噪声混在 prompt 里。
3. 安装与初体验:从npm一行命令到打开TUI界面
3.1 环境预检:你其实只需要一个Node环境和API Key
先说结论:只要你有 Node.js 16+ 和 Claude Code 的环境,装 claude-mem 基本没有任何额外门槛。它本身是 Go 写的二进制,但官方分发走的是 npm,所以 Node 环境是必须的。
另外要准备的是一枚 Anthropic API Key。注意这和你登录 Claude Code 用的账号不是一回事——你可以用同一个账号下的 API Key,但 claude-mem 的提取引擎是独立调用 Anthropic API 的,需要单独配置。如果不想用 Anthropic 官方 API,它也支持配置兼容 OpenAI 协议的本地端点(比如 Ollama),这个后面会细说。
3.2 两种安装方式
安装本身很简单,我用的最快的路径是 npm 全局装:
npm install -g claude-mem装完验证一下版本:
claude-mem --version如果你对 Go 的工具链更熟,也可以从源码装:
go install github.com/thedaviddias/claude-mem@latest两条路都走通的人我见过不少,但更推荐 npm,因为后续升级只需一条命令。说实话,用 Go 源码安装的升级频率一高,就会觉得有点烦。
3.3 init初始化到底做了什么
安装完之后不要急着用,先跑一次初始化:
claude-mem init这个交互式命令会问你四组问题:
- 存储后端:默认是本地 SQLite,如果选了 Supabase 或 Dropbox 会引导你填连接信息;
- Anthropic API Key:填进去之后会写入 claude-mem 自己的配置文件,不会动 Claude Code 的配置;
- API 地址:默认是官方端点,用本地模型的人在这里改成自己的 Ollama 地址;
- 记忆范围的默认开关:哪些类型默认开启捕获,哪些默认关闭。
初始化完成后,它会生成一个配置文件,通常在你的用户目录下,类似~/.claude-mem/config.json。我建议初始化完立刻看一眼这个文件,确认 API Key 和存储路径没写错,避免后面出问题的时候排查半天。
3.4 用status和TUI做最简验证
初始化完,先用status命令看看整体状态:
claude-mem status正常情况下它会显示:配置路径、存储类型、记忆条数、API 连通性等。如果显示异常,优先检查 API Key 和网络。
接下来是最直观的一步——启动它的 TUI 界面:
claude-mem你会进入一个终端交互界面,左边是记忆分类列表,右边是对应分类下的记忆条目。觉得哪条记忆没用,直接删掉;想看某条记忆的原始提取来源,也能查得到。第一次打开 TUI 时记忆是空的,这很正常,接下来要和 Claude Code 绑定才能真正开始积累。
4. 和Claude Code的深度绑定:Hook配置与自动记忆开关
4.1 Hook是记忆的闸门:SessionStart注入、Stop提取
claude-mem 要真正跑起来,必须接进 Claude Code 的 Hook 流程。这一步很多人装完忘做,导致 claude-mem 干转但一个记忆都收不到。
先说原理。Claude Code 的 Hook 配置支持多个触发点,我们关心两个:
- SessionStart:触发时机是每次新会话创建。claude-mem 在这里执行
on-start命令,把相关记忆注入给 Claude; - Stop:触发时机是 Claude 每次生成完回复。claude-mem 在这里执行
on-stop命令,把会话日志提取成记忆。
请留意:Stop是每次回复结束都会触发,不是整个会话结束才触发。也就是说对话过程中 Claude 已经可能触发多次提取了。这也意味着 token 消耗是持续发生的,不是一次性账单。
4.2 配置Hook的两种路径
配 Hook 有两条路,个人推荐第一种:
路径一:用 Claude Code 的 config 命令设置
claude config set --global hooks.SessionStart[0].hooks[0].command "claude-mem on-start" claude config set --global hooks.Stop[0].hooks[0].command "claude-mem on-stop"这是结构化配置,写进 Claude Code 的全局设置文件,后续改动仍然用config命令覆盖,适合长期维护。
路径二:直接编辑 Claude Code 的配置文件
找到~/.claude/settings.json,在里面加上 hooks 段:
{ "hooks": { "SessionStart": [ { "matcher": "startup", "hooks": [ { "type": "command", "command": "claude-mem on-start" } ] } ], "Stop": [ { "matcher": "", "hooks": [ { "type": "command", "command": "claude-mem on-stop" } ] } ] } }两种方式的效果一样。改完之后重开一个 Claude Code 会话,再跑一句claude-mem status,如果 memory 计数开始增长,就说明 Hook 通了。
4.3 手动触发的补充场景
Hook 自动触发能满足 90% 的场景,但有些情况需要手动介入。比如你开着 Claude Code 挂机,没退出终端但在改别的文件,这时候 Claude 可能在等待输入,Stop事件已经触发过了,而你没看到提取结果。可以用:
claude-mem on-stop手动让 claude-mem 执行一次提取。另外,如果你在多个设备上工作,手动跑claude-mem on-start也能把另一台设备上积累的记忆强制拉取到当前会话,对于"早上在公司、晚上在家"的工作流很实用。
5. 让记忆按你的规矩来:自定义规则、存储后端与隐私保护
5.1 自定义提取规则:哪些话题必须记、哪些一概不碰
默认情况下 claude-mem 会从对话里找候选记忆,但它的判断未必完全合你的口味。好在它支持在配置文件里写自定义规则。
我在实际使用中养成了两个习惯:
第一,用 include 规则强制捕获关键内容。比如我在归档规则里写了一条:当对话中出现"用户说"、"客户要求"、"需求变更"这些词时,一定要把上下文里的约束提取进projects类型。原因很简单,AI 对话里最容易被遗忘的就是需求本身的演化过程,而需求恰恰是项目生命周期里最宝贵的上下文。
第二,用 exclude 规则屏蔽噪音。像"谢谢""好的""明白了"这类寒暄,或者 Jira 工单号这种一次性的信息,默认可能会被提取进去,占存储空间不说,还会污染后续会话。我在 exclude 里屏蔽了这些模式,效果立竿见影。
配置完规则后,重启 Claude Code 会话才会生效。
5.2 存储后端对比:SQLite、Supabase还是Dropbox
claude-mem 的存储后端不是一个摆设,不同选择对应完全不同的使用姿势:
| 后端 | 适用场景 | 优点 | 需要注意 |
|---|---|---|---|
| SQLite(本地) | 个人单机使用 | 零配置、响应快、完全离线 | 换设备记忆不迁移 |
| Supabase(云数据库) | 多设备、团队共享 | 跨设备同步、可结构化查询 | 需要开通服务,有额外费用 |
| Dropbox(文件同步) | 个人多设备 | 用现成的同步盘,无服务器成本 | 同步冲突可能丢记忆 |
我个人的选择是:单机开发用 SQLite,简单可靠;但凡有多设备需求,直接上 Supabase。因为 Dropbox 那种文件级同步在 claude-mem 这种"频繁写、偶尔读"的模式下,很容易因为多设备同时写入产生冲突,记忆文件损坏是真的很糟心。
5.3 隐私边界:代码片段会不会被发出去
这个问题几乎每个用过的人都会问。答案分两层:
第一层,提取引擎调用的是 Anthropic API,默认情况下会话内容确实会被发送到 Anthropic 的服务器。如果项目涉及非常敏感的代码或商业机密,这个行为本身需要评估。好在它支持自定义 API 端点,你可以把提取引擎指向本地模型(如 Ollama 里的 Qwen、Llama 等),会话内容完全不出机器。
我个人给公司的内部项目配置的就是本地模型端点,效果上略逊于官方 Claude 模型,但对记忆提取这个任务来说,差距没那么大。如果你追求极致的提取质量,官方 API 更稳;如果更看重合规,本地端点才是安全底线。
第二层,存储内容是摘要不是原文。即便走了 API,存下来的也是 LLM 提炼后的短句,不是对话逐字稿。但别高兴太早,摘要里仍然可能包含代码片段、文件路径、内部命名等敏感信息。所以,控制哪些内容进入提取范围永远比事后删库要靠谱。
6. 一个跨会话的实战演示:从零开始让Claude记住你的项目
6.1 场景设定
光讲原理太虚,我拿一个真实跑过的例子演示。
假设我正在做一个电商后台项目,技术栈是 Next.js + PostgreSQL。我打算在一个会话里把项目基础约定讲清楚,然后开一个新会话验证 Claude 是否记得这些约定。
6.2 会话一:建立项目记忆
打开 Claude Code,我输入:
这个项目前端用了 Next.js App Router,后端是 PostgreSQL + Prisma。 所有 API 路由放在 app/api 目录下,没有单独的 /pages/api。 数据库表命名统一用复数 snake_case。 代码格式化用 Prettier,不用 ESLint 的 stylistic 规则。 用户模块的权限字段叫 role,取值范围只有 admin / operator / viewer。这一步我的预期是:claude-mem 的提取引擎在 Stop 触发后,应该把其中几条识别为code或preferences类型的记忆。等对话结束,我立刻跑一下:
claude-mem recall输出里出现了大概 4 条记忆,比如"Next.js App Router + Prisma + PostgreSQL 架构"、"API 路由位于 app/api"、"数据库表名采用复数 snake_case"。NAME="claude-mem" 这句没有,但记忆内容基本抓全了。
唯一没进记忆的是最后那条权限字段取值。原因是我的排除规则里有一条"仅出现一次的枚举值不记",这正好符合我的预期,我不希望 Claude 把这种细碎的枚举约定当成长期记忆,太容易过期。
6.3 会话二:验证记忆是否真的跨会话工作了
关掉会话一,完全重开一个新的 Claude Code 会话。这次我直接问:
刚才我们定的数据库表命名规则是什么?还有 API 路由放在哪个目录?Claude 的回答是:"数据库表名使用复数 snake_case,API 路由统一放在 app/api 目录下。"
它答对了。这说明 SessionStart 注入确实把记忆送进了 Claude 的系统提示。为了进一步验证,我又抛了一个测试:
现在我要创建一个订单表,你按项目约定给我生成 Prisma schema 片段。结果生成的表名是orders,外键命名为user_id,完全符合复数 snake_case 和你没再重复交代的偏好。这说明记忆不仅被"看到"了,还能影响实际的代码生成行为,这比单纯记忆复述有价值得多。
7. 我用了一个月后的避坑清单
7.1 最容易翻车的Hook配置问题
Hook 配了但 claude-mem 没反应,这是我见过最多的问题,自己也踩过。最典型的根因有两个:
一是配置作用域不对。Claude Code 的~/.claude/settings.json有全局和项目两层,如果你在项目里改了.claude/settings.json,但 claude-mem 是靠全局生效的,那自然不工作。要么把 Hook 配到全局,要么确认你改的就是项目那份。
二是 matcher 干扰。SessionStart的 matcher 默认值应该是startup,不要乱改成空字符串或别的词。有一次我把 matcher 改成了"start"想匹配得更宽,结果 Hook 直接不触发了。这个字段的取值是 Claude Code 内部约定的,不是随便给的。
排查的时候建议用:
claude-mem log看提取日志里是否有每次 Stop 调用的记录。如果没有,说明 Hook 压根没调起来;如果有但有报错,再顺着日志去查 API Key 或者网络。
7.2 记忆膨胀与上下文污染
claude-mem 用了一段时间后,记忆条数会快速增长。这个"增长"并不总是好事。记忆注入到 Claude 的系统提示后,会占用上下文窗口。如果积累了几百条记忆,每一条又都带着细节,不用多,注入几十条就够让 Claude 的注意力涣散。常见表现是:它答非所问,或者过度依赖某一类记忆,甚至用旧约定覆盖了你当前明确提出的新指令。
防止记忆膨胀,我的做法有三条:
- 定期在 TUI 里清理记忆,过期的、已被替代的约定直接删;
- 严格控制提取阈值,让 claude-mem 只保留真正重要的内容,减少无效记忆入库;
- 利用 exclude 规则屏蔽一次性信息,从源头上减少垃圾进账。
另外要注意不同会话里可能提取出互相矛盾的记忆。比如某次对话你说"不要用 ES Modules",下次又说"试试 ESM 吧",两条都会被存进去。下次会话注入时 Claude 看到两条矛盾指令,它对到底该听哪个的判断很可能会摇摆。我在实际项目里遇到过一次,最终靠手动删掉旧记忆才恢复正常。所以这个工具不是装完就万事大吉,它需要持续的维护。
7.3 成本控制:别让提取API偷走你的预算
记忆提取是持续调用 LLM 的,而且每次 Stop 都会触发。一天高强度用下来,token 消耗是真的会让人肉疼。我自己的使用量大概是每天 200-400 次调用,提取引擎用默认模型的情况下,月消耗会比纯粹使用 Claude Code 多出大概 30% 到 50% 的成本。
控制成本有三个实际有效的手段:
- 降低提取频率,把 Hook 从每次 Stop 触发改成只在特定时机触发。不过这会降低记忆捕获的完整性,需要自己权衡;
- 换更小的提取模型,如果你的 API 支持指定模型版本,选择响应快、token 单价低的小模型;
- 本地部署提取引擎,用 Ollama 跑小而快的模型,按量成本几乎为零,只是提取质量会比 Claude 官方模型稍弱。
我自己现在用的是折中方案:主会话用官方 API,提取引擎切到一个中档模型,既保证提取质量,又把 token 成本压到可接受范围。
还有一个容易忽略的消耗点:多设备同时用 claude-mem。如果公司电脑和家里电脑都连着同一个云端存储后端,两边会话都会触发提取,成本是叠加的。出门在外偶尔用一下手机上的 Claude Code 会话,也可能产生同样的提取费用。做到心里有数,账单来了才不慌。
8. 最后再分享一点对"记忆工具"的边界感
工具是好工具,但我不建议你把 claude-mem 当成一个"什么都往里面扔"的仓库。AI 编程助手的记忆功能,和人的记忆一样,真正有价值的不是记得多,而是记得准、记得少。一段对话里真正值得跨会话保留的信息,可能只有两三条,把它们提出来、分好类、在下个需要它的时刻精准送回去,这套流程才算跑到了点子上。
如果你还在用 Claude Code 每次重复交代项目背景,那 claude-mem 值得你拿出半小时来配一遍。第一周可能感觉不明显,等到某天你新建会话、不用提醒一句、它自动说出你上个月定下的技术决策时,你就会明白这个工具的价值到底在哪里。