我先交代一下背景。如果你做 AI 辅助开发已经有段时间,肯定遇到过这样的情况:Claude 明明在半天前帮你把某个模块的设计定了方案,还顺手写进了项目文档,可今天重新打开会话,它却像初次见面一样问你“这个模块的需求是什么”。这不是模型变笨了,而是 Claude Code 这类终端 AI 编程工具的上下文窗口终究有限,开着长会话会爆,关掉旧会话就没记忆。你需要的,是一个能把项目关键信息沉淀下来、跨会话复用的记忆层。
claude-mem解决的就是这个问题。它是一个开源项目,核心是在 Claude Code 之外构建一个持久的记忆存储系统,把整个项目生命周期里的技术决策、用户偏好、关键约束、常用命令全部记录下来,在后续会话中自动注入给助手。实话说,我一开始对这玩意儿是半信半疑的——不就一个写配置文件的工具嘛——但用了三周之后,它确实让我对“AI 辅助开发”的体感上了一个台阶。如果你也在用 Claude Code 跑真实项目,这篇文章值得你花五分钟看完,里面所有坑我都替你踩过了。
1. 为什么需要 claude-mem:从一个真实痛点说起
1.1 Claude Code 的上下文困境
先说清楚背景。Claude Code 的强大我已经不用多吹,但它的短板非常明显:上下文受限于窗口大小,而且对话一结束,所有临时记忆都归零。早期网上流传的玩法是把项目重要内容写进CLAUDE.md文件,让 Claude 每次启动都自动读一遍。这个思路有效,但问题在于CLAUDE.md是一个静态文件,它只记录你手动写进去的内容,不会随着 AI 思考、决策、踩坑而自动更新。
举个例子。上周我在一个 monorepo 工程里做依赖升级,遇到了一个很隐蔽的兼容性问题:某个子包用了旧版 Node.js 的 API,升级 node 版本后构建失败。我花了两小时定位,最后 Claude 帮我在代码注释里写清楚了原因,但这段“上下文”只存在于那个会话里。第二天我换了个任务开新会话,让 Claude 处理另一个包时,它又开始建议我“试试升级 node”——完全忘了昨天刚踩过这个坑,差点把问题重新引入一次。这就是上下文隔离造成的重复劳动。
1.2 claude-mem 的解决思路
claude-mem的思路比手动维护CLAUDE.md高出一截。它不是一个“提示词文件”,而是一套带存储层的记忆系统,核心模块包括:SQLite 数据库做结构化事件存储、向量引擎做语义搜索、以及推理客户端(通过 Anthropic API)从对话记录中自动提炼记忆。每次 Claude Code 会话结束后,它会分析这段对话,自动提取出技术决策、命令别名、代码注意事项等信息,按类型写入记忆库。下次会话开始时,这些记忆会根据当前任务需求被自动检索并注入到提示词里。
这么说可能有点抽象。打个比方:CLAUDE.md像一张贴在工位上的便签,写什么全看你记得住;claude-mem则像一个随身的项目经理助理,每次开完会它自己写会议纪要,下次帮你做方案时自动把历史约束翻出来提醒你。你不用管它记了什么,只需要知道该记的它大多记了。
1.3 项目核心架构拆解
claude-mem的架构并不复杂,但从工程角度讲挺讲究的。它由三个核心组件构成:
- SQLite 存储层:所有记忆事件以结构化数据存储,默认路径在
~/.claude-mem/memories.db和配套events.db。SQLite 选择很合理——零运维、单文件、查询快,个人项目和中小团队完全够用。 - 向量索引与语义搜索:单纯存数据库没用,关键是“在合适的时机把合适的记忆找出来”。
claude-mem使用向量嵌入,把记忆内容转化为高维向量,在会话启动时计算当前任务与历史记忆的语义相似度,只注入最相关的那几条。 - 推理提取层:它不是直接把原始对话扔进数据库,而是调用一次模型推理(默认使用 Anthropic 的模型),把散落在对话里的信息抽成结构化的
MemoryEvent数据,比如标题(summary)、内容(observation)、类别(category:command/decisions/notes/technical 等)。这一步非常关键,保证了写入的记忆是“提炼过”的,而不是流水账。
理清楚这层架构你就会明白:为什么这个东西能跨会话工作,而CLAUDE.md不行。因为它不仅仅是一个存储方案,还在存储前后做了语义处理——写入时提炼,读取时检索。后面我会带你亲手把它跑起来。
2. 从零搭建 claude-mem:安装与环境准备
2.1 前置条件与工具选型
动手之前先确认环境。claude-mem依赖 Node.js(建议 v20+)、npm 以及一个可用的 Anthropic API Key。它本身是一个 Node 包,通过全局命令方式运行,同时通过 MCP(Model Context Protocol)协议作为 Claude Code 的插件接入。
这里有一个工具选型值得说一下:你如果用的是 Claude Code 官方 CLI,那么接入 MCP 服务是最顺的路径;但如果你是自己写了脚本调用 API,claude-mem也提供了一个 HTTP 接口模式,你可以直接和它的本地服务通信。大多数情况下我们走 MCP 方案,因为 Claude Code 自己就支持claude mcp add这条命令,加一个本地服务几乎是无痛的。
顺序上我建议:先装 Claude Code 再装 claude-mem。因为后续步骤里我们要用 Claude Code 的 MCP 注册命令来让两个工具互相认识。如果还没装 Claude Code,直接执行:
npm install -g @anthropic-ai/claude-code注意安装完先跑一次claude完成账号登录和基础初始化,确认终端里能正常使用。
2.2 安装 claude-mem
全局安装非常直接:
npm install -g claude-mem安装完成后,先检查一下环境变量是否生效、命令是否可用:
claude-mem --version如果找不到命令,八成是 npm 全局目录没进 PATH。在 macOS 上常见的是:
export PATH="$HOME/.npm-global/bin:$PATH"或者重新配置 npm prefix,这里不赘述,装过 Node 全局包的人应该都会处理。
2.3 创建与配置记忆存储
安装完成之后,第一件要做的事是初始化记忆库。我在一个 React + TypeScript 项目里试的时候,先进入项目根目录,执行:
claude-mem init --workspace my-react-app这个workspace是很重要的概念。你可以把它理解成“记忆隔离区”——每个项目一个 workspace,记忆互不混淆。如果你不指定--workspace,命令会尝试从当前目录读取项目名,但实测下来,在 monorepo 或者目录名和项目名不一致的场景下经常猜不准,干脆手动传更干净。
执行完之后检查一下目录结构,正常情况下应该生成.claude-mem/文件夹,里面有索引目录、日志目录和配置文件。同时你的 home 目录下会出现~/.claude-mem/,存放全局数据库。SQLite 文件就在那里。
初始化完记得配一下环境变量,核心是ANTHROPIC_API_KEY:
export ANTHROPIC_API_KEY="sk-ant-xxxx"这个 Key 用于调用模型做记忆提取。没有它,claude-mem也能装能跑,但“自动提炼记忆”的核心功能就废了。建议写到你的 shell 配置文件里(.zshrc/.bashrc),避免每次重启终端丢失。
另外还有一个重要变量:CLAUDE_MEM_MCP_CONFIG_ANTHROPIC_MODEL,控制记忆提取用的模型名,默认是claude-3-5-sonnet-20241022,如果你的账号能访问更新的模型,可以换成claude-sonnet-4-0之类的(根据实际可用性调整)。
2.4 接入 Claude Code(MCP 配置)
这是最核心的一步,搞清楚了整个工具才算真正激活。
打开你的 Claude Code(在项目根目录运行claude),然后在聊天框中执行:
/claude mcp add claude-mem --env KEY=value -- command这里command部分就是启动 claude-mem 本地服务的命令。不同场景会有差别,常见的有两种。如果你全局安装装对了,最省事的写法是:
/claude mcp add claude-mem -- npx claude-mem mcp如果你喜欢指定 Node 直接启动:
/claude mcp add claude-mem -- node /path/to/claude-mem/build/src/cli.js mcp这里我需要解释一下 MCP 是什么。MCP 是一个标准化协议,简单说就是让 Claude Code 能够像“插U盘”一样接入外部工具和数据源。claude-mem 通过 MCP 暴露了几个关键工具给 Claude Code,比如memory_search、memory_create、memory_update,Claude 在对话中会自行决定何时调用它们,把关键信息写入记忆库,或者在需要时检索记忆。配置完成后,你不需要在对话里手动触发,Claude 会“感知”到记忆工具的存在。
配置成功的话,Claude Code 会回显一条消息,说明 tool 已经连上。之后退出并重启 Claude Code,让 MCP 服务重新加载。如果一切正常,你能通过下面命令看到已连接的 MCP 服务:
/claude mcp list到这一步,claude-mem就已经和 Claude Code 接上线了。接下来的问题是:它怎么知道该记什么?以及,记忆是怎么在工作流里自动流转的?这就是下一章要聊的内容。
3. 核心配置与记忆数据流
3.1 环境变量的作用与配置
claude-mem不是装完就完美适配所有人,需要根据自己的需求做一点环境配置。我把核心变量列一个表,方便查阅:
| 变量名 | 作用 | 默认值 | 备注 |
|---|---|---|---|
ANTHROPIC_API_KEY | 调模型翻译记忆 | 无 | 必填,否则无法自动提取 |
CLAUDE_MEM_MCP_CONFIG_ANTHROPIC_MODEL | 记忆提取用模型 | claude-3-5-sonnet-20241022 | 建议选便宜快的模型 |
CLAUDE_MEM_MCP_BASE_URL | 自定义 API 网关地址 | Anthropic 官方 | 走代理/网关时使用 |
CLAUDE_MEM_MCP_MAX_TOKEN_CAP | 记忆注入的最大 token 预算 | 默认几百到 1000 | 调太大会挤压任务上下文 |
CLAUDE_MEM_INDEXER_BATCH_SIZE | 向量索引批处理大小 | 20 | 数据量大时调大能提速 |
这里面我最想提醒的是CLAUDE_MEM_MCP_MAX_TOKEN_CAP。也就是说,Claude 启动时最多只会塞给它多少 token 的“记忆片段”。如果你把项目历史所有记忆全塞进去,一方面 Claude 的注意力会被淹没,另一方面也会占用大量任务上下文空间,得不偿失。官方默认值在几百 token 量级,我建议不管项目多大,先维持 500 token 左右,跑几天觉得记忆不足再往上加一点。
3.2 workspace 与记忆隔离
说到 workspace,多说几句。claude-mem init --workspace <名称>生成的是一个独立记忆空间。这样做的理由很实际:你不可能让写 React 项目的记忆去污染服务端 Go 项目的上下文,两边的技术栈、约束、决策完全不同,混在一起 Claude 会被误导。
在多项目机器上,这一步的重要性会被放大。我就遇到过一次:前一天在 A 项目记录了“不要用 npm 直接安装,必须 pnpm”,第二天去 B 项目工作时,Claude 居然把这个记忆也带过来了,开始建议我“这个项目要不要也统一用 pnpm”?它在 A 项目是对的,在 B 项目是灾难。所以无论多着急,每个项目都要单独 init 一个 workspace,并且确保工作目录正确。你在项目根目录启动claude,它天然会和各种工具形成工作目录绑定,但这不代表记忆库会自动隔离。
3.3 记忆如何被自动提取与注入
这里有一个很多人没搞懂的问题:claude-mem不是在你打字的过程中实时记忆的。它的运作节奏是“事件驱动”的——关键节点触发记忆记录,而不是逐字记录整个对话。
默认机制是这样的:当一次 Claude Code 会话结束时,claude-mem 会分析整个对话记录,提取出结构化记忆事件。所以你会看到网上有人吐槽“怎么我聊了半天它什么都没记住”——因为它要等你结束会话后才开始提取。你可以在项目里主动让 Claude 调memory_create工具手动记录,也可以在会话结束后等它自动完成提炼。
自动提取的数据主要分四类:
- decisions:技术选型与架构决策,比如“选择 Vue 3 Composition API 而非 Options API”
- commands:项目常用命令,比如“测试使用 vitest --watch 运行”
- notes/technical:技术约束和踩坑记录,比如“node 版本低于 18 不能用 fetch”
- preferences:开发者偏好,比如“注释用中文写”“变量命名用 camelCase”
到了新会话开始的时候,claude-mem 会做一次语义检索:读取当前项目的任务描述(比如 Claude Code 自动生成的 session 摘要),从记忆库中检索最相关的事件,按 token 预算截断后注入到系统提示词里。
这个“按需注入”的设计值得说道说道。之前有些记忆类工具是“全量注入”,把历史笔记一股脑塞给模型,结果上下文占用大且噪声高。claude-mem越好用的地方恰恰在于它做了语义检索——只给当前任务最相关的记忆。实测下来,它对 token 的占用是非常克制的,对任务上下文的影响也小。
3.4 查询与监控记忆内容的方法
记忆系统是个黑盒就会让人不放心。好在claude-mem提供了一组 CLI 命令来查看记忆库的实时状态。
进入项目根目录执行:
claude-mem --workspace my-react-app这个交互式命令会打开 REPL,你可以输入自然语言查询记忆,比如“这个项目的测试命令是什么?”或者“为什么不能用 npm?”它本质上是在调记忆库做语义检索。
如果想看看数据库里到底存了什么,有个更粗暴的方式(适合技术人):
sqlite3 ~/.claude-mem/events.db "SELECT category, summary FROM memory_events ORDER BY created_at DESC LIMIT 20;"在实际使用中你会慢慢发现,它记录的东西不全是你预期的——有时候会把一些片段性的观察当成重要决策写入,但无伤大雅。真正影响体验的反倒是下面这些坑。
4. 常见问题与排查实录
4.1 启动失败 / MCP 端口冲突
常见的第一个坑,是配置完 MCP 后,Claude Code 启动时报错说找不到claude-mem命令。这种情况在 macOS 上特别常见,原因是 MCP 服务启动时所用的 shell 环境和你终端里的环境不一致,npx 的路径没被正确找到。
解决思路有两个:一个是给 Claude Code 的 MCP 配置里写绝对路径(用which claude-mem查一下真实路径,然后写进去);另一个是启动命令改用 Node 直接执行 cli.js 文件,绕开环境变量。两种方法我都在用,更推荐第一种,因为更稳定,不会因为 npm 全局目录变更而失效。
第二个坑是端口冲突。claude-mem本地服务默认占用某个端口,如果你的机器上其他服务占用该端口,MCP 握手就会失败。遇到连接重置类错误,先换一个端口试试。好在 MCP 配置里可以指定参数,灵活度很高。
4.2 模型权限与 API Key 问题
刚才提到,记忆提取依赖 Anthropic 模型调用。这里有个非常隐蔽的坑:如果你用的是第三方代理商提供的 API Key,或者企业的安全网关,那么CLAUDE_MEM_MCP_BASE_URL必须手动配置,否则 claude-mem 会把请求发到官方地址,然后收到 401 或 403。
排查方法很简单:打开一个终端,手动执行 claude-mem 的提取任务,观察有没有报 401/403 相关的错误。如果确认是 API Key 或网关的问题,就去设置CLAUDE_MEM_MCP_BASE_URL指向你实际使用的接口地址。
另外提醒一句:如果用的是某个模型的试用账号,最好看看该模型是否支持 memory 相关的 prompt 要求,有时候模型权限不足会导致提取过程静默失败,看起来像是什么都没发生,实际上数据库里一条记录都没新增。
4.3 macOS 网络权限弹窗
这个属于 macOS 用户的特色经历:第一次启动 claude-mem 或者执行 MCP 连接时,系统可能会弹出“是否允许接受传入网络连接”的提示。原因很简单,claude-mem 本地服务要监听端口,macOS Gatekeeper 会拦截。
处理方法:在“系统设置-隐私与安全性-防火墙”里允许 claude-mem 相关进程通过,或者直接在弹窗里点允许。记住要允许的是 node 进程,因为 claude-mem 本身是命令封装,真正监听端口的是它调起的 Node 进程。我第一次就点错了,放了终端放漏了 node,导致服务一直起不来。
4.4 记忆不回填 / 找不到 workspace / 数据膨胀
如果你发现会话结束后记忆库没有新增数据,十有八九是 workspace 没有匹配。特别是你用claude-mem init --workspace my-app生成记忆库后,又在另一个目录启动了 Claude Code,那么 Claude Code 当前的工作目录与 workspace 没有对应关系,claude-mem 不知道该往哪个库写。
官方建议是,在 Claude Code 启动时通过环境变量或 MCP 配置方式把 workspace 名称显式传入。这块查文档时多看几眼。
另一个容易忽略的问题是数据膨胀。跑了几周以后,记忆库里的碎片数据会越来越多,而无用的旧记忆会让检索结果越来越“分心”。我的习惯是:每个月花十分钟用 SQL 清理掉超过三翻仍从未被检索到的事件。有时候记忆不是越多越好,而是越准越好。
还有一个跟 Claude Code 自身相关的坑:如果你平时习惯开着多个会话但不主动结束,claude-mem的自动提取会在“会话结束时”才触发,但它的“会话”概念和 Claude Code 的会话概念有时候对不上。最好养成习惯:一个任务完成就/exit干净地结束会话,让后续的记忆提炼管道完整跑一次。
我把这段时间遇到的所有问题做了一个速查表,方便你遇到类似情况时一眼定位:
| 症状 | 可能原因 | 解决方案 |
|---|---|---|
| MCP 启动失败,提示找不到命令 | npx 路径不在服务 PATH | MCP 配置写绝对路径 |
| 端口占用,服务握手失败 | 本地端口被其他服务占用 | 更换服务端口,重新注册 MCP |
| 401/403 错误 | API Key 无效或网关地址不对 | 检查CLAUDE_MEM_MCP_BASE_URL |
| 会话结束无新记忆 | workspace 不匹配 | 初始化时显式指定 workspace 名 |
| 检索结果跑偏 | 记忆库碎片太多,未清理 | 定期删除长期未命中的事件 |
| macOS 弹窗拦截 | Gatekeeper 防火墙未放行 node | 允许 node 进程接收传入连接 |
5. 我的使用心得与扩展思路
5.1 一个月的真实体验与感受
连续用了三周以后,最直观的感受是:跨会话的“连续性”终于有了。过去把项目从设计和实现拆成多个会话来做,每次切换都要重新描述一遍上下文,这个工具把这一层开销基本消掉了。
举个例子,我维护的一个内部工具库,过去 Claude 每次会把代码风格从零学一遍,反复问“你们这里是用 default export 还是 named export”“测试框架是 vitest 还是 jest”。装了claude-mem之后,这些问题基本不再出现。因为新会话启动时,它自动把记忆库里的偏好注入了。第一次感受到“它真的记住我了”的那一刻,确实有点惊艳。
但也有一个需要适应的点:记忆提取的延迟是滞后的。由于它是在会话结束后才分析并写入,你没法在对话中“实时”看到记忆形成。如果你想在会话进行中主动记录关键想法,请明确让 Claude 调用memory_create工具。Claude Code 现在支持这种指令式写法,比如你可以在聊天里说“把刚才这个决策记下来”,它就会调用记忆工具写入。
5.2 最佳实践组合建议
从我实际使用的经验来看,工具虽好,也要配合使用方法才能发挥最大价值。这里给几组我认为最有用的实践组合:
一是CLAUDE.md+claude-mem双轨并行。CLAUDE.md用来放项目最核心、最稳定的信息(比如项目结构、API 设计规范),claude-mem负责记录动态演进的技术决策和开发偏好。一个管“宪法”,一个管“日记”,两者不冲突,反而互补。
二是在CI 环境中不使用claude-mem 的记忆注入(至少不用自动模式)。因为 CI 里跑的每次任务都是全新的,自动注入历史记忆不仅没必要,甚至可能带来错误的“先验”。把它限制在交互式开发会话里就够了。
三是定期清理索引。这个刚才提到了,记忆库需要维护。日常跑项目的过程中,我建议每周执行一次claude-mem --workspace <name>进入 REPL,花两分钟翻一翻最近记得都是些什么,删除明显错误或没用的条目。这不是洁癖,是为了保证检索信噪比。
5.3 后续扩展方向
关于claude-mem的后续扩展,我最近在关注两个方向。
一是把它的存储层从 SQLite 扩展到更“重型”的系统。虽然我们个人项目用 SQLite 完全够,但如果你带团队,希望多人共享同一份项目记忆,那么开发一个服务端同步能力会很有用。官方项目目前是单机模式,团队场景下要么靠同步文件夹,要么自己包一层服务。
二是和 IDE 的联动。现在记忆是在 CLI 会话里工作,但很多人也会在编辑器里用 Claude 插件。如果 claude-mem 能做到 IDE 内自动注入记忆,打通终端和 IDE 两套工作流,使用体验会完整得多。
最后分享一个我目前用得最顺的个性化设置,也算压箱底的小技巧:用 prompt 的方式让 Claude 每次做关键决策前先“翻记忆”。我会在CLAUDE.md里加一句:
在给出技术方案或修改建议之前,先检查记忆库中是否有相关历史决策;如有冲突,需明确指出差异点。
配合claude-mem的记忆检索工具,这句 prompt 能极大减少“旧坑新踩”的概率。个人实测下来,它比单纯安装工具本身带来的体验提升更明显。说到底,工具只是一个存储与检索通道,真正让它产生价值的,是你怎么定义“记什么、什么时候想起它”。这个工具已经把通道铺好了,接下来就是靠使用习惯把数据养起来。如果你也正在用 Claude Code 跑真实项目,值得花半小时把claude-mem搭起来,坚持用一周再回头看,大概率你会和我一样觉得:这东西,早该装了。