☰
claude-mem:为Claude打造本地持久化记忆系统,告别重复上下文
2026/10/28 16:17:32 网站建设 项目流程

1. 项目缘起与核心定位

第一次看到claude-mem这个名字,我的直觉是:这大概率是一个围绕 Claude 生态做“记忆层”的项目。事实也确实如此。它要解决的核心问题非常明确——让 Claude 在跨会话、跨任务、跨项目的场景下,拥有可持久化、可检索、可复用的记忆能力。

如果你用过 Claude 的 Projects 功能,或者用过 Claude Code 做长期开发,你一定会遇到一个非常现实的痛点:每次开新对话,它就像失忆一样,之前聊过的架构决策、命名约定、踩过的坑、项目背景,全都要重新讲一遍。短对话还好,一旦项目周期拉长到几周甚至几个月,这种“重复交代上下文”的成本会高到让人崩溃。claude-mem就是冲着这个痛点来的。

它的基本形态是一个本地优先的记忆管理系统,通常以 MCP Server 的形式挂载到 Claude 客户端上,通过工具调用的方式让 Claude 主动写入和读取记忆。记忆以结构化的 Markdown 或 JSON 文件存储在本地目录中,按项目、按主题、按时间维度组织。Claude 在需要的时候可以搜索历史记忆,也可以把当前对话中值得留存的信息写进去。

适合谁来参考?三类人最值得看:一是长期用 Claude 做开发的人,尤其是用 Claude Code 维护多个项目的工程师;二是做 AI Agent 应用的人,想给自己的 Agent 加一层记忆机制;三是对 MCP 协议感兴趣的人,claude-mem是一个非常好的 MCP 实战样本,代码量不大,但把工具注册、参数校验、文件读写、检索逻辑都串起来了。

我自己的使用场景是:同时维护三个中型项目,每个项目都有自己的技术栈约定、目录结构规范、历史决策记录。以前每次切换项目都要重新给 Claude 喂一遍背景,现在这些全部沉淀在claude-mem里,新会话开场只需要一句“读一下项目记忆”,Claude 就能把关键上下文捞回来。这个体验的提升是质变级别的。

2. 记忆系统的整体设计与思路拆解

2.1 为什么不做成向量数据库方案

很多人一提到“记忆”,第一反应就是上向量数据库,做 embedding 检索。但claude-mem走的是另一条路——基于文件系统的结构化存储 + 关键词检索。这个选择乍看有点“土”,但仔细想过之后,我认为它在 Claude 这个场景下是更合理的。

原因有三。第一,Claude 的上下文窗口足够大。Claude 3.5 之后,200K 上下文是标配,这意味着你不需要靠向量检索去“精准命中”那几条记忆,你完全可以把一个项目的记忆文件整体读进来。向量检索的优势在于从海量数据里捞针,但个人项目的记忆量通常也就几十KB到几百KB,根本用不上向量。

第二,结构化存储可读可编辑。记忆存成 Markdown,你随时可以用编辑器打开看、手动改、手动删。向量数据库里的东西你基本没法直接干预,出了问题只能重新 embedding。而claude-mem的记忆文件,你打开就能看懂,改起来也放心。

第三,零外部依赖。不需要跑一个向量数据库服务,不需要调 embedding API,不需要管理索引。整个系统就是一堆文件加一个 MCP Server,部署成本几乎为零。对于个人开发者和小团队来说,这个优势太大了。

提示:如果你的记忆量真的到了几万条以上,或者需要跨大量文档做语义检索,那确实应该考虑向量方案。但在个人项目这个量级,文件方案是性价比最高的选择。

2.2 记忆的分层结构

