你有没有遇到过这种情况:上午刚和一个 AI 助手把项目技术方案聊清楚,下午换了个新会话,它连你选的数据库是什么都忘了,甚至把你的称呼从“老王”变回“用户”。我之前的做法很原始——每次开新会话前,把“人名、项目背景、技术栈、代码风格偏好”复制粘贴一遍,像给远方亲戚写家书。直到我接触到 claude-mem 这个工具,才算把这件事从“手动复制粘贴”变成了“自动沉淀和注入”。
这篇文章不是官方文档翻译,是我自己把 claude-mem 用在真实项目里之后,整理出来的经验帖。我会讲清楚它解决什么问题、内部是怎么运作的、安装配置的关键步骤,以及我在实际使用中踩过的坑和调整思路。无论你是重度使用 Claude Code 的开发者,还是想在普通 API 调用里给模型加一层长期记忆,这篇文章应该都能给你一个可以直接落地的参考。
1. “上下文窗口不是记忆”:我为什么需要 claude-mem 而不是继续堆 Prompt
只要用过 Claude 这类大模型,你肯定体会过同一个尴尬:单次会话里它表现得像个对你知根知底的老搭档,可一旦会话过期、上下文被清空,它就翻脸不认人。这不是模型笨,是架构决定的——模型只能在给定的上下文窗口内“看到”信息,窗口之外的内容对它来说等于不存在。
很多人会用“把背景写进系统提示词”来对付这个问题。我也这么干过,但时间一长你会发现几件事:
- 背景材料越写越长,从最开始的三五行,涨到后面几十行,占用大量 token;
- 你更新了技术方案,但忘了同步更新提示词里的旧描述,模型拿着过时信息给你出主意;
- 背景是写好了,但里面真正对当前任务有用的可能就两三句,其他全是噪音;
- 换一个项目就要重新写一套,维护成本堪比写文档。
我真正意识到“靠人维护提示词不可持续”,是有一次做重构时,需要让 Claude 基于之前的对话历史给出建议。我从 Claude Code 的会话日志里翻了半天,才发现信息分散在几十轮对话里,自己整理都要花半小时,更不可能每次手动塞给模型。于是我去查社区里有没有现成方案,找到了 claude-mem。
claude-mem 的思路和我手动维护提示词完全不同:既然模型记不住,那我们就让一个工具把历史对话“消化”成一条条精炼的记忆条目,存到本地,下次开新会话时自动把这些记忆拼回提示词里。相当于给模型配了一个外置硬盘,读写都有人代劳。
从实际效果看,这个工具解决的三个问题正是我在意的:
- 人事实不再丢失:不管换多少次会话,它都知道我的称呼、职业、公司、常用语言;
- 项目约定能够延续:技术选型、目录结构、代码风格这些约定,在对话里提过一次,后续就会一直带着;
- 上下文可以被压缩:几百轮对话被提炼成几十条短记忆,注入成本远低于粘贴原始记录。
如果你和我一样,觉得“每次都要重新讲背景”已经成了使用 AI 的瓶颈,那 claude-mem 这套思路是值得认真研究的。
2. claude-mem 到底怎么工作:扫描、提取、存储、注入四段式
我不喜欢用一堆抽象概念介绍工具,直接说它做的事情:它是一个命令行工具,负责把 AI 会话记录变成结构化记忆,并在需要的时候把记忆交还给模型。整个过程可以拆成四段,理解这四段之后,后面用起来就会顺手很多。
2.1 扫描:先有原料,才能提炼
claude-mem 的第一步是找到对话记录。如果你在用 Claude Code,本地会有一堆 JSONL 格式的会话日志,里面记录了每一轮 user/assistant 的消息、工具调用结果、时间戳等。claude-mem 会去读这些日志,从中提取可供分析的消息对。
除了 Claude Code 自己的日志,它也能处理从对话页面导出的记录,以及部分兼容格式的历史文件。这一步对用户来说基本无感,运行一个扫描命令,工具会自动遍历目录里的文件,找出还没处理过的会话。
提示:扫描的目录如果很大(比如积累了几个月的历史),第一次会稍微慢一点。我建议第一次只扫最近一周的数据,确认流程没问题之后再扩大范围。
2.2 提取:让语言模型当“记忆提炼师”
拿到对话记录之后,claude-mem 不会把原文存下来(那等于没压缩),而是调用一个语言模型,按预设的提示词从对话中抽取“值得长期记住的东西”。比如,如果对话里出现了“用户偏好使用 TypeScript strict 模式”,提取器就会把它整理成一条记忆:“技术偏好: 使用 TypeScript strict 模式”。
这个环节是整个工具的核心。它本质上是一个信息抽取任务,提示词质量直接决定了记忆条目的好坏。我用的提取提示词大概长这样:
你是一个记忆提取器。给定一段 AI 助手与人之间的对话,提取出以下类型的长期记忆: 1. 关于用户的事实(姓名、职业、所在城市等) 2. 用户的偏好(风格、工具、流程偏好等) 3. 项目上下文(技术选型、目录结构、业务背景等) 4. 已做出的决定(例如“确定使用 PostgreSQL 作为主数据库”) 5. 用户的常用表达习惯(例如“喜欢简短回复”) 要求: - 每条记忆必须是独立的一句话,主体明确; - 不要提取一次性临时信息,如“今天天气不错”; - 如果同一事实出现多次,只保留信息最完整的那次; - 输出格式为 JSON 数组。把这一段和对话片段一起发给模型,拿回来的就是结构化的记忆条目。这里有个很容易被忽略的点:提取用的模型不需要和主对话模型一样强,用便宜快速的模型就够了,毕竟它的任务单一,上下文也短,没必要烧钱用顶配模型。
2.3 存储:本地 SQLite 是记忆的家
抽取出来的记忆不会上传到任何云端,而是落在本地存储里。默认情况下 claude-mem 使用 SQLite 数据库,每一条记忆都有类型、内容、首次出现时间、最后出现时间、出现次数、来源会话 ID 等字段。
我用下来觉得这个设计很关键,因为 SQLite 让记忆好查询、好去重、好统计。你可以随时打开数据库看看模型都记住了什么,也能删掉某条明显错误的记忆。如果你不喜欢 SQLite,也可以导出成 Markdown 或 JSON,方便做备份或者在别的工具里复用。
2.4 注入:在模型“失忆”之前把记忆塞回上下文
扫描和提取是后台动作,真正让模型“记住”你的,是注入这一步。当一个新的会话开始时,claude-mem 会从数据库里取出与当前项目相关的记忆,拼接成一段“记忆上下文”,作为会话的第一条系统约定发给你接下来要用的模型。
注入的位置很讲究。如果放在系统提示词里,模型会把它当成可信背景,引用时会比较自然;如果放在用户消息里,模型虽然也会读到,但有时会误解为普通对话内容。claude-mem 默认走系统提示词方向,这个选择我实际对比下来是更稳的。
四段式流程合在一起,效果就是:每次开新会话,模型不再“从零认识你”,而是带着过去所有对话的精华正式进入工作状态。
3. 安装和上手:从零开始把 claude-mem 跑起来
下面这部分是我实际操作的记录。我会直接给命令,同时解释每个命令背后的目的,方便你按需调整。
3.1 安装依赖和工具本体
claude-mem 需要 Python 3.10 以上环境。如果你平时用 pyenv 或 conda 管理 Python,建议先建一个干净的虚拟环境,免得和系统 Python 打架。
# 进入项目目录,创建虚拟环境 python -m venv .claude-mem-venv source .claude-mem-venv/bin/activate # 安装 claude-mem pip install claude-mem安装完成之后可以先确认版本:
claude-mem --version如果正常打印出版本号,说明工具本体已经就位。接着要配置 API 密钥,因为提取步骤需要调用语言模型。你可以用环境变量,也可以在配置文件里写:
export ANTHROPIC_API_KEY="sk-ant-..."注意:密钥只会被用来调用提取模型,不会被写入记忆数据库。这个我确认过,但如果你更谨慎,可以用一个单独的 API key,方便权限控制和用量追踪。
3.2 首次扫描:让工具认识你的历史
安装配置好之后,第一次运行扫描。我先指定了 Claude Code 的日志目录:
claude-mem scan --source ~/.claude/projects --since 7d--since 7d表示只处理最近七天的会话。第一次跑的时候可以盯着输出,它会显示正在处理哪个文件、提取到了多少条记忆。我当时的第一次扫描结果大概是 30 多个会话文件,耗时约两分钟,产生了 40 多条记忆,其中不少是重复内容,去重后剩下 23 条。
扫描完之后,可以用一条命令查看现有的记忆库:
claude-mem list --limit 20这时候你会看见类似这样的记忆条目:
[1] user_fact: 用户称呼自己为“老周”,是一名后端工程师 [2] tech_stack: 主技术栈为 Python 3.12 + FastAPI [3] preference: 代码里倾向使用显式类型注解,不使用动态类型省略 [4] project_context: 当前项目是订单服务,数据库采用 PostgreSQL第一次看到这个列表的时候,我其实挺震撼的——它真的把散落在上百轮对话里的信息捞出来了。
3.3 起一个新会话并验证记忆是否生效
扫描完成后,启动一个带记忆的新会话:
claude-mem use --session-id orders-service这个命令会启动一个交互式会话,并且在会话开头自动注入记忆。验证方式很简单,直接问模型:“我叫什么名字?我们这个项目用的是什么数据库?我偏好什么代码风格?”
如果记忆注入成功,模型会流利地回答出来。如果答不上来,大概率是注入环节出了问题。我遇到过一种情况:模型回答时把记忆里的信息说错了,后来排查发现是因为记忆条目本身有歧义,比如同时存在两条“数据库是 PostgreSQL”和“数据库是 MySQL”,模型就困惑了。这个问题等在“踩坑”部分详细说。
3.4 把记忆库导出备份
记忆是资产,万一数据库坏了就麻烦了。我每隔一段时间会导出一份 Markdown 到网盘或私有仓库:
claude-mem export --format markdown > memory_backup.md导出的文件结构很清晰,按记忆类型分组,阅读和二次处理都比较方便。
4. 配置项与实际取舍:记忆分类、去重和隐私边界
既然是自用工具,那配置就得按自己的需求来调。我不太建议“装完默认用到底”,因为默认配置是为通用场景设计的,不一定合你的口味。
4.1 记忆分类:不同类型不同对待
我在用的时候会把记忆分成五类,每类的价值和维护方式都不同:
| 记忆类型 | 示例 | 建议处理方式 |
|---|---|---|
| user_fact | “用户叫老周,后端工程师” | 长期保留,错误时手动更正 |
| preference | “偏好使用类型注解” | 长期保留,模型引用率很高 |
| project_context | “项目是订单服务” | 项目结束可删除或归档 |
| tech_stack | “使用 PostgreSQL” | 跟随项目变化,变更时更新 |
| decision | “确定用队列异步处理邮件” | 时效性强,过时后应该清理 |
配置里可以针对不同类型设置开关。比如对我个人来说,“用户称呼”这种事实比“某次具体决定”更重要,所以我让工具在提取时更积极地抓 user_fact 和 preference,对 decision 则要求必须出现“决定”“确定”“方案”这种强信号词才提取。
这个调整本质上是改提取提示词。你可以在配置文件中指定自定义提示词,给 claude-mem 喂一版更符合你场景的模板。我改完之后最明显的感受是:记忆库里的噪音少了很多,不再出现“用户今天问了某个函数用法”这种一次性内容。
4.2 去重与冲突处理:记忆库的“卫生”问题
默认去重靠的是文本相似度。同一事实如果表达不同,比如“用 PostgreSQL”和“数据库是 PostgreSQL”,会被识别为高相似度并在一定程度上合并。但这是启发式方法,不是完美的。
真正麻烦的是冲突。比如上个月对话里说“数据库用 MySQL”,这月又说“迁移到 PostgreSQL 了”,如果两条记忆并存,模型就不知道哪个是对的。claude-mem 采取的办法是让用户确认:遇到可能冲突的新记忆时,会把新旧两条一起列出来,让你手动挑选或合并。
我一开始觉得这个确认流程烦,后来发现它能救命——尤其项目发生技术栈迁移时,不清理旧记忆,模型会一直在“MySQL 还是 PostgreSQL”之间摇摆。现在我养成的习惯是:每次重大技术决策之后,跑一次冲突检查命令,主动清理旧记忆。
4.3 隐私边界:本地存储不等于没有风险
claude-mem 把记忆存在本地,这比起云端方案确实好很多。但它读取的原始会话日志本身可能包含敏感内容,所以请务必注意几点:
- 不要在有严格数据合规要求的机器上扫描工作相关会话;
- 记忆库文件虽然本地存,但如果你备份到公共仓库,等于变相泄露;
- 如果多人共用一台电脑,建议给记忆数据库单独设置访问权限。
另外,扫描之后工具会保留原始对话的索引位置,但没有把原文复制进记忆库。这一点我验证过:导出的 Markdown 里只有提炼后的条目,没有成段的原始对话。即便如此,只要你有备份记忆的习惯,那备份文件本身就是敏感资产,要像对待密码本一样对待它。
5. 我踩过的坑:上下文膨胀、记忆污染和成本失控
工具用顺手之后,我把 claude-mem 接进了日常开发流程,连续高强度用了一个多月。这段时间里踩了不少坑,挑三个最典型的分享,希望你能绕开。
5.1 记忆过多导致注意力被稀释
记忆不是越多越好。有一阵子我的记忆库积累了 200 多条条目,注入的时候全塞进系统提示词,结果模型反而开始“迷失重点”:让它做代码审查,它却大谈特谈我上个月聊过的项目规划,因为那条记忆恰好和当前任务沾了点边。
后来我把注入机制改成了“按项目过滤”——只有和当前会话项目标签匹配的记忆才会被注入。这个改动立竿见影。如果你也遇到类似问题,优先去看注入前有没有做项目维度的筛选,而不是一味删记忆。
5.2 错误记忆一旦沉淀,会反复污染后续对话
记忆库里有条错误记录:“用户使用 VS Code 编辑器”。其实我只在某个旧项目里用过,后来早就切到 Neovim 了。那条错误记忆被反复注入之后,模型每次给我生成配置建议都以 VS Code 为前提,纠正了好几次才改过来。
这事给我两个教训:第一,导入大量历史时会因为上下文不足出现“一本正经编造”的记忆,所以第一次扫描后一定要人工过一遍列表;第二,给记忆加上“置信度”或者“最后确认时间”很有必要。claude-mem 里边有类似的字段,但默认不会主动标注,需要你养成定期 review 的习惯。
5.3 高频扫描的成本比我预想的高
提取环节每次都要调用模型接口,而且是整段对话喂进去,token 消耗并不低。我第一次把扫描周期从“每周”改成“每天”之后,月底看账单吓一跳,提取消耗比主对话还高。
优化方案有两个:一是把扫描频率降下来,改成只在会话结束或项目里程碑节点触发;二是用更便宜的模型做提取。如果你的主模型是旗舰款,提取模型完全可以换成低一档的,效果几乎没差别,成本能降一个数量级。
6. 把 claude-mem 接到自己的工作流里:从 Claude Code 到普通 API
claude-mem 最有价值的地方,不只是它自带命令,而是它可以被嵌入到不同工作流中。我自己现在有三套用法,分享给你作为扩展思路。
6.1 配合 Claude Code 的会话启动钩子
如果你用 Claude Code,可以在会话启动时自动执行记忆注入。方法是在项目的配置里加一个会话启动命令,让每次进入项目都自动跑一次记忆列表加载。具体形式各版本略有差异,但核心思路是:session 开始时读取该项目的记忆文件,作为上下文给到模型。
我目前的效果是:进入项目目录、启动会话,模型已经知道当前项目的技术栈和进行到哪一步,省掉了每次浪费十分钟重新讲述背景的环节。
6.2 封装一个带记忆的 API 客户端
不依赖交互式会话的话,可以写个小脚本,动态读取记忆库并拼进 API 请求里。我写过一个很简陋的 Python 客户端,逻辑很简单:
import subprocess import json def build_context(project_key): # 读取 claude-mem 导出的记忆 output = subprocess.check_output( ["claude-mem", "list", "--project", project_key, "--format", "json"] ) memories = json.loads(output) context = "以下是关于用户和项目的长期记忆:\n" for m in memories: context += f"- {m['type']}: {m['content']}\n" return context然后把build_context(project_key)的结果拼到每次调用的 system prompt 里。这样不管是写自动化脚本还是做原型工具,都能让模型“想起来”你之前说过的话。
6.3 定期清理遗忘:记忆也要“断舍离”
我最后加了一个每周清理流程。检查三件事:有没有失效的 tech_stack 和 decision;有没有重复的记忆可以用一句话合并;有没有超过两个月没出现、且不再相关的事实,该归档就归档。
这一步不是 claude-mem 自动完成的,而是我用它的查询接口配合一个简单的脚本做的。效果是记忆库长期保持精简,注入成本低,模型注意力也更集中。
最后再分享一个经验:无论用哪种方式接入长期记忆,都不要完全相信工具的自动提取结果。记忆是一个需要维护的资产,它的价值取决于内容质量,而质量只有在你定期审视和修正的时候才能保证。claude-mem 给了一套很好的基础设施,但真正让模型“懂你”的,还是你那几次谨慎的手动把关。