如果你每天用 Claude Code 写代码,一定经历过这个场景:昨天还在跟它讨论某段逻辑的重构方案,今天开个新会话,它一脸茫然地看着你,好像你们从来没聊过。这不是模型变笨了,而是 Claude Code 默认没有跨会话的长期记忆——每个新会话都是从零开始。为了解决这个问题,我在项目里接入了 claude-mem,一个给 Claude Code 加长期记忆的开源工具。这篇文章把我从安装、配置到实际使用积累的经验都写下来,包括它的原理、完整的接入流程、记忆的提取和排序机制,以及我踩过的几个坑。如果你正在用 Claude Code 做长期项目、想让它记住你的技术决策和项目偏好,这篇应该能帮你省不少时间。
1. Claude Code 的"失忆"问题与 claude-mem 的定位
1.1 会话割裂带来的真实痛点
Claude Code 是跑在终端里的 AI 编程 Agent,能读写文件、执行命令、主动规划任务,效率确实高。但它有一个非常明显的短板:会话之间不共享记忆。每个新会话启动时,它对之前的对话毫无概念,除非你把上下文重新贴给它。
这个问题在单次任务里影响不大,但在一个持续几周甚至几个月的项目里会越来越扎眼。上次确定的架构决策、约好的接口命名规范、排查到一半的 Bug 线索,到了新会话全被当成"第一次听说"。你只能重复一遍背景,然后祈祷这次的理解跟上次一致。
有人会反驳:"不是有 CLAUDE.md 吗?" 确实,CLAUDE.md 可以放项目级说明,但它本质是静态文档,需要你手动维护。对话里临时定下的技术选型、你对某个模块的口头要求、一次调试过程中发现的隐性约束,很难每次都有空整理进 CLAUDE.md。等你想起来要写,细节早就丢了。静态文档和动态对话之间存在一个巨大的管理空档,claude-mem 就是补这个空档的。
1.2 claude-mem 不是聊天记录备份
claude-mem 的定位不是"存档聊天内容",而是做一层可检索的结构化记忆。它通过 MCP(Model Context Protocol)跟 Claude Code 连接,在对话过程中自动提取值得记住的信息,整理成带重要性权重、标签和分类的记忆条目,存到本地数据库。等下次开新会话,Claude Code 会调用检索接口,把跟当前任务相关的记忆拉出来作为上下文的一部分。这样一来,昨天讨论的方案,今天它确实"记得"。
这个设计的核心价值在于:把"记忆"从手工维护的文档,变成了自动沉淀、按需调取的信息资产。它适合所有把 Claude Code 当作日常开发工具的人,尤其是长期项目、多人协作、频繁切换任务的场景。
2. 一条记忆从产生到被召回:claude-mem 的工作链路
2.1 从对话到记忆的四个阶段
我习惯把 claude-mem 的工作流程拆成四步:提取、嵌入、存储、检索。
第一步是自动提取。claude-mem 会周期性拿当前对话内容,通过内部提示词让语言模型提炼要点,比如技术决策、项目约定、用户偏好、任务进展。每次提取完会生成候选记忆,并打上重要性分数和分类。这一步是异步的,不阻塞主对话,所以你会感觉不到它在干活。
第二步是嵌入。候选记忆要转成向量才能做语义检索,claude-mem 用的是 FastEmbed 加 ONNX Runtime,模型在本地跑。这一步决定了后续检索是"按意思找"而不是"按关键词找"。
第三步是存储。向量和原始文本一起落到数据库,默认是 SQLite,也可以切换成 PostgreSQL。每条记忆还附带 created_at、last_accessed_at、access_count 这类元数据,方便后续做权重衰减和清理。
第四步才是用户能感知的部分——检索。新会话开始或在对话过程中,Claude Code 会调用 run_memory_search 工具,拿当前的问题去语义匹配记忆库,返回最相关的一批结果注入上下文。整个过程对使用者是透明的,你只看到它"突然想起了之前的事"。
2.2 关键组件与数据流向
这里面的几个关键组件值得单独说。MCP Server 是跟 Claude Code 通信的桥梁,所有工具调用都走它;FastEmbed 是嵌入引擎,负责把文本变成向量;SQLite/PostgreSQL 是记忆的物理载体;提取队列负责异步处理对话文本。
可以用一个生活化的类比:提取阶段像你每天睡前在脑子里过一遍今天发生的事,挑出值得记的;嵌入阶段像把每件事浓缩成一句话并贴好标签;存储阶段像把纸条放进抽屉并按主题归类;检索阶段像第二天遇到相关话题时,从抽屉里翻出对应的纸条。少了任何一个环节,记忆都不成立。
2.3 为什么语义检索比关键词检索更适合这里
这是 claude-mem 设计和传统存档方式最大的区别。对话里的同一件事可能有无数种说法,你问"上次那个接口怎么改的",存的时候可能是"把 /users 接口的鉴权逻辑抽到中间件"。关键词检索永远匹配不上这两个说法,但语义检索可以。向量化的本质是把语言映射到高维空间里,意思相近的句子距离相近,所以能兜住这种口语化、碎片化的表达差异。实测下来,跨会话召回准确率比我预想的高很多。
3. 接入 Claude Code 的完整安装与配置流程
3.1 安装前的准备与 uv 方式
claude-mem 本质是一个运行在本地的服务进程,所以要求你的机器上已经装好 Claude Code CLI。安装方式有三条路:Python 生态的 uv/pipx、npm、Docker。我推荐第一条,因为 claude-mem 是 Python 写的,用 uv 管理依赖最干净,不会把全局 Python 环境搞得一团糟。
以 uv 方式为例,先在终端执行安装:
uv tool install claude-mem装完之后,把 claude-mem 的 MCP 服务注册进 Claude Code。MCP 协议就是让 Claude Code 发现工具并调用它的标准通道,没有这一步,两边根本不认识。注册命令长这样:
claude mcp add --transport stdio claude-mem -- uv tool run claude-mem mcp3.2 三种接入方式的选型
npm 方式适合你没装 Python、或者团队统一用 Node 环境的情况:
npm install -g claude-mem claude mcp add --transport stdio claude-mem -- npx claude-mem mcpDocker 方式更适合服务器部署或者多人共享一个记忆库。它一般是起一个 HTTP 服务,然后把 Claude Code 通过 http 传输接过去:
docker run -d -p 8000:8000 <官方镜像名> claude mcp add --transport http claude-mem --url http://localhost:8000/mcpDocker 的具体镜像名和 HTTP 路径以仓库 README 标注为准,版本之间可能有差异。三种方式的区别我整理了一下:
| 方式 | 适合场景 | 优点 | 需要注意的点 |
|---|---|---|---|
| uv/pipx | 本地单机开发 | 环境隔离干净、版本管理方便 | 需要 Python 环境 |
| npm | 已有 Node 工具链 | 一条命令装好 | 依赖 Node 运行时 |
| Docker | 团队共享/服务器部署 | 环境完全封装、可远程 | 要维护容器和网络 |
我个人是本地开发用 uv,团队服务用 Docker。切换成本很低,记忆库都在同一个 SQLite 或 PostgreSQL 文件里,接哪个服务只是数据库指向的问题。
3.3 验证接入是否成功
配置完最重要的一步是验证。先跑:
claude mcp list如果看到 claude-mem 在列表里且状态正常,说明 MCP 注册成功。然后新开一个 Claude Code 会话,直接试一下斜杠命令:
/mem search 数据库迁移能返回结果(哪怕是空结果)就说明工具链路通了。第一次用的时候,我建议先手动存一条记忆再搜一遍,最直观:
/mem store 记住:本项目接口统一走 /api/v1 前缀 /mem search /api/v1 接口规范如果返回了你刚存的内容,恭喜,记忆循环已经跑起来了。
4. 记忆的自动提取、手动管理与排序机制
4.1 自动提取到底提取了什么
claude-mem 最省心的是自动提取。默认情况下,它会在对话进行中或结束后,把会话文本交给一个内置的提取提示词,产出结构化记忆。我观察到的典型提取内容是:技术选型及理由、项目结构和模块职责、你反复强调的编码偏好、尚未完成的待办、踩过的坑和解决方案。每条记忆会带 importance 分数(0 到 1),分数越高说明这条信息越值得长期保留。
自动提取可以随时开关,对话里输入:
/mem auto off关掉之后,它只响应你手动触发的存储和搜索。我建议刚上手阶段保持开启,跑一周之后再看库里存了什么、有没有噪声,再决定要不要收紧。别一开始就关掉自动提取,那样你根本感受不到这个工具的核心能力。
4.2 手动存储、检索和查看全部记忆
自动提取之外,手动接口是我日常用得最多的。除了前面提到的 /mem store 和 /mem search 之外,还有两个工具值得掌握:store_memory 可以让 Claude 在对话过程中把临时决定直接写进记忆;get_all_memories 可以拉取指定分类下的全部记忆,适合做定期复盘和清理。
工具层面的调用是 Claude Code 自动完成的,你不需要手写,但理解它们的存在能帮你判断当前会话为什么突然带上了某段记忆。如果你想让它忘掉某些内容,目前没有一键删除的斜杠命令,我后面会说我是怎么在 SQLite 里清理的。
4.3 权重、分类与去重如何影响排序
同一个记忆库里会积累几百上千条记忆,不是每条都值得在这次会话拿出来。claude-mem 的排序规则是多因素叠加:语义相似度是基础,importance 分数加权,access_count 和 last_accessed_at 会做时间衰减——很久没访问的低分记忆会被压到后面,最近常在用的关键记忆排前面。这跟算法推荐有点像,"越相关、越重要、越常用"的记忆越容易被召回。
分类和去重也参与排序。每条记忆可以有 category,你可以自定义分类名称,比如 architecture、bugfix、style、user-preference。检索时如果当前任务能推断出分类,会做一次过滤。去重则是靠嵌入空间里的相似度阈值,如果新记忆跟已有记忆距离太近,会被合并或丢弃。这套机制保证了记忆库不会无限膨胀成垃圾堆。
5. 个性化配置与隐私边界
5.1 调整分类和系统提示词,让记忆更贴你的项目
安装时默认的分类体系适合通用场景,但我的建议是拿到项目第一天就改。claude-mem 的配置文件按 YAML 格式维护,里面可以自定义记忆分类列表、自动提取开关、搜索返回数量、是否启用重排序等。我会把分类改成项目相关的名字,比如 ledger-service、auth-refactor、data-migration。这样检索结果更精准,复盘时也一眼能看懂。
系统提示词也是可配的。CLAUDE.md 是给 Claude Code 的项目级指令,claude-mem 类似地允许你定制"记忆如何被呈现"。比如你希望它每次带出记忆时附带来源会话信息,或者只允许它引用高权重的记忆,都可以在配置里调。这一步对结果质量影响很大,值得花十分钟调一版。
5.2 本地嵌入的隐私价值
我对 claude-mem 最满意的一点是隐私设计。它做嵌入用的 FastEmbed + ONNX Runtime 模型完全跑在本机,对话内容、记忆内容都不会因为"向量化"这一步被发送到第三方。记忆默认存在本地 SQLite,数据不出机器。
如果你看到某些配置项可以接云端的 Embedding 服务,不要被那个便利吸引——一旦走云嵌入,你的对话摘要就离开本地了。除非你明确接受这一点,否则本地嵌入是更稳妥的选择。另外,claude-mem 有些可选功能需要调用外部搜索 API 来丰富记忆,比如某些网络检索增强配置,这类功能默认不开,开启后查询词会发给第三方搜索服务。弄清楚哪些数据在本地、哪些会出网,再用才安心。
5.3 PostgreSQL 与 Docker 化部署
单机开发用 SQLite 完全够,但团队场景会有两个问题:一是记忆库分散在各人机器上,每个人记得的东西不一样;二是 SQLite 并发写的能力有限。claude-mem 支持把记忆库切换到 PostgreSQL,这样团队可以共用一个记忆库,所有成员检索到的都是同一套上下文。配合 Docker 部署的 MCP 服务,相当于给团队一个统一的"项目大脑",新人进来能快速获得历史上下文,老人也不用反复解释背景。
不过要提醒一句:共享记忆库意味着所有成员的对话都会被提取写入,团队规范上要约定清楚什么内容可以进库。这属于工程治理问题,工具本身给不了答案,但用久了你会发现,明确边界比多一个功能更重要。
6. 实测效果、常见坑与我的使用建议
6.1 几个典型场景的真实效果
跑了两周之后,我感受最明显的场景有三个。第一个是跨天回归,头天讨论完的模块重构方案,第二天新会话直接能接着往下写,不需要我把结论重新铺一遍。第二个是项目术语统一,我们有个服务叫 ledger,库里沉淀了它和 payment 的边界约定,后面生成的代码很少再混淆这两个概念。第三个是调试上下文延续,某次排查性能问题找到的根因记录在案,两周后同类问题再出现,它直接说出"上次我们已经定位到是索引缺失"。
当然它也有局限。claude-mem 不是数据库,复杂的关系型知识它表达得不够好;它也不是实时系统,提取队列有延迟,刚聊完就去搜可能还是搜不到。理解这些边界,才能正确使用它。
6.2 我踩过的坑和对应的排查思路
先说最常见的 MCP 没生效。表现是 /mem 命令无反应,或者会话里根本看不到相关工具。排查链路是:先 claude mcp list 确认注册,再确认命令里的可执行文件路径在当前 shell 可用,最后重启 Claude Code。我遇到过 uv 安装后 PATH 没更新的情况,重启终端才正常。
第二个坑是搜不到刚聊的内容。这不是故障,是提取队列还没跑完。claude-mem 的提取是异步的,长对话要等一等。排查时先看配置里 auto extract 是否开启,再等十几秒重试,还不行就开 DEBUG 日志确认提取任务有没有报错。
第三个坑是记忆污染。当库里积累了几百条低分记忆,检索结果里会出现不相关的内容,既浪费上下文窗口又干扰判断。我的处理方案是:把搜索返回条数往下调,只保留最高的三五条;定期按分类检查记忆库,把明显过时或错误的记录清掉;通过 importance 阈值过滤掉低分碎片信息。删记录我直接查 SQLite 表操作,先备份再删,别一次删过头。
我把常见问题整理成了一张表,方便你直接对照:
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| /mem 命令无响应 | MCP 未注册或进程未启动 | 核查 claude mcp list,重启会话 |
| 搜不到刚聊的内容 | 异步提取队列未完成 | 等待重试,确认 auto extract 开启 |
| 检索结果混杂无关内容 | 低权重记忆太多 | 调低返回数量、清理记忆库、设 importance 阈值 |
| 记忆重复出现 | 去重阈值不敏感 | 检查是否启用了重排序,重新评估阈值 |
| 团队记忆不同步 | 各自使用本地 SQLite | 统一切到 PostgreSQL 共享库 |
6.3 跟 CLAUDE.md 配合使用的分工
最后说说我现在的使用分工。CLAUDE.md 放"稳定不变的硬约束":技术栈、目录规范、构建命令。claude-mem 放"对话中产生的软知识":临时决策、踩坑结论、偏好约定、历史上下文。两者互补,不冲突。硬约束如果只放记忆里,换个会话环境可能就丢了;软知识如果全写进 CLAUDE.md,文档会变得臃肿且没人维护。
实际操作中,我一般每周花十分钟看一眼记忆库,删掉过时的、合并重复的、补两条值得长期保留的关键结论。这个习惯跟整理笔记很像——工具负责自动收集,人负责最终把关。跑顺之后,你会明显感受到 Claude Code 从"每次都是新朋友"变成"了解项目来龙去脉的老同事"。