claude-mem的记忆不是一锅粥,它做了分层。我梳理下来,大致是这么几个维度:

  • 项目级记忆:跟某个具体项目绑定的信息,比如技术栈、目录约定、部署方式、历史决策。这类记忆的生命周期跟项目一致。
  • 主题级记忆:跨项目的通用知识,比如“我习惯用 pnpm 而不是 npm”“我的代码风格偏好”“常用的调试命令”。这类记忆在所有项目间共享。
  • 会话级记忆:某次对话中产生的临时结论,可能过几天就没用了,但短期内需要保留。
  • 归档记忆:已经过时但不想删的历史记录,留作追溯用。

这种分层的好处是检索时可以按范围过滤。你在项目 A 里工作时,只需要加载项目 A 的记忆加上通用主题记忆,不需要把项目 B、C 的记忆也拉进来,避免上下文污染。

2.3 写入时机的设计考量

记忆系统最难的不是存,而是决定什么时候存。存太多,噪音大,检索出来的都是垃圾;存太少,关键信息漏掉,等于没存。

claude-mem的做法是让 Claude 自己判断。它提供给 Claude 一个memory_write工具,Claude 在对话过程中如果觉得某条信息值得留存,就主动调用写入。同时还有一个memory_search工具用于读取。

这个设计把判断权交给了模型本身。好处是灵活,Claude 能根据上下文判断什么重要;坏处是可能不稳定,有时候该存的不存,不该存的乱存。我的经验是,在系统提示词里明确告诉 Claude 什么该存什么不该存,效果会好很多。比如我会写:“当用户明确表达偏好、做出架构决策、或者纠正了你的错误认知时,调用 memory_write 记录。”

2.4 与 Claude Code 的集成方式

claude-mem最常见的用法是作为 MCP Server 挂到 Claude Code 上。配置方式是在 Claude Code 的 MCP 配置文件里加一段:

{ "mcpServers": { "claude-mem": { "command": "node", "args": ["/path/to/claude-mem/dist/index.js"], "env": { "MEMORY_DIR": "/Users/yourname/.claude-mem" } } } }

挂载之后,Claude Code 在会话中就能看到memory_write和memory_search这两个工具。你可以在 CLAUDE.md 里加一句“每次开始新任务前,先搜索相关记忆”,这样 Claude 就会养成先查记忆的习惯。

3. 核心细节解析与实操要点

3.1 记忆文件的目录结构

理解目录结构是玩转claude-mem的基础。默认情况下,记忆根目录下会按这样的结构组织:

~/.claude-mem/ ├── projects/ │ ├── project-a/ │ │ ├── decisions.md │ │ ├── conventions.md │ │ └── issues.md │ └── project-b/ │ └── ... ├── topics/ │ ├── preferences.md │ ├── tools.md │ └── workflows.md ├── sessions/ │ └── 2024-01-15-abc123.md └── archive/ └── ...

projects/下按项目名分目录,每个项目里再按记忆类型分文件。topics/放跨项目的通用知识。sessions/放会话级临时记忆。archive/放归档。

这个结构不是强制的,你可以根据自己的习惯调整。但我的建议是保持项目维度的隔离,因为项目之间的上下文污染是记忆系统最大的坑。你肯定不希望项目 A 的架构决策被误用到项目 B 上。

3.2 记忆条目的格式规范

每条记忆的格式直接决定了检索效果。claude-mem默认用的是带元信息的 Markdown 条目,大致长这样:

## 使用 pnpm 作为包管理器 - **类型**: 偏好 - **项目**: project-a - **时间**: 2024-01-15 - **标签**: 工具链, 包管理 项目 A 统一使用 pnpm,不用 npm 或 yarn。原因是 pnpm 的硬链接机制在 monorepo 场景下节省大量磁盘空间,且依赖提升行为更可预测。

这里有几个关键点。标题要具体,不要写“包管理器偏好”这种模糊的,要写“使用 pnpm 作为包管理器”,这样关键词检索时命中率更高。标签要覆盖同义词,比如你写“包管理”,那搜索“依赖管理”就搜不到,所以标签里最好把常见说法都列上。正文要写清楚原因,因为 Claude 读到这条记忆时,不只是要知道“用什么”,还要知道“为什么”,这样它在新场景下才能做出合理判断。

