☰
Claude Code跨会话记忆实战:用claude-mem实现AI编程助手长期记忆
2026/10/7 4:24:43 网站建设 项目流程

我先说一个我特别有感触的场景:你和 Claude Code 来回磨了一整个下午,把一个老项目里那几个坑人的历史包袱翻了个底朝天,连“为什么当初要这么设计”都能讲出一大段故事了。第二天早上打开终端,接着昨天的思路继续,它却一脸茫然地看着你,问出那句你最不想听到的话:“这个项目的背景是什么?你能给我介绍一下吗?”

那一刻我是崩溃的。模型本身没有变笨,但每次新会话都像重新招了个实习生,你上周教过的所有东西它全忘了。后来我开始用 claude-mem 这个开源工具,把 Claude Code 的跨会话记忆真正补上了,今天就把这套东西的来龙去脉、配置方式和踩坑经验完整写出来。

1. 每个新会话都是“失忆”的:最让我崩溃的三个时刻

1.1 昨天拍板的架构决策,今天要重新吵一遍

做技术的人应该都有这种经历:项目里一个模块到底是走微服务还是继续在单体里拆包,这种决策通常不是一次能聊完的。你得翻历史代码、对比依赖关系、评估团队成员的水平,最后才能得出一个“现阶段不要拆分”的结论。

这个结论只存在昨天那次会话的记录里。今天你新开一个会话,让 Claude 帮忙重构代码,它不知道你昨天已经做过权衡,很可能会一本正经地建议你“拆分出独立的服务”。你如果没坚持住,就带着它往错误方向走了几步,浪费小半天才发现方向不对,还得折回来。

1.2 改到一半的手艺活,上下文像沙子一样流走

写代码这件事特别依赖上下文。比如你在调一个数据同步脚本,关键信息包括:源表有 2000 万行、目标库有唯一键冲突、历史数据里有脏数据需要单独清洗、公司规定晚上 10 点以后才能跑批任务。

这些信息散落在好几轮对话里。窗口还够的时候,Claude 表现得像个高手;一旦上下文被长日志挤掉,它就变回那个“重启过的实习生”,开始问你已经回答过的问题。你要么反复粘贴旧信息,要么被它带到逻辑混乱的沟里去。

1.3 为什么“提示词模板”治标不治本

有人会说:把项目背景写进一个 PROJECT_BACKGROUND.md,每次开新会话就让 Claude 先读一遍不就行了?

这个思路对,但没有完全对。问题在于:项目背景是动态变化的,今天你发现了一个历史 bug 的根因,明天你调整了目录结构,后天你确定了新的接口规范。这些增量信息你很难每次都手动维护进文档。更现实的是,你经常忘了这件事——忘了告诉它,它自然就不知道。

claude-mem 解决的核心问题,就是让“增量记忆”自动化:对话结束后自动归档,新会话开始时自动召回。它不是给模型本身加脑子,而是给每个新会话提前发一张“你曾经知道什么”的提示卡。

2. claude-mem 的完整工作链路:从捕获、压缩到检索注入

2.1 整体架构:捕获、压缩、存储、注入四层

把 claude-mem 想成是一个“贴身秘书”在给你做三件事:速记、归档、发提示卡。它的架构其实很清晰,可以分成四层:

层级对应模块职责
捕获层Hooks / MCP 监听记录会话里的用户输入、助手回复、工具调用结果
处理层压缩与摘要把冗长对话压成结构化短句,控制 token 成本
存储层SQLite + 向量索引保存摘要、原始片段、嵌入向量、时间戳、项目归属
注入层MCP 工具 + 上下文组装新会话启动时检索相关记忆,拼进 messages 前缀

这四层各干各的活,互不阻塞。捕获是实时的,处理通常放后台异步跑,存储只是个数据库读写,注入则发生在每次会话开始的时候。这也是它设计上比较聪明的地方:不让记忆过程拖慢正常对话。

2.2 捕获阶段:怎么把对话变成“可记忆事件”

claude-mem 跟 Claude Code 的集成走的是 Hooks 和 MCP(Model Context Protocol)。简单说,每次你发消息、每次 Claude 回复、每次工具被调用,都会产生一个事件,这些事件就是“可记忆的原始素材”。

但要注意:不是所有对话内容都值得进记忆库。我跟你说“帮我看看这个报错”,这种一句话请求没有太多长期价值;而“这个模块我们决定不再维护,后续迁移到 XXX 服务”,这种结论就值得沉淀。

