资讯动态

claude-mem:给Claude Code接入跨会话长期记忆的实践指南

发布时间:2026/10/9 3:55:48 来源:尧图企业网站定制
每天打开一个新的 Claude Code 会话你有没有一种感觉这个 AI 又把我当成第一次见面的人了项目背景要重新说明代码风格要重新交代连上一周刚讨论定的接口版本策略它也忘得干干净净。claude-mem 这个开源项目就是冲这个痛点来的——它利用 Claude Code 的 hooks 机制在会话结束时把关键信息提炼成结构化记忆存进本地数据库下一次会话开始时按需把最相关的几条注入上下文让 AI 第一次拥有跨会话的长期记忆。如果你正在重度使用 Claude Code或者准备给团队搭一套带长期状态的 AI 工作流那这篇文章不是泛泛介绍而是我从安装到上生产环境的完整折腾记录。1. 为什么我在集成式AI工作流里加了一层记忆插件1.1 会话隔离的代价Claude Code 每次都像新人Claude Code 天然就是每开一个会话从零开始。这个设计本身没有错隔离上下文能避免不同任务互相污染但它有一个很扎心的副作用同一个项目里你上周已经和它讨论清楚的事情这周又要重新解释一遍。我带过的团队里几乎每个人都干过这种事——把项目背景、目录结构、接口约定、避坑指南在会话第一轮用大段文字重新喂给 AI。然后第二周再重复一次。这不是用户不会用而是工具的结构性缺陷。没有持久状态的 AI就像没有 git 的代码库你可以继续写代码但没人记得上一次 commit 里改了什么、为什么改。当你同时在管三四个仓库、五六条需求线时这个缺陷会被无限放大。我算过一笔账按一天 8 小时严格使用 Claude Code 来算每天至少有两成左右的 token 浪费在重复背景说明和纠正 AI 的失忆错误上。时间成本比 token 成本更贵——因为每次 AI 猜错项目约定你都要停下来核对代码、翻文档、然后纠正它。我自己试过用 CLAUDE.md 来缓解这个问题把项目规则写在里面让每个会话启动时自动读取。但它有两个天然短板第一CLAUDE.md 是静态的你得手动维护第二它记不住当时我们为什么这样决定的语境只有结果没有来龙去脉。真正的需求不是一份固定文档而是一个能跟着项目进展不断更新的动态记忆层。这个记忆层要能回答三个问题这个项目现在的约定是什么上次讨论到哪了哪些决定还没落地1.2 记忆插件的定位不是数据库而是上下文过滤器很多人的第一反应是给 AI 加记忆不就是把之前的对话全存下来下次再一股脑塞给它吗这个思路错得很彻底。上下文窗口是有限预算你把一万条历史对话都塞进去就算 Context 能装下真正有用的信息也会被淹没模型注意力被无关细节稀释回答质量反而断崖式下降。claude-mem 的核心设计理念是记忆不是存储系统而是过滤器。它只保留三类东西——事实、偏好、决策并且每条记忆都是一个短小的原子条目而不是一长串聊天记录。这就像复习考试时你不会把整个学期的教科书重新看一遍而是翻自己整理的错题本和知识卡片。错题本帮你把几百页内容压缩成几十条关键信息考试时一眼扫过去就能快速唤起记忆。理解了这一点你才能明白为什么 claude-mem 要用提炼 检索 注入这三步走而不是简单地把历史 log 倒出来。它是在模仿人脑的工作方式遗忘掉大部分过程只记住结论和教训。后面所有配置、调优、踩坑都是围绕这个定位展开的。2. claude-mem 的记忆管道从对话转写到检索注入的全链路2.1 捕获端Hooks 挂钩的是对话生命周期先看最底层的数据从哪里来。Claude Code 本身是有 hooks 机制的它会在会话生命周期里触发特定事件比如 SessionStart、Stop、PreToolUse、PostToolUse、Notification。claude-mem 主要挂在两个节点上Stop 时抓取完整会话转写SessionStart 时做记忆注入。为什么要选 Stop 而不是每轮对话都抓我最初也觉得实时抓取更靠谱但实测下来问题很大。一是每轮都跑一次提炼费用和时间成本翻数倍二是会话中途的信息往往还没定型你今天说可能考虑迁移到 XX 方案过三小时又说算了还是维持原样如果每轮都提取就会把讨论中的想法固化成结论反而制造噪音。只在 Stop 时做一次整体扫描能拿到完整的上下文提炼出的结论也更接近最终状态。捕获完成后会话转写并不会直接进记忆库。claude-mem 会先把转写落到一个临时文件再交给后面的提炼模块处理。整个过程在 hooks 配置里就是一个命令的事但真正的逻辑都在后台管道里。2.2 提炼端规则加模型把文本压成结构化条目如果把原始转写直接存库记忆库很快会被垃圾信息淹没。你每句帮我看看这个报错试一下这个方案都会被原样保存检索时还容易和真正有价值的记忆抢排名。所以 claude-mem 在提炼端做了两层处理。第一层是规则过滤器。它会先扫描文本找出一批高信号词汇比如我决定记住以后都用我们约定不要再用这类表达把它们所在的目标句子圈出来进入候选池。这个规则表是可以自定义的我会根据自己团队的说话习惯往里加词——比如我们常说这个接口已经废了我就会把这个短语加进信号词表让这类表述更容易被捕捉。第二层是模型抽取。候选池里的句子会被交给一个模型让它按照预设的 Schema 输出结构化记忆。每条记忆包含几个关键字段内容、类型、作用域、时间戳、重要度、来源会话 ID。类型我一般分成四种fact客观事实、preference个人或团队偏好、decision敲定的决策、todo待办事项。这样区分非常重要后面检索和过滤都是靠类型来约束的。结构化的好处是记忆库不再是一堆散文而是可以按条件查询的关系表。一条典型的记忆长这样{ content: 前端新模块目录统一使用 kebab-case 命名禁止用 snake_case, type: decision, scope: repo:frontend, timestamp: 2025-06-12T14:30:00Z, importance: 0.85, source_session_id: a3f9c1 }2.3 存储端SQLite 加向量索引的组合存储层怎么设计直接决定了检索性能的上限。我见过很多人一上来就上向量数据库结果配置复杂、资源占用高最后跑得还不如一个 SQL 查询快。claude-mem 的默认方案是 SQLite 主存储外加一个向量索引。说白了就是结构化字段放 SQLite语义检索字段单独建索引。SQLite 解决的是精确查询问题比如这个项目有哪些 decision 类型条目最近三天新增了哪些记忆。这些等值查询和范围查询用 SQL 非常快。向量索引解决的是语义相似问题比如用户新会话里说了句我们之前是不是定过 API 版本策略这句跟记忆库里的文字不一定有共同关键词但向量空间里它们距离很近能召回到那条 API 版本的决策记忆。我建议的存储配置如下表方案优点缺点适用场景纯 SQLite轻量、可审查、支持复杂过滤语义检索弱只能关键字匹配手动维护、记忆量小纯向量数据库语义召回能力强部署重、索引维护复杂大规模多项目共享SQLite 向量索引元数据过滤和语义召回兼顾实现稍复杂claude-mem 默认选型适合日常开发向量索引这里有个实现细节值得注意它并不单独开一个常驻服务而是作为本地文件保存在项目目录的隐藏目录下面比如.claude-mem/vector.index。这样 clone 一个仓库时记忆索引不会跟代码混在一起也不会因为协作者不同的本地状态产生冲突。embedding 模型可以选本地模型也可以调用云端 API我建议先跑本地的轻量 embedding 模型省去隐私顾虑响应速度也更快。2.4 注入端把记忆装进 System Prompt 的合适位置记忆提炼好、存储好最后一步是下次会话怎么用。SessionStart 触发时claude-mem 会做几件事先拿到当前项目目录作为 scope 过滤的键值再拿用户的第一条消息或预先配置的任务描述作为查询向量从记忆库里召回 Top-K 条最相关的记忆最后把它们拼成一个固定的 Memory Context 文本块追加到 system prompt 尾部。这一步看似简单但有几个关键参数需要控制。第一个是 Top-K我默认设成 5多了容易混入噪音少了又可能漏掉关键决策。第二个是最低相似度阈值默认 0.25低于这个分数说明相关但不够相关不注入。第三个是注入的 token 预算claude-mem 会限制整个 Memory Context 块的长度默认不超过 3000 token防止记忆喧宾夺主把 Claude Code 本应处理的用户任务挤出上下文窗口。这里还有一个细节要注意把记忆明文塞进 system prompt会让模型认为这些记忆都是高优先级约束。如果记忆库里有一条过时的决策Claude 却把它当成当前规则就会固执地按旧真相行事。这个问题非常常见我单独拉一节专门讲这里先按不表。3. 安装与接入从零跑通 claude-mem 的完整过程3.1 前置条件Claude Code 版本与 Node/Python 环境claude-mem 的组成有点特殊它不是单一体capture 和 inject 等 hooks 入口是 Node.js 命令所以你需要装好 Node但真正做模型抽取和向量检索的模块是 Python 写的所以还要保证 Python 环境干净可用。听起来有点绕但习惯了就会发现这种组合很常见——接口层用轻量 Node数据处理层用 Python 生态。安装之前先确认三件事claude --version node -v python3 --versionClaude Code 的版本不能太老hooks 机制是后面才加的建议至少 0.1.43 以上。Node 和 Python 不需要最新版稳定版本即可我在 Node 18 和 Python 3.10 上都跑过没有任何问题。3.2 安装主程序与初始化数据库环境备齐后安装过程反而很轻量npm install -g claude-mem claude-mem initinit 命令会做三件事在~/.claude-mem/config.toml生成默认配置、创建记忆数据库目录、下载/指定 embedding 模型。config 文件里最重要的几个字段是embeddings_model默认 local指定本地模型也可以设成 api走云端 embedding 接口。memory_limit单条记忆内容的字符上限默认 500避免存进去一整段对话。inject_top_kSessionStart 注入记忆条数默认 5。min_score检索最低相似度阈值默认 0.25。我强烈建议第一次就跑 local 模式。理由很简单claude-mem 的提取模块会把会话转写发给模型做强提炼如果走云端 API等于每一次会话结束都要把完整对话送到第三方虽然不少团队不在意但在公司仓库上这就是合规风险。本地模型慢一点但胜在可控、不依赖外网、没有额外费用。3.3 在 Claude Code 里注册 Hook安装完只是装好了工具还要让 Claude Code 知道自己该在什么时机调用它。这里的配置位置是~/.claude/settings.json或项目级的.claude/settings.json后者优先级更高。用项目级配置的好处是不同仓库可以挂不同的记忆作用域同一个人的全局配置则会被所有项目共用。一个常见的配置长这样{ hooks: { SessionStart: [ { hooks: [ { type: command, command: claude-mem inject } ] } ], Stop: [ { hooks: [ { type: command, command: claude-mem capture, timeout: 120 } ] } ] } }Stop hook 的 timeout 我特意调成了 120 秒因为大项目的会话转写可能很长提取模块跑完需要时间。如果你用的是云端模型做提取这个 timeout 还得再放大一些。注册完 hooks重启 Claude Code 才能生效。这一步很多人会忘——我见过好几个同事配置改完后不重启在那儿干瞪眼半小时。3.4 验证最小链路让它记住你的咖啡偏好第一次接入完别急着搞复杂场景先做一个最轻量的验证确认整条链路是通的。我自己习惯用包管理器偏好来做冒烟测试风险为零、结果直观。具体操作是这样新开一个 Claude Code 会话输入一句话我喜欢用 pnpm 管理依赖不喜欢 npm install。正常聊几句然后/exit结束会话。再次新开会话直接问它我对包管理器有什么偏好如果 claude-mem 生效它会准确回答你偏好 pnpm。如果它答不上来或者答错说明链路某个环节断了。这时候去看日志最常见的坑是 Stop hook 没触发——检查一下你是不是真的用了/exit而不是直接关掉终端SessionStart hook 没注入——检查一下 settings.json 的路径是否对、配置结构是否符合当前 Claude Code 的 schema。4. 核心能力演示让 Claude Code 记住我们项目的关键决策4.1 场景排练一次重构讨论后新会话自动继承决策上下文链路由 smoke test 之后就可以拿真实项目场景来检验它的价值了。我用过最典型的场景是一次 API 版本策略讨论。会话 A 里团队在讨论是否要全面迁移到 /v2 接口。当时你说了很多兼容期怎么定、哪些老接口要保、哪些直接砍掉最后敲定结论/v2 从 7 月 1 日起全面接管/v1 保留六个月的兼容窗口。聊完直接/exit。会话 B第二天早上打开你不用重复任何背景直接问我们 API 的版本策略是什么 claude-mem 在 SessionStart 时已经针对当前项目的 repo scope 召回到这条 decision 记忆并把它放进了 system prompt。Claude 会直接告诉你根据项目记忆/v2 从 7 月 1 日起全面接管/v1 兼容到年底。这个体验最爽的点在于你不需要专门跟它说这是昨天的结论它自己就默认按既定决策行事。相当于你在团队里带了一个记性极好的实习生你跟它说过一次的事情它下次不会再来问第二遍。4.2 用记忆做项目标准约束除了临时的决策项目里还有一类更长期的东西很适合交给 claude-mem就是工程规约。比如前端新文件命名统一用 kebab-case所有对外接口必须带 OpenAPI 注解后端不允许在业务代码里直接编写原生 SQL。这些约束过去有两种处理方式写进 CLAUDE.md 或者每次会话开头口头交代。前者维护成本高后者容易漏。claude-mem 给了第三种路径从过往对话里自动提取或者手动写入一次之后每次 SessionStart 都会自动注入。我自己更喜欢手动写入的方式因为工程规约通常发生在非常早期的讨论里提取模型不一定能准确识别出来而一旦你在某个会话里明确说过记住以后这里都按这个来它就会进入偏好或决策类记忆形成长期约束。要注意的是这类项目标准记忆的重要度通常很高。如果不想让模型自作主张可以在 config 里开启决策确认模式让 Claude 在涉及关键决策时先说一句根据项目记忆你们之前约定……是否遵循再行动。这样记忆只是参考而不是把 AI 变成死脑筋。4.3 通过命令直接写入手工记忆自动捕获再牛也不可能覆盖所有场景。有时候你想在会话中间快速塞一条约定不想等 Stop 之后才被提炼claude-mem 也提供了一组手动命令claude-mem add --scope backend --type decision 用户认证统一走 OIDC不再自建 session 表 claude-mem list --scope backend claude-mem remove --id 23这条命令我非常推荐在想在代码里先写注释但又不希望 AI 忘了这个约定的场景用。比如你在设计评审会上刚确定了一个技术选型趁热打铁跑一条 add这个决策就定格了。比起先聊到 Stop 再让它自动理解和提炼手动命令的优势是精准、无歧义不会出现提取模型理解偏差的问题。除此之外claude-mem list很适合做定期盘点看看库里面现在都有哪些条目。我每周至少跑一次把它当项目记忆的健康检查——清理掉垃圾、修正错误、合并重复。5. 实测中最容易翻车的三个环节数据质量、匹配精度与级联失效5.1 数据污染当旧决策因为曾说过一次而变成真理这是我对 claude-mem 印象最深的一个坑。有次我们讨论要不要把算力模块从 Python 重写成 Rust讨论过程中我随口说了一句要是能用 Rust 重写性能应该能好不少。结果这句话被提取成了一条 decision 类型记忆重要度还挺高。之后几天里不管聊什么功能Claude 都时不时建议可以考虑用 Rust 重构算力模块甚至在我明确表示暂缓之后它还坚持这个方向。根子出在提炼端模型分不清假设性讨论和实际决策只要语义上像结论就可能入库。这个问题的解法思路是治理记忆质量。一是靠分类。给记忆类型设置权重decision 类型拥有最高约束力fact、preference、todo 次之。当一条记忆的来源只是一句没有明显决策信号的随口语时让它进 preference 甚至不进库。二是开确认模式。高重要度决策在注入时不是让模型直接奉为真理而是先问一句根据记忆你们曾讨论过 Rust 重写需要我按这个方向做吗——给模型一个可以推翻的出口。三是定期清理。我习惯每个月跑一次claude-mem list --type decision把那些已经落地、已经过时、或者根本就是讨论产物的条目直接删掉。记忆不是用来囤的而是用来辅助当下决策的过期的记忆比没有记忆更危险。5.2 匹配精度向量检索的 Top-K 选不好注入的不是相关而是噪音我一开始天真地以为embedding 检索嘛相似度算出来取 Top-5 就行。但实际跑下来经常会出现一种情况召回的第一名确实和当前任务高度相关但从第二名开始就全是泛泛的团队偏好比如我们喜欢写测试代码要简洁。这些信息不是说没用但它们对当前具体任务毫无帮助反而占用记忆上下文。这个问题的本质是单纯依赖向量相似度会偏向语言风格接近而非业务上下文相关。我的优化实践分成三步。第一步先做 scope 过滤再召回。在检索时限定scope当前项目把候选集从几千条缩小到几百条再去算向量相似度。这就好比你在一个城市里找人先锁定街道再拿着照片一个个认效率完全不一样。第二步增加重排逻辑。召回 Top-K 之后不要直接输出而是用一条轻量规则给候选记忆打个加权分重要度越高权值越大时间越近权值越大类型如果是 decision 则再加一分。最后按加权分排序选出真正当前任务需要的。第三步调整top_k和min_score。top_k从 5 起步如果发现注入的记忆里经常出现不相关内容就调小如果发现 Claude 经常问这个项目是不是以前讨论过XX就说明召回不够调大。min_score则用来挡住那些有点相关但不确定的弱匹配我一般维持在 0.25 左右。5.3 级联失效Hooks 没触发、提取失败、注入超大文本整个 claude-mem 链路其实是一条数据管道任何一环断了都会表现为记忆没生效但真正排查起来要分清三个故障区。第一类是 hooks 没触发。Claude Code 版本升级后settings.json 的 schema 可能变化旧配置失效或者 hooks 事件名称改了。排查方式是打开 logs 看 SessionStart 和 Stop 有没有对应执行记录如果没有就去检查配置结构和当前版本是否兼容。第二类是提取失败。Stop hook 超时、模型调用报错、transcript 转写格式变化都会导致捕获得不到可用记忆。我遇到最多的是超大会话导致 Stop hook 超时。解决办法是把 capture 做成异步——hook 只负责把 transcript 丢进队列真正的提取逻辑由后台 worker 慢慢跑而不是阻塞在 hooks 里等结果。第三类是注入的超大文本。如果记忆库条目太多、Top-K 太大注入的 Memory Context 会挤爆上下文预算表现为会话首轮响应变慢甚至 Claude 开始无视上下文回答变得答非所问。解决办法是在 config 里限制max_inject_tokens同时把 Top-K 降到一个保守值。我把排查常见症状整理成了一个表格方便你对照症状可能原因排查路径解决方案新会话完全不记得旧事SessionStart hook 未执行检查 hooks 日志升级配置结构重启 Claude Code记忆偶尔生效但内容很旧Stop hook 超时未提取看 Stop hook 执行时间改成异步 capture加大 timeout首轮响应特别慢注入文本过大统计 Memory Context 长度降低 inject_top_k / max_inject_tokensClaude 坚持错误决策记忆库有过期 decision运行 list 查看记忆条目删除过期条目开启确认模式6. 进阶把 claude-mem 接进多人协作者工作流时的调优建议6.1 多项目多分支的记忆隔离当 claude-mem 只服务于你一个人一个仓库时记忆混一点问题不大。可一旦团队里有好几个人、项目不再只是单个仓库记忆隔离就变成了一件必须认真对待的事。我的做法是给每个仓库设置独立的 scope比如scoperepo:backend和scoperepo:frontend。这样后端仓库里讨论的数据库连接池调大不会跑到前端仓库里变成噪音。分支层面也一样临时功能分支上的讨论最好用branch:feature-xxx这样的临时 scope 标记等功能合并后再统一迁移到主干 scope。如果不管这些最典型的结果就是你在 feature 分支上决定这个版本先不做权限优化等切回主分支之后Claude 还老念叨这个决定非常闹心。claude-mem 的 config 里有include_scopes和exclude_scopes字段可以控制哪些 scope 参与检索。我推荐主干记忆只保留稳定的项目事实和团队契约临时分支讨论则放在独立的临时 scope 下事后再清理。6.2 共享记忆库与 Git 版本控制的取舍团队协作避不开一个问题记忆能不能跟代码仓库一起走我的结论是向量索引和 SQLite 数据库文件绝对不能提交进 Git。原因有三这些文件经常变、体积会增长、二进制格式不适合 review。你自己本地跑得很爽的 embedding 索引提交上去只会让队友在 clone 时拉下一堆没用的重复文件。那怎么共享团队记忆我采用的方案是种子记忆机制。维护一个claude-mem/seed/目录里面放若干 Markdown 文件每个文件对应一类基础记忆。比如seed/project-conventions.md里写清楚项目结构、命名规范、测试要求seed/known-decisions.md里记录重要技术选型。新成员 clone 仓库后第一件事是运行claude-mem init --seed ./claude-mem/seed这个命令会把这些 Markdown 转成结构化记忆导入本地库。这样团队的基础约定就实现了写进仓库、可 review、可版本化而每个人自己的 Session capture 产生的动态记忆只留在本地。这套方案完美分离了团队共享的稳定知识和个人产生的临时上下文。6.3 与 CI/Agent 组合把记忆用于自动 PR 检查和任务上下文传递claude-mem 不只可以在人类开发者手里发光也能在 CI 和自动化 Agent 场景里发挥价值。我后来把记忆检索的结果接到代码评审机器人上效果非常显著。思路是这样的PR 触发的自动评审 Agent 本身也是没有记忆的 AI它对项目背景一无所知。但我在 CI 脚本里加了一步在启动评审机器人之前先跑一次claude-mem inject --scope repo:backend --max-tokens 2000 /tmp/agent_memory_context.md然后把这份记忆上下文作为额外的 context 传给评审 Agent。Agent 在检查 PR 时就会知道团队所有对外接口必须带 OpenAPI 注解不得引入额外 session 管理依赖这类约定评审建议的命中率和准确度立刻上一个台阶。这个用法还有一个潜在衍生场景像任务调度 Agent 这种需要串联多轮任务的自动化组件每次执行前注入记忆可以让它记住批量任务之间的前置条件和后续要求不再每次都像失忆了一样重新开始。代价是需要一个共享可读的记忆源比如团队共享存储或 CI 产物的归档目录。最后分享一个我自己的使用习惯每个月底我会手动跑一次claude-mem list --type decision --output markdown把它当成项目遗忘清单把已经落地、已经过时、或者本来就不该记的条目删掉给记忆库做一次下班前的整理。用 claude-mem 最深的体会是它不是一个容量无限的笔记本而是一个学会遗忘的助手。记忆系统能走多远不取决于它存了多少而在于它有没有勇气丢掉那些不再重要的。希望这篇基于实际折腾过程的分享能帮你省掉我踩过的那些坑。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