3.3 检索机制的实现细节

claude-mem的检索是关键词匹配 + 范围过滤。当你调用memory_search时,可以传几个参数:

  • query:搜索关键词,支持多个词,默认是 OR 关系
  • project:限定项目范围
  • tags:按标签过滤
  • limit:返回条数上限

检索逻辑大致是:先按 project 和 tags 做粗筛,然后在候选集里做关键词匹配,匹配时对标题的权重高于正文,对标签的权重又高于标题。最后按相关度排序返回。

这个机制简单但有效。实测下来,只要你的记忆条目标题写得够具体、标签打得够全,检索命中率能到 90% 以上。真正的问题往往出在写入端——Claude 写记忆时标题写得太泛,导致后面搜不到。

注意:如果你的查询词和记忆里的用词不一致,比如你搜“状态管理”但记忆里写的是“store 方案”,那就搜不到。解决办法是在写入时把同义词都塞进标签里,或者在系统提示词里要求 Claude 写入时考虑未来可能的检索词。

3.4 记忆的更新与去重

记忆系统用久了必然遇到重复和过时的问题。claude-mem的处理策略是允许覆盖 + 定期归档。

当 Claude 写入一条新记忆时,它会先搜索是否有相似条目。如果有,可以选择更新原条目而不是新增。这个判断也是交给 Claude 做的。我的经验是,在系统提示词里明确要求:“写入前先搜索是否已有相关记忆,如果有则更新,没有才新增。”

对于过时记忆,不要直接删,而是移到archive/目录。因为有时候你需要追溯“为什么当初做了这个决策”,归档记忆能帮你还原历史。归档记忆默认不参与检索,但可以手动指定搜索归档。

4. 实操过程与核心环节实现

4.1 从零搭建 claude-mem 的完整步骤

假设你从零开始,下面是完整的搭建流程。我用的是 Node.js 环境,版本要求 18 以上。

第一步,克隆仓库并安装依赖:

git clone https://github.com/yourname/claude-mem.git cd claude-mem npm install

第二步,构建项目:

npm run build

构建产物在dist/目录下,入口是dist/index.js。

第三步,创建记忆根目录:

mkdir -p ~/.claude-mem/{projects,topics,sessions,archive}

第四步,配置 Claude Code 的 MCP。找到 Claude Code 的配置文件,通常在~/.claude/claude_desktop_config.json或者项目级的.mcp.json,加入:

{ "mcpServers": { "claude-mem": { "command": "node", "args": ["/absolute/path/to/claude-mem/dist/index.js"], "env": { "MEMORY_DIR": "/Users/yourname/.claude-mem", "DEFAULT_PROJECT": "default" } } } }

第五步,重启 Claude Code,在会话里输入“列出可用的 MCP 工具”,如果能看到memory_write和memory_search,说明挂载成功。

4.2 初始化项目记忆的实操

挂载成功后,第一件事是给当前项目建立记忆基线。我会在 Claude Code 里这样操作:

先让 Claude 读一遍项目结构:

请阅读当前项目的目录结构、package.json、README,然后总结出这个项目的技术栈、目录约定、构建命令,写入项目记忆。

Claude 会调用memory_write,把总结写进projects/<项目名>/conventions.md。这一步相当于给项目建立了一个“档案”,后续新会话开场读一下这个档案,就能快速恢复上下文。

然后我会手动补充一些 Claude 看不出来的信息,比如:

请记录以下决策:项目使用 Zustand 而不是 Redux,原因是团队规模小,Zustand 的样板代码更少,且不需要 middleware 生态。标签加上:状态管理、store、zustand、redux。

注意我在最后特意加了标签,把“状态管理”“store”这些同义词都列上,这样以后无论用哪个词搜都能命中。