所以 claude-mem 通常不只靠自动捕获,还提供手动标记机制——在对话里输入类似/remember的指令,把当前讨论的重点显式保存下来。我个人的实操习惯是:在项目大决策、配置改动、名词定义这种关键节点,手动标记一下;平时的小修小补,靠自动摘要兜底就行。

2.3 压缩阶段:用低成本“摘要通道”控制 token

如果每轮对话原文都存进来,那数据库很快就会被淹没,检索时也会浪费大量 token。claude-mem 的默认思路是两级结构:

  • 第一级:原始分片。最近的对话按块保存,保留相对完整的表述。
  • 第二级:会话摘要。会话结束后,用一个更便宜的模型(比如 Haiku 级别的轻量模型)把整个会话压成几百字的摘要,作为长期记忆的主体。

这里最关键的是压缩率的把握。我见过一个极端例子:一次会话来回聊了 3 万 token,最后摘要只有 400 token,压缩率接近 98%。400 token 足够写下“结论是什么”“为什么这么定”“涉及哪些文件”,而那些中间讨论的过程细节,绝大部分是不需要长期记住的。

你可以在配置里设置摘要触发阈值,比如会话 token 超过 8000 才做摘要,低于这个数就直接存原文。这个阈值设太低了会让记忆碎片化,设太高了会浪费存储和 token。我建议从 8000 开始,跑两周再根据实际项目体量调整。

2.4 存储与检索:SQLite 时间线 + 向量语义双通道

claude-mem 默认把记忆存在本地 SQLite 文件里,同时给摘要内容做向量化,以便按“语义相似度”检索。

这就像你有一个笔记本:SQLite 负责按时间翻页(“上周五我记过什么”),向量索引负责按意思找(“我记得之前聊过关于缓存失效的事情”)。两个通道各有用途,实际检索时通常合并打分:

score = 语义相似度 × 时间衰减系数

时间衰减做的是一件很朴素的事:越久远的记忆,自动降权。一个 90 天前的决策,和当前问题的语义相似度就算再高,也不如昨天的对话重要。这个逻辑不复杂,但直接影响记忆质量。后面我会专门讲怎么调这个衰减参数。

3. 从安装到接入 Claude Code:一套完整的配置路径

3.1 安装和初始化

先说明版本前提:claude-mem 是 Python 写的,需要 Python 3.10 以上。我自己用 uv 管理 Python 工具链,安装很干净:

uv tool install claude-mem

如果你习惯 pip,直接装也行:

pip install claude-mem

装完后做初始化:

claude-mem init

这个命令会在用户目录下生成一个配置目录,默认是~/.claude-mem/。里面最关键的是config.toml,所有记忆行为都由它控制。另外可以跑一下自带的自检命令:

claude-mem doctor

它会把配置、数据库连接、MCP 配置这些逐一检查,告诉你哪里没通。我第一次跑的时候,它提示 Python 环境里的路径没对上,换到 uv 管理的环境就好了。小问题,但确实省了不少排查时间。

3.2 config.toml 里的关键字段

配置文件的写法是 TOML,不复杂。我放一份我目前在用的简化配置,然后逐个讲为什么这么设:

[storage] backend = "sqlite" path = "~/.claude-mem/memory.db" max_item_age_days = 90 [compression] enabled = true target_model = "claude-3-5-haiku" max_tokens = 800 summary_threshold_tokens = 8000 [retrieval] top_k = 8 min_similarity = 0.3 time_decay_factor = 0.7 [semantic] enabled = true embedding_model = "text-embedding-3-small" [mcp] name = "claude-mem"

max_item_age_days = 90表示超过 90 天的记忆默认不检索。注意这和“删除”是两码事,它只是让过期记忆退出检索范围,库文件还在。假如你想做季度总结,历史数据仍可以从数据库里捞。

target_model是摘要用的轻量模型,我的是 Haiku 级别。这个不要图省事不设置,否则默认用主模型做摘要,等于每次会话结束还要烧一波不便宜的 token。

top_k = 8是每次新会话最多注入几条记忆。不要贪多,后面我会讲为什么记忆注入不是越多越好。

min_similarity = 0.3是一个经验值。低于这个相似度的记忆会被过滤掉,避免注入一堆“看起来沾边但实际没用”的旧内容。阈值设太高(比如 0.7),你可能会发现什么都检索不到。

3.3 接入 Claude Code 的两种方式

claude-mem 要跟 Claude Code 联动,核心是靠 MCP 协议把自己注册成 Claude Code 可发现的工具服务。我个人的做法是直接使用 Claude Code 的 MCP 命令添加:

claude mcp add claude-mem -- claude-mem

不同版本可能参数有细微差异,安装好后用claude mcp --help确认一下就好。添加成功后,你会在 Claude Code 的会话里看到 claude-mem 的可调用工具列表,包括检索记忆、保存记忆、检查统计这类能力。

另一种方式是手动改~/.claude/settings.json,在mcpServers里手动加一条,效果是一样的。我建议大部分人选第一种,命令一行搞定,还省得出错。

3.4 验证记忆链路真的跑通了

配置完之后,别急着干正事,先做一次完整验证:

  1. 开一个会话,跟 Claude 闲聊一句“项目里最常说的缩写是 X,代表 Y 模块”。里面可以特意造一个项目里不常见的名词组合。
  2. 用/remember或者 claude-mem 提供的记忆保存工具,把这句闲聊显式存下来。
  3. 退出会话,重新开一个新会话,问它:“你还记得 X 是什么吗?”

如果它能正确答出“X 代表 Y 模块”,说明捕获、存储、检索、注入整条链路都通了。这里有个小技巧:测试时最好用“不常见名词组合”,防止 Claude 靠常识蒙对答案。比如随便编一个符号ZK-Token,第二天看它还能不能想起来。

我用这个方案跑了一周以后,最直观的感受是:每次开新会话,Claude 会主动带上“上次我们正在做什么”的提示,而不是让我重新铺垫一遍。那种感觉有点像早上到工位,旁边同事跟你打了个招呼说“昨天那事我继续跟进哈”——离谱地顺畅。

4. 让记忆真正“好用”的四个关键策略

4.1 记忆注入预算是第一原则

Claude 的上下文窗口再大,也是有限资源。你如果把最近 50 条记忆全塞进去,虽然技术上可能放得下,但预算全被背景信息吃掉了,留给真正任务处理的 token 就少了,回答质量反而下降。

我自己的原则是:注入的记忆总量控制在 2000~3000 token 以内,条数控制在 5~10 条。这在 config.toml 里就是top_k和max_tokens两个参数的事。宁可少而精,不要大而全。记忆系统就像给主持人递提词卡,几张小卡片就够了,而不是塞一整本《百科全书》上去。

4.2 时间衰减与永久记忆的搭配

时间衰减系数很值得细调。它的原理是把“记忆的年龄”作为检索打分时的一个权重因子。比如你设置衰减因子的半衰期是 14 天,那么一条 14 天前的记忆,它的相似度分数会打五折;28 天前打二五折。

但有些记忆不该衰减,比如架构决策项、代码风格约定、团队成员的分工。这类“规则型”记忆应该被固定住。实操上,我会把这类内容用/remember保存时加上固定标记(如果有 pin 参数的话),让它们始终在注入名单里。

做个简单计算你就明白价值了:假设一条记忆的向量相似度是 0.75,如果没有任何衰减,90 天后它照样会排在最前面;如果有衰减,90 天后的有效分可能只有 0.1,直接被过滤。前者会让旧信息干扰新决策,后者能保证记忆库永远“保鲜”。

4.3 多项目隔离,防止记忆“串味”

这是我踩过最大的坑之一。

我同时维护一个小工具项目和一个公司数据项目,两个项目里都有“任务队列”“批量处理”这种词。最开始我没做隔离,结果在数据项目里写代码时,Claude 时不时把工具项目里的旧决策翻出来,还一本正经地用在一个完全不相关的场景里。

建议在 config.toml 或者启动参数里把项目维度分开,比如不同目录用不同的记忆库。claude-mem 本身支持按项目维度存储和过滤,你要做的是确认它确实按路径或项目名隔离了。验证方法很简单:在项目 A 里存一条“A 项目的关键变量名是 alpha”,切到项目 B 里问它“alpha 是什么”,如果它能答出来,说明隔离没生效,赶紧查配置。

4.4 定期体检记忆库:清理、修正、导出

记忆库不用每天管,但建议每个月做一次体检:

  • 看有没有明显错误或过时的记忆,手动删掉或修正。
  • 看记忆条数增长速率,判断压缩策略是否合理。
  • 把重要的架构决策记忆导出成一份项目文档,作为团队共享的背景资料。

我用一个很土的办法:每个月把记忆库里的摘要按时间排序刷一遍,花十分钟过目,就像给电脑清垃圾文件一样。这些看起来不起眼的操作,能有效避免记忆库成为“事实垃圾场”。

