
最近在 GitHub 上翻到一个项目名字很简练——claude-mem。如果你长期用 Claude 的 API 或者 Claude Code 写代码、整理文档大概率遇到过同一个尴尬上午聊得好好的下午新开一个会话它完全不记得上午说过什么。Claude 自己是有上下文窗口的但窗口一关历史清零一切从头再来。claude-mem就是给这个痛点补位的它把每次会话自动保存下来整理成结构化记忆下次再聊的时候把相关的历史内容重新注入提示词让 Claude 表现得像想起来了一样。这篇文章我会从原理讲到实操把我折腾这个工具的过程、踩过的坑、以及最后总结出来的一套用法完整分享出来。适合正在用 Claude 做实际项目、又受不了反复交代上下文的开发者参考。1. 这个项目到底解决什么问题为什么我需要它先别急着装工具想清楚一个问题Claude 本身已经有很大的上下文窗口了为什么还需要额外的记忆层这个问题想通了你才知道claude-mem适合放在什么位置。1.1 Claude 的金鱼记忆困境Claude 的每次 API 调用都是无状态的。也就是说模型本身不保存你和它的聊天记录。你看到的连续对话其实是前端把整段聊天历史反复塞给模型模型基于这些历史生成新的回答。这个机制有两个直接后果。第一上下文窗口有上限。虽然 Claude 的窗口已经做得很大但真正常用的场景中长文档、多次工具调用、多轮问答叠加起来很容易逼近上限。一旦超出要么报错要么被静默截断早期的信息就丢了。第二会话之间的记忆完全不互通。你在项目 A 里交代过的技术选型、命名偏好、代码规范切到项目 B 的新会话时Claude 一概不知。重复交代是一件非常消耗耐心的事情尤其是你已经在之前某个会话里花了半小时把一个复杂的业务规则讲清楚了结果第二天又要重讲一遍。我试过最笨的办法每次开场把之前的结论粘贴过去。短对话还行对话一长就不现实。复制出来的东西本身又占 token而且你只会粘自己记得的重要结论那些当时没觉得重要、后面才发现有用的细节就这么丢了。1.2 claude-mem 的定位给 Claude 加一层长期记忆claude-mem做的事情简单说就是三件事存、取、注入。存把每次会话的原始内容落盘形成一份可以检索的历史档案。取新会话开始前根据当前的问题从历史档案里找出相关的片段。注入把这些片段拼到 system prompt 或者对话开头作为背景信息交给 Claude。这样 Claude 在生成回答时就相当于拥有了一份外部记忆不用靠上下文窗口硬扛。它不改变模型本身只是在外面套了一层记忆管理。这个思路其实很像给一个完全没有记性的员工配一个私人助理助理负责在开会前把以前的会议纪要和相关邮件放到桌上。1.3 claude-mem 和 RAG 的区别很多人看到存下来、检索、再注入第一反应是 RAG检索增强生成。本质上确实有相似之处但定位完全不同。RAG 通常解决的是模型不知道的知识比如公司内部文档、产品手册这些是静态的、公开的、多人共享的。而claude-mem解决的是模型曾经知道但忘了的信息这些信息是动态的、私有的、跟具体对话历史绑定的。简单点说RAG 是图书馆claude-mem是你的个人聊天记录本。图书馆里的书谁都可以借但记录本里写的是你和 Claude 之间发生过的具体事情。两者可以共存但不是一个东西。维度Claude 原生会话claude-mem记忆范围单次会话内跨会话、跨项目存储形式内存中临时保存磁盘落盘持久化检索能力无关键词/向量检索额外成本每次调用都带全量历史只带最相关的片段适用场景短对话、一次性问答长期项目、持续迭代这张表基本就是我当时决定折腾它的原因我需要的是跨会话的稳定记忆而不是每次重新开始。2. 核心机制拆解它是怎么把忘记变成记住的claude-mem不是一个黑盒它背后的几个关键步骤都很值得拆开看一遍。理解了这些机制你在配置参数时才不会抓瞎。2.1 会话数据从哪里来要让工具记录会话第一步是让数据流到它手里。claude-mem的接入方式取决于你怎么用 Claude。如果你用的是 Claude Code最常见的方式是在配置文件里配置 hooks。Claude Code 本身支持在特定事件发生后执行外部命令claude-mem就是靠这个接管会话记录的。每当一轮对话结束hook 触发把最新的消息追加到对应的会话文件里。如果你只是用普通 API 写自己的应用接入方式就更灵活了。可以在调用 API 的封装层里加上一段逻辑拿到 Claude 的返回结果后异步调用claude-mem的记录接口把用户输入和模型输出写进去。这里有我的一点经验数据采集尽量放在应用层不要在模型层做。原因是模型层拿到的只是 prompt 和 response没有调用元信息比如会话 ID、用户 ID、触发时间。有了这些元信息后面的检索和过滤才能做得精准。2.2 记忆的加工与存储原始聊天记录不能直接用。如果每次检索都把整段对话塞回上下文那跟手动粘贴历史没有本质区别token 一两轮就爆了。所以claude-mem会在存储阶段做几层处理。第一层是归档原始记录。这是最保险的做法无论如何原始日志留一份后面摘要错了还能回溯。第二层是提取核心事实。比如你告诉 Claude这个项目的部署环境是 Ubuntu 22.04使用 Docker Compose这句就是一条值得单独保存的显式记忆。它会被拆出来打上标签比如环境、部署、项目名。第三层是生成摘要。Claude 的每次会话往往是一大段来回工具会定期对长对话做压缩形成一段简洁的会话摘要。摘要的作用不是替代原文而是为检索提供更高层的入口。比如你问之前为什么选 PostgreSQL匹配到的可能不是某条原始消息而是某次会话摘要里的关键词。存储后端我见过几种实现思路最常见的是 SQLite 加 JSONL 文件。SQLite 存索引和元信息JSONL 存原始消息流。这样做的好处是查询速度快而且只需要一个文件备份非常简单。如果你要自己实现一套同样的机制存储结构至少要包含这几个字段会话 ID唯一标识一次对话用户 ID区分不同使用者时间戳排序和过滤的基础角色用户、助手还是系统内容文本本身标签/元数据用于后续过滤2.3 记忆检索与注入不是全量回放claude-mem最有含金量的部分是检索。工具会在新会话启动时或每次用户提问后拿当前的输入去历史记忆里做匹配找出最相关的若干条记录然后拼装成一段记忆上下文。检索方式通常有两种。简单的是关键词匹配适合记忆量不大、对精度要求不高的场景。复杂一点的是向量检索先把历史记录切成片段用 embedding 模型转成向量再用余弦相似度排序。向量检索的好处是语义相关也能命中即使你这次问题的措辞和之前完全不一样也能找回那段历史。我自己的使用体会是向量检索不是必须的。如果你只是个人使用每天几十轮对话关键词加标签过滤已经够用了。向量检索的收益要到记忆库积累到一定规模后才明显但代价是需要引入额外的模型和计算资源。检索完之后是注入。注入的位置一般有两个system prompt 或者 user message 的开头。我个人更倾向于放 system prompt因为 Claude 会把 system prompt 当作长期背景信息来处理优先级更高不容易被用户说的话干扰。注入的内容要严格控制长度claude-mem里一般会有类似max_context_tokens的参数默认可能几百到一千出头超过的部分宁可不用也不要硬塞。2.4 几个关键参数到底在调什么用这个工具时你会碰到几个参数我把含义说透。top_k检索结果的数量。设得太小可能漏掉关键记忆设得太大无关内容混进来反而干扰模型判断。similarity_threshold相关性阈值只有相似度高于这个值的记录才算是相关。这个值我建议从低往高试先看检索结果是否准确再逐步收紧。max_context_tokens注入内容的最大 token 数。这是硬上限为了控制成本必须设。session_ttl记忆的保留时间。这个参数容易被忽略但对精度影响很大。时间太久的记忆可能早已过期比如某个服务的临时地址强行注入反而误导模型。理解这些参数背后的逻辑之后你就不会盲目照抄别人的配置了。不同项目、不同使用频率最优参数是完全不同的。3. 实操从零搭起一套可用的 claude-mem下面这部分是完全可以照着做的。我尽量把每一步都写清楚包括我自己实际执行时用的命令和配置文件。3.1 安装与环境要求claude-mem这类工具通常以 Node.js 包或 Python 包的形式分发。安装之前先确认本机环境Node.js 18 以上或者 Python 3.10 以上具体看项目文档的要求有 Anthropic API Key并且环境变量ANTHROPIC_API_KEY已经配置好如果你用的是 Claude Code需要安装并初始化过 Claude Code CLI安装命令我以 npm 为例npm install -g claude-mem装完之后先跑一下版本检查claude-mem --version如果命令不存在大概率是 npm 的全局 bin 目录没加到PATH里。Windows 上常见Linux 上一般没事。3.2 最小可用配置安装完成之后第一步先初始化配置目录。我建议把数据目录单独设到一个你容易备份的位置不要放在系统临时目录里。export CLAUDE_MEM_STORAGE_DIR$HOME/.claude-mem claude-mem init初始化之后目录里会出现一个配置文件。最基本的配置长这样storage: backend: sqlite path: $HOME/.claude-mem/memory.db chatlog: format: jsonl path: $HOME/.claude-mem/chatlogs retrieval: method: keyword top_k: 5 similarity_threshold: 0.3 max_context_tokens: 800 injection: position: system enabled: true这里我特意把检索方式设成keyword而不是向量。原因前面说过个人使用场景下关键词检索已经能解决大部分问题而且配置简单不需要额外拉一个 embedding 模型。等你记忆库超过几万条再考虑切换向量检索不迟。设置好配置后可以把显式记忆功能测试一下。显式记忆的意思是你主动告诉工具这句话很重要请记住。我见过有些实现支持类似--remember的参数claude-mem remember 项目代号为 atlas生产环境数据库不允许直连然后在新的会话里搜索claude-mem search atlas 环境约束正常的话刚才那条记录能搜出来。这一步通了说明存储和检索链路是通的后面接入 Claude 才有意义。3.3 接入 Claude Code用 hook 实现自动记录Claude Code 支持通过.claude/settings.json配置 hooks。claude-mem的接入逻辑是在一轮对话结束的 hook 里调用claude-mem的采集命令把消息追加进记录。在项目根目录的.claude/settings.json里添加类似这样的配置{ hooks: { Stop: [ { hooks: [ { type: command, command: claude-mem ingest --session $CLAUDE_SESSION_ID --input - } ] } ] } }注意Stop事件会在一次模型回答结束后触发此时用git diff或者标准输入的变动信息可以把当前轮次的上下文交给claude-mem处理。配置完成后随便在 Claude Code 里聊几句有实质内容的话比如把项目的端口配置改成 8080并且以后所有回话都默认这个端口。然后退出会话新建一个会话直接问这个项目现在默认端口是多少。如果配置生效Claude 应该能给出准确回答。这一步是整篇文章里最容易出问题的地方。很多人配置完成后发现没生效原因多半是以下三个hook 的命令路径不对claude-mem不在 Claude Code 进程的 PATH 里环境变量没传到 hook 子进程$CLAUDE_SESSION_ID是空的配置文件的 JSON 格式不对解析失败但不会报明显错误排查方式很简单在命令行手动执行一次 hook 里的命令看能不能正常输出。能输出问题就在 hook 环境里不能输出问题就在你的配置参数上。3.4 管理命令和数据备份claude-mem一般会提供几个管理命令用来查看和操作记忆库。常见的几个# 列出所有会话 claude-mem list # 查看某个会话的详情 claude-mem show session_id # 搜索某条记忆 claude-mem search 关键词 # 删除某条记忆或整个会话 claude-mem delete session_id --confirm # 导出数据 claude-mem export --format json我强烈建议你定期执行一次导出把记忆库备份到网盘或者 Git 仓库。记忆数据是你和 Claude 反复沟通沉淀下来的丢失了很难找回来。备份频率不用太高每周一次足够。3.5 在自定义 API 应用中集成如果你不用 Claude Code而是自己写程序调 Claude API集成思路稍微绕一点但原理一样。在你的请求处理流程里加三步调用claude-mem search用当前用户输入去检索历史记忆把检索结果拼进 system prompt请求完成后把用户输入和模型输出写入claude-mem伪代码大概是这么个样子user_input 这个项目的数据库密码加密方式定下来了没 memories claude_mem_search(user_input, user_idzhangsan) system_prompt base_prompt memories.to_context() response anthropic.messages.create( modelclaude-sonnet-4-20250514, systemsystem_prompt, messages[{role: user, content: user_input}] ) claude_mem_ingest( user_idzhangsan, messages[ {role: user, content: user_input}, {role: assistant, content: response.content} ] )这套流程跑通之后你的应用就拥有了跨会话记忆能力。用户今天问你一次加密方案定了没过三天再问你还是可以给出当时的结论而且不需要用户在界面上手动翻聊天记录。3.6 多用户场景下的隔离策略如果你的应用是给多个人用的一定要在记忆里区分用户维度。claude-mem的检索命令通常支持指定用户 ID 或项目 ID比如claude-mem search 部署环境 --user-id zhangsan不要把所有用户的记忆混在一起。我见过有人图省事把系统里所有用户的对话都写进同一个记忆库结果用户 A 问我之前定的方案你记得吧Claude 答成了用户 B 的方案。这个 bug 特别难排查因为从代码逻辑上看完全没问题问题出在数据隔离缺失。4. 常见问题与排查技巧实录这部分是我实际使用中踩过的问题汇总不保证覆盖所有情况但大概率能帮你省几个小时排查时间。4.1 检索结果总是命中旧信息怎么办这是记忆工具最常见的翻车场景。原因大多数是检索参数没区分时间维度。比如你一个月前用 PostgreSQL这周切到了 MySQL但旧记忆权重太高每次搜索数据库都命中 PostgreSQL 的那条记录。解决办法有两个层面。第一个是配置层面把top_k调低同时加上时间衰减逻辑。有些工具支持类似recency_weight的参数时间越近的记录权重越高。第二个是使用层面重要变更发生时手动把对应的旧记忆删除或标记为过期比如claude-mem delete old_record_id --confirm不要指望工具自动判断所有内容是否过期。机器判断不了你的业务变化定期清理是必须的。4.2 token 成本为什么会暴涨用claude-mem之后如果发现 API 账单明显上涨大概率是注入内容太多。每次请求都携带 2000 token 的记忆上下文一天几千次请求这个增量就很可观了。我的建议是严格控制max_context_tokens。个人日常问答600 到 1000 token 足够代码生成场景可以稍微放宽但也不要超过 1500。另外可以加一个规则只在会话开始时注入记忆会话中间不重复注入。否则每一轮都重新检索、重新注入成本翻倍。4.3 显式记忆和自动记忆谁优先级更高我测试下来显式记忆应该永远优先于自动摘要的内容。实现方式也很简单给显式记忆打一个更高的标签权重比如source: explicit检索排序时优先展示。如果你使用的工具不支持权重排序那就把显式记忆直接拼在检索结果的最前面。模型对前置内容的关注度远高于后面内容这条规则虽然有点暴力但有效。4.4 记忆丢失或找不到如何排查先确认数据有没有写进去。执行claude-mem list --limit 10看看最近的会话在不在。如果在但搜不到问题出在检索链路。检查关键词是否一致例如你记得当时说的是数据库密码但配置里把重点标签设成了数据库凭据那就搜不到。如果记录也没了那就得看存储文件。SQLite 文件是否存在、是否有权限、是否在会话过程中被其他进程锁住。这类问题多半和存储路径配置有关检查配置文件里的路径是不是在系统重启后发生变化。我整理了一张速查表按现象直接对照处理方法现象可能原因处理方式搜索无结果关键词不一致或阈值太高降低 similarity_threshold搜索有结果但内容混乱注入顺序不对把显式记忆放前面会话记录没有写入hook 未触发手动执行 hook 命令检查路径token 成本异常max_context_tokens 过大限制注入长度会话内只注入一次多用户记忆串线没有按用户过滤检索时指定 user-id数据目录被清空使用了临时目录改用固定路径并备份4.5 注入内容被模型忽略模型不是每次都严格遵循 system prompt 里的记忆内容。有时候你明明注入了用户偏好使用简洁回答但模型还是啰嗦了一大堆。这种情况不一定是注入没生效可能是你的记忆内容太模糊。比如用户偏好简洁这种描述不如改成用户要求回答不超过 200 字不要列多余步骤。具体的约束比抽象的偏好更容易被模型执行。另外注入内容尽量用陈述句避免疑问句。你写用户是否喜欢简洁回答模型可能会把这句话当作一个问题来处理而不是一条背景指令。5. 我的一些使用体会和扩展想法最后这部分不打算写太长的总结就分享几件我在实际使用中印象比较深的事。第一件事记忆工具真正提高效率的阶段是在记忆库积累了大概两周之后。刚装上的头两天你会觉得这工具很鸡肋搜出来的东西感觉都是废话。这是因为记忆太少、太碎片化。坚持用下去让对话记录沉淀出规律它才开始好用。第二件事摘要生成要给 Claude 留出专门的调用。如果你只是把历史记录原样存下来不提炼摘要检索效果会打折扣。但反过来如果每一轮都让 Claude 做一次长文本摘要成本也不低。我的做法是只在会话结束或者隔段时间做一次总结不是每条消息都摘。第三件事claude-mem未来如果能和 MCP 生态打通会方便非常多。现在的记忆工具本质上是一个独立服务需要外部把对话数据喂给它。如果能做成标准 MCP 工具让模型自己决定什么时候读写记忆那记忆就不只是注入上下文这么简单而是真正变成了模型可调用的外部能力。从接入体验来看这是很自然的演进方向。有一段时间我也试过最土的办法直接用一个 JSON 文件手动往里面塞关键信息然后每次请求前手动拼到 prompt 里。这个办法在会话数量很少时确实能用但一旦超过三五十条记录手动维护就完全不可持续了。claude-mem这类工具的价值恰恰在于把存、取、注这个流程从手工变成了自动化。另外一个让我比较惊喜的场景是它不只是给你当前的 Claude 会话提供记忆还能让你跨会话检索自己之前的所有思考过程。比如整理月度复盘时直接搜这个月踩过哪些坑能把散落在十几个会话里的相关内容一次性拉出来。这种能力比单纯记性好用得多等于给自己的工作留了可检索的底稿。如果你正在被每次重新交代上下文折磨不妨把它当成一个小基础设施去搭。装好、配置好、然后把备份做起来。它在前期需要一点耐心但磨合期过后带记忆的 Claude 和裸用的 Claude体验差距不亚于有草稿箱和每次写完再重抄一遍。我自己现在的新项目已经默认加上了这层记忆层今后大概率也会一直用下去。