4.3 日常使用中的记忆读写节奏

日常使用中,我形成了几个固定习惯。

开场读记忆。每次新会话开始,第一句就是“搜索项目记忆,关键词:当前任务相关”。比如今天要改认证模块,就搜“认证 auth 登录”。Claude 会把相关记忆捞出来,我确认无误后再开始干活。

决策时写记忆。每当做出一个架构决策、确定一个命名约定、或者踩了一个坑并找到解法,立刻让 Claude 记录。比如:“记录:项目 A 的 API 路由统一用 kebab-case,不用 camelCase,原因是跟后端约定保持一致。标签:命名规范、路由、api。”

收尾时归档。一个任务完成后,让 Claude 检查本次会话产生的记忆,把临时性的、已经过时的移到 archive。比如:“把 sessions 里关于这次调试的记忆归档,保留结论性的条目。”

4.4 参数配置与调优

claude-mem有几个环境变量可以调:

变量名默认值说明
MEMORY_DIR~/.claude-mem记忆根目录
DEFAULT_PROJECTdefault未指定项目时的默认项目名
MAX_SEARCH_RESULTS10单次搜索返回条数上限
SEARCH_TITLE_WEIGHT3标题匹配权重
SEARCH_TAG_WEIGHT2标签匹配权重
SEARCH_BODY_WEIGHT1正文匹配权重

权重参数决定了检索排序。默认配置下,标题命中权重是正文的 3 倍,这个设置我认为是合理的。如果你发现搜索结果里正文匹配的噪音太多,可以把SEARCH_BODY_WEIGHT调到 0.5。

MAX_SEARCH_RESULTS默认 10 条,我建议保持这个值。返回太多会占用上下文,返回太少可能漏掉关键信息。10 条是个平衡点。

5. 常见问题与排查技巧实录

5.1 记忆写入失败或丢失

最常见的问题是 Claude 该写记忆的时候没写。排查思路是:先确认 MCP 工具是否正常挂载,在会话里直接问“你能看到 memory_write 工具吗”。如果看不到,检查 MCP 配置和 Claude Code 日志。

如果工具正常但 Claude 不主动写,那就是提示词的问题。在 CLAUDE.md 里加一段明确的指令:

## 记忆管理规则 - 当用户表达偏好、做出决策、纠正错误时,必须调用 memory_write - 写入前先调用 memory_search 检查是否已有相关记忆 - 记忆标题必须具体,包含关键名词 - 标签必须覆盖同义词

实测下来,加了这段指令后,Claude 的写入主动性会明显提升。

5.2 检索结果不相关

检索不相关通常是两个原因:要么记忆条目标题太泛,要么查询词和记忆用词不一致。

排查方法:手动打开记忆文件,看看相关条目的标题和标签是什么。如果标题写的是“项目配置”,那搜“构建命令”肯定搜不到。解决办法是手动编辑记忆文件,把标题改具体,把标签补全。

另一个技巧是在查询时用多个同义词。比如搜“包管理”时,同时搜“pnpm npm 依赖”,用空格分隔多个词,OR 关系会扩大命中范围。

5.3 记忆文件冲突或损坏

如果你在多台机器上同步记忆目录,可能会遇到文件冲突。claude-mem本身不做冲突解决,它假设单机使用。如果你需要多机同步,建议用 Git 管理记忆目录,每次同步前先 pull,冲突时手动合并。

记忆文件损坏的情况很少见,但如果发生了,通常是 JSON 格式的记忆文件解析失败。检查文件是否是合法 JSON,Markdown 文件一般不会损坏。

5.4 上下文污染问题

这是记忆系统最隐蔽的坑。当你搜索记忆时,如果范围没限定好,可能会把其他项目的记忆拉进来,导致 Claude 用错误的上下文做判断。