5. 实测中的意外情况与排查链路

5.1 症状一:新会话什么都没有注入

第一反应是先确认“记忆到底存进去了没有”。打开 SQLite 数据库,统计一下表里有几条记录:

sqlite3 ~/.claude-mem/memory.db "SELECT count(*) FROM memories;"

如果记录数是 0,说明捕获层就没工作,往上看集成配置。如果记录数是几百条,但新会话的注入列表还是空的,那问题就出在检索层,最可能是这几种:

  • min_similarity设太高,过滤掉了所有结果。
  • 当前工作目录跟记忆库里的项目路径对不上,触发了隔离过滤。
  • 时间范围设太短,比如只检索最近 7 天,但你测试的记忆是 10 天前存的。

排查顺序建议是:先看记录数,再看项目名,再看时间范围,最后调相似度阈值。

5.2 症状二:检索到的记忆“牛头不对马嘴”

这个症状很隐蔽——记忆确实注入了,但注入的是不相关的旧决策。Claude 看到这些背景信息后,有时候还会把它们当作当前任务的上下文,导致回答跑偏。

处理思路是双管齐下:

  1. 降低top_k,从 10 调到 5,减少“凑数记忆”。
  2. 提高min_similarity到 0.4~0.5,过滤低相关的垃圾。

另外,我在会话里发现一个规律:语义检索对“名词短语”的匹配远好于“长句废话”。所以我在手动/remember时,会刻意用“对象 + 动作 + 结论”的短句格式来写,比如:

  • “订单导出:采用异步任务方案,避免接口超时”
  • “配置中心:迁移到 Vault,不再使用明文 properties”

这种结构化短句,向量化之后的区分度明显更高,检索准确率也更好。

5.3 症状三:SQLite 文件一段时间后明显膨胀

记忆库跑了一个月,数据库文件从几百 KB 涨到了几百 MB,这是正常的,但不完全是正常“该有”的。

主要原因有两个:一是没开启摘要压缩,大量的原始对话分片被原文保存;二是 SQLite 在 WAL 模式下会留下大量 WAL 文件碎片。

解决方法:

  • 确认[compression]配置已经开启,summary_threshold_tokens别设太高。
  • 数据库表对应的原始内容可以设置保留期限,比如只保留最近 30 天的原文,更早的内容只保留摘要。
  • 定期执行一次 VACUUM,回收 SQLite 的碎片空间。

实测下来,一次 VACUUM 可以把几个月的库文件缩掉 40%~60%,治标也治本。

5.4 症状四:中文项目记忆检索效果不佳

如果你的项目文档和对话都是中文,可能会遇到一个尴尬:英文记忆检索挺准,中文记忆动不动就查不到。

这跟 embedding 模型对中文的支持程度、分词粒度都有关系。排查经验是这样的:

  • 优先选对中文支持良好的 embedding 模型,不要用纯英文优化的老模型。
  • 手动保存记忆时,把关键词用尽量标准的中文术语写,不要用口语长句。比如“用户在下单页点了提交但没走完支付流程”这种叙述型内容,不如存成“下单页支付流程:转化率问题,卡在支付回调”。
  • 检索时也用短关键词问,不要用一大段描述去匹配。我在配置里把语义检索的召回阈值调低了一点,因为中文向量相似度的绝对值普遍比英文低一些。

这个问题“没有银弹”,核心是得多实测两轮,看哪组配置在你的项目语言组合下表现最稳定。

5.5 还有一招:显式地“教它记住”

任何时候你发现 Claude 忘了某件重要的事,别硬扯别骂它。用/remember类的指令补一条记忆,然后让它基于记忆继续即可。这个习惯养成了以后,整套记忆系统会越用越准。

6. 如果让我从零开始再做一遍

其实我现在再回头看,最重要的体会是:记忆工具要解决的从来不是“存得越多越好”,而是“在该出现的时候出现”。claude-mem 这个工具帮我把“记忆”变成了可管理、可检索、可过期的基础设施,这一点比单纯的对话记录仪强很多。

如果让我从零开始再搭一遍,我会只做三步:装好工具、调通 MCP 注册、设置一个保守的注入预算。剩下的交给时间和真实使用数据去校准,不折腾,不炫技。

最后多说一句:任何记忆系统都会有误判和遗漏,它替代不了你自己对项目大局的把控。你仍然需要定期回到真实代码和文档里,确认 Claude 的记忆没有“越想越偏”。工具只是把上下文成本降下来了,真正的判断力还在你手里。

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

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

立即咨询