避免方法:搜索时始终指定 project 参数。在系统提示词里要求 Claude 搜索时带上当前项目名。另外,通用主题记忆要严格审核,只放真正跨项目通用的内容,不要把项目特定的东西塞进 topics。

5.5 常见问题速查表

问题现象可能原因解决方法
Claude 不写记忆提示词未明确要求在 CLAUDE.md 加写入规则
搜索无结果标题太泛或标签缺失手动编辑记忆文件补全
搜索结果不相关查询词与记忆用词不一致用多同义词查询
记忆文件冲突多机同步未处理冲突用 Git 管理并手动合并
上下文污染搜索未限定项目范围搜索时指定 project 参数
MCP 工具不可见配置错误或未重启检查配置并重启 Claude Code

5.6 我踩过的几个坑

第一个坑是记忆写得太细。一开始我让 Claude 把每次对话的结论都记下来,结果记忆文件迅速膨胀到几百条,检索出来的全是噪音。后来我改成只记“决策性”和“偏好性”的内容,日常讨论不记,信噪比立刻上来了。

第二个坑是标签用中文还是英文。我一开始混着用,结果搜“auth”搜不到标了“认证”的条目。后来统一规定:标签中英文都打,比如认证, auth, 登录, login。这样无论用哪种语言搜都能命中。

第三个坑是忘记归档。过时记忆不归档,会一直参与检索,导致 Claude 拿到旧信息。现在我每周花五分钟让 Claude 检查一遍记忆,把过时的移到 archive。

6. 记忆系统的扩展玩法

6.1 与 Git 结合做记忆版本管理

把~/.claude-mem目录用 Git 管理起来,每次记忆变更都 commit。这样做的好处是:可以追溯记忆的演变历史,可以看到某个决策是什么时候做的、后来有没有改过。出问题时也能回滚到之前的版本。

我的做法是写一个定时脚本,每天自动 commit 一次:

#!/bin/bash cd ~/.claude-mem git add -A git commit -m "auto: $(date +%Y-%m-%d)" || true

配合 cron 每天跑一次,记忆的版本历史就自动维护起来了。

6.2 多项目记忆的共享与隔离

如果你有多个项目共享一些通用约定,可以把这些约定放在topics/下,所有项目都能搜到。但项目特定的内容必须放在projects/<项目名>/下,严格隔离。

一个实用技巧是:在topics/下建一个global-preferences.md,放你的通用编码偏好、常用命令、工具链选择。这样新项目初始化时,Claude 读一下这个文件就能了解你的整体风格,不用每个项目重复交代。

6.3 记忆的定期清理策略

记忆不是越多越好。我建议每个月做一次清理,流程是:

  1. 让 Claude 列出所有记忆条目,按最后访问时间排序
  2. 超过三个月没被检索过的条目,检查是否还有价值
  3. 没价值的移到 archive,有价值的更新一下时间戳
  4. 合并重复条目,删除矛盾条目

这个清理过程大概花十分钟,但能让记忆库保持精简高效。我试过不清理,三个月后检索命中率明显下降,清理之后又恢复了。

6.4 给 Agent 应用开发者的启示

如果你在做自己的 AI Agent,claude-mem的设计思路很值得借鉴。核心就三点:文件存储降低依赖、结构化格式保证可读、模型自主判断写入时机。这三点在个人项目和小团队场景下,比向量数据库方案更实用。

你可以把这套思路移植到自己的 Agent 里:用 Markdown 存记忆,用关键词检索,用系统提示词引导模型读写。代码量不大,但效果立竿见影。

我个人在实际操作中的体会是,记忆系统的价值不在于技术多复杂,而在于坚持用。再好的记忆机制,如果你不养成读写习惯,也发挥不出作用。我现在的习惯是:每天开工第一件事读记忆,收工最后一件事写记忆。这个习惯坚持了两个月,Claude 已经成了我真正意义上的“长期协作伙伴”,而不是每次都要重新介绍的陌生人。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询