1. 项目缘起与核心定位1.1 从一次“记忆断片”说起做长期项目的人大概都遇到过这种尴尬上周跟搭档讨论好的接口约定这周打开代码编辑器脑子里只剩一句“当时好像说用驼峰来着”。翻聊天记录翻了二十分钟最后发现约定的是下划线。这不是记性问题是工具链的问题——我们每天在跟 AI 助手对话但绝大多数对话都是“阅后即焚”的关掉窗口上下文就归零了。claude-mem这个项目本质上就是在解决这件事。它不是某个官方产品而是一类围绕 Claude 生态构建的持久化记忆层方案的总称。核心思路很朴素把每次对话里值得留存的信息——决策、约定、偏好、踩过的坑——抽出来存到一个结构化的本地记忆库里下次对话时按需召回重新注入上下文。这样一来AI 助手就不再是每次从零开始的陌生人而是一个记得你项目脉络、记得你代码风格、记得你上次说“这个库别用有坑”的老搭档。它适合谁三类人最该关注。第一类是长期维护同一套代码库的开发者项目周期动辄几个月上下文丢失的成本极高第二类是写长文档、做系列内容的人前后一致性靠人脑记根本扛不住第三类是把 AI 助手当日常生产力工具的重度用户每天几十轮对话没有记忆层等于每天重新自我介绍一遍。1.2 它到底解决什么问题把痛点拆开看claude-mem这类方案主要对付四个场景。上下文窗口的物理限制。任何模型的上下文长度都是有限的哪怕标称几十万 token实际用起来也会因为成本、延迟、注意力衰减等问题打折扣。你不可能把三个月的项目历史全塞进去必须做取舍。记忆层的作用就是帮你做这个取舍——不是全存全取而是存摘要、取相关。跨会话的状态延续。今天讨论到一半的方案明天接着聊中间隔了一夜模型那边是彻底失忆的。记忆层把“未完成的讨论”标记成待续状态下次开新会话时自动带出来体验上就连续了。团队协作中的知识沉淀。一个人跟 AI 聊出来的结论如果只存在他自己的会话历史里对团队就是黑盒。把记忆库做成可共享的文件团队里谁都能读到“我们为什么选了这个方案”新人上手成本直接砍半。重复解释的精力浪费。你有没有发现每次新开会话都要重新说一遍“我用的是 Python 3.11别给我 2.x 的写法”“这个项目不用 ORM手写 SQL”这些偏好一旦沉淀成记忆就再也不用重复了。1.3 为什么是“记忆”而不是“知识库”这里要区分一个容易混淆的概念。传统知识库比如把文档丢进向量库做 RAG解决的是“查资料”问题你问它答被动响应。而claude-mem这类记忆层解决的是“记住我”问题它更主动、更个性化、更贴近工作流的连续性。打个比方知识库像图书馆你去找书记忆层像你的工作笔记本它知道你昨天写到哪、为什么这么写、下一步打算干嘛。两者可以共存但定位完全不同。记忆层的关键特征是写入时机由对话驱动、内容以决策和偏好为主、召回时优先考虑时效性和相关性而不是单纯做语义相似度匹配。理解了这层定位后面的技术选型和实操才有方向。很多人一上来就堆向量数据库结果发现召回的全是无关的旧对话就是因为没想清楚“记忆”和“检索”的区别。2. 记忆层的架构设计与选型考量2.1 三层记忆模型短期、工作、长期我在实际搭建时把记忆分成三层来管这个划分直接借鉴了认知科学的模型落地效果比单一存储好很多。短期记忆就是当前会话的原始对话流不做任何加工存在内存或临时文件里会话结束就丢。它的作用是给当前这轮对话提供完整上下文不需要检索直接全量喂给模型。工作记忆是跨会话但有时效性的内容比如“本周正在做的任务”“当前迭代的目标”。它需要持久化但过期就该清理。我一般给它设 7 到 14 天的生命周期超期自动归档或删除。长期记忆是真正沉淀下来的东西项目架构决策、代码规范偏好、踩过的坑、常用工具链。这部分生命周期无限但需要定期做去重和摘要压缩否则会越滚越大。三层分开管的好处是召回策略可以差异化。短期直接全量注入工作记忆按时间窗口过滤长期记忆才走语义检索。如果混在一起要么召回太杂要么该记的没记住。2.2 存储选型为什么我最终选了 SQLite 向量索引存储这块我试过三种方案最后落在 SQLite 加本地向量索引的组合上。第一种是纯文件方案每次对话追加到一个 Markdown 文件里。优点是简单、可读、能直接 git 管理。缺点是检索全靠关键词匹配稍微换个说法就找不到而且文件大了之后读取慢。第二种是纯向量数据库比如把每条记忆编码成向量存进去。检索确实强但问题是元数据管理弱你想按“项目名 时间范围 类型”做复合过滤时很别扭而且部署和维护成本对个人项目偏重。第三种就是我现在用的SQLite 存结构化字段向量索引存语义特征。每条记忆一行记录字段包括 id、项目标识、类型决策/偏好/坑/待办、内容、摘要、创建时间、最后访问时间、访问次数、向量 blob。检索时先用 SQL 做硬过滤比如限定项目和时间范围再在候选集里做向量相似度排序。这样既保证了过滤精度又保留了语义召回的灵活性。选 SQLite 还有个现实原因它是单文件扔进项目目录就能跟着 git 走团队共享零成本。向量部分我用的是本地轻量方案不依赖外部服务离线也能跑。2.3 写入策略什么时候该记什么时候不该记这是整个项目里最容易被忽视、但最影响效果的环节。我的经验是不是所有对话都值得记记错了比不记还糟。我设了几条写入触发规则。第一显式指令触发比如对话里出现“记住这个”“以后都这样”“这个别忘”之类的表达直接标记为高优先级记忆。第二决策类内容触发当对话里出现方案对比、选型结论、架构讨论时自动抽取结论部分。第三纠错类内容触发当用户纠正 AI 的错误时把“错误做法 正确做法”成对记录这类记忆价值极高。第四偏好类内容触发用户表达“我喜欢”“我习惯”“别用”时记录。反过来闲聊、临时调试、一次性的问答这些不记。判断标准很简单这条信息在两周后还有用吗如果答案模糊就不记。宁可漏记不要污染记忆库。我早期犯的错就是什么都往里塞结果召回时噪音太大反而干扰了正常对话。2.4 召回策略相关性、时效性、重要性的三角平衡召回不是简单的“取最相似的几条”。我用的打分公式大致是这样score w1 * 语义相似度 w2 * 时效衰减 w3 * 重要度 w4 * 访问频次语义相似度用向量余弦距离算权重最高占 0.5 左右。时效衰减用指数衰减函数越新的记忆得分越高但衰减不能太狠否则三个月前的架构决策会被埋掉所以权重给 0.2半衰期设 30 天。重要度是写入时打的标签决策类 1.0偏好类 0.8普通记录 0.5权重 0.2。访问频次是个正向反馈被召回后用户如果继续用了这条记忆频次加一权重 0.1。这套参数不是拍脑袋定的是我调了两周、看了几十次召回结果后收敛出来的。不同项目可以微调但整体框架通用。关键是要有可解释性——每次召回你都能说清楚为什么这几条被选中而不是黑盒。3. 核心实现细节与关键代码拆解3.1 记忆抽取从对话流到结构化记录抽取环节我写了一个轻量的规则加模型混合方案。纯规则太死板纯模型调用成本高且不稳定混合最实用。先走规则层做初筛。用正则匹配触发词比如“记住”“别用”“以后”“约定”“决定”这些。命中后把前后各若干轮对话切出来作为候选片段。这一步能过滤掉 80% 的无关内容大幅降低后续模型调用量。然后走模型层做结构化。把候选片段喂给一个抽取提示词让它输出 JSON 格式的记忆条目字段包括类型、内容摘要、关键词、重要度。提示词我改了很多版核心是要求它只输出结论不输出过程。比如一段关于数据库选型的讨论最终记忆应该是“项目 X 选用 PostgreSQL理由是 JSON 支持和事务能力”而不是把整段讨论都存下来。EXTRACT_PROMPT 从以下对话片段中抽取值得长期记忆的信息。 只输出 JSON 数组每个元素包含 - type: decision | preference | pitfall | todo - summary: 一句话结论不超过 50 字 - keywords: 3-5 个关键词 - importance: 0.0-1.0 对话片段 {dialog} 抽取完还要做一次去重。我用的是“摘要向量相似度 关键词重叠”双重判断相似度超过阈值就合并保留新的、更新旧的访问时间。这一步能防止同一个决策被反复记录。3.2 向量化与索引构建向量化我用的是本地嵌入模型选型标准是体积小、速度快、中文支持好。没必要上大模型记忆条目的语义相对简单小模型足够。索引构建有个细节要注意摘要和原文分开编码。摘要用于召回匹配原文用于注入上下文。召回时用摘要向量算相似度命中后再取原文。这样既保证了匹配精度又避免了长文本编码的噪声。索引更新我用的是增量方式。新记忆写入时同步生成向量并插入索引不重建全量。删除或合并时做软删除标记定期比如每周做一次全量整理清理无效条目、重建索引。全量整理放在低峰期跑避免影响正常使用。3.3 上下文注入怎么把记忆塞回对话注入是最讲究技巧的一步。塞太多模型注意力被稀释塞太少记忆没起作用。我的做法是分层注入 预算控制。先算预算。假设模型上下文窗口是 N token我预留 30% 给记忆剩下给当前对话和系统提示。然后按优先级填充长期记忆里的高重要度条目优先工作记忆次之短期记忆最后。填到预算用完为止。注入格式也很关键。我用的是带标签的结构化文本而不是直接拼接[记忆-决策] 项目使用 PostgreSQL理由是 JSON 支持和事务能力2024-01-15 [记忆-偏好] 代码风格用 4 空格缩进不用 tab2024-01-20 [记忆-坑] 库 X 的 2.3 版本有内存泄漏升级到 2.42024-02-01标签让模型能快速识别记忆类型做出差异化处理。实测下来这种结构化注入比纯文本拼接的召回利用率高不少。3.4 生命周期管理记忆的增删改查记忆不是只增不减的。我设了几条清理规则。过期清理工作记忆超过 14 天未访问自动降级为归档状态不再参与召回但保留在库里备查。合并压缩同一主题下超过 5 条记忆时触发一次摘要合并把多条压成一条更精炼的。比如关于某个库的多个坑合并成一条“库 X 的已知问题清单”。冲突检测新记忆写入时检查是否与旧记忆矛盾。比如旧记忆说“用方案 A”新记忆说“改用方案 B”这时标记旧记忆为失效并在新记忆里注明“替代了 XX 决策”。这个机制能防止模型拿到过时信息。手动干预提供简单的命令行工具能查、能删、能改。自动化再强也得给人留个后门否则出了错没法收拾。4. 实操落地从零搭一套可用的记忆层4.1 环境准备与依赖安装先把基础环境搭起来。我用的是 Python 3.11依赖不多核心就几个。pip install sqlite-vec sentence-transformers pyyamlsqlite-vec是 SQLite 的向量扩展轻量且够用。sentence-transformers用来做本地嵌入选paraphrase-multilingual-MiniLM-L12-v2这个模型体积小、中文效果可接受。pyyaml用来管配置。目录结构我建议这样组织claude-mem/ ├── config.yaml ├── memory.db ├── extractor.py ├── retriever.py ├── injector.py └── cli.pymemory.db就是 SQLite 单文件跟着项目走。配置文件里放模型路径、权重参数、预算比例这些可调项。4.2 数据库表结构设计表结构我设计得比较克制字段不多但够用。CREATE TABLE memories ( id INTEGER PRIMARY KEY, project TEXT NOT NULL, type TEXT NOT NULL, summary TEXT NOT NULL, content TEXT, keywords TEXT, importance REAL DEFAULT 0.5, embedding BLOB, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_access TIMESTAMP, access_count INTEGER DEFAULT 0, status TEXT DEFAULT active );project字段做项目隔离不同项目的记忆互不干扰。status管生命周期active、archived、invalid 三态。embedding存向量 blob配合 sqlite-vec 做相似度查询。建索引的时候project和status上各建一个普通索引created_at上建一个复合查询时能快不少。4.3 抽取模块的完整实现抽取模块是整个流程的入口我把它写成一个独立函数输入对话文本输出记忆条目列表。import re import json TRIGGER_PATTERNS [ r记住, r别忘, r以后都, r约定, r决定用, r别用, r有坑, r我习惯, r我喜欢 ] def should_extract(text): for p in TRIGGER_PATTERNS: if re.search(p, text): return True return False def extract_memories(dialog, llm_client): if not should_extract(dialog): return [] resp llm_client.complete(EXTRACT_PROMPT.format(dialogdialog)) try: items json.loads(resp) except json.JSONDecodeError: return [] return [it for it in items if it.get(summary)]这里有个实操心得规则初筛的触发词要定期维护。用一段时间后你会发现某些表达频繁出现但没被捕获比如“这个方案定了”“就按这个来”把它们加进模式列表召回率会明显提升。4.4 召回与注入的串联召回函数接收当前对话文本返回排序后的记忆列表。def recall(query, project, top_k8, budget_tokens2000): q_vec embed(query) candidates db.query( SELECT * FROM memories WHERE project? AND statusactive, (project,) ) scored [] for m in candidates: sim cosine(q_vec, m[embedding]) age_days (now() - m[created_at]).days decay 0.5 ** (age_days / 30) score 0.5*sim 0.2*decay 0.2*m[importance] 0.1*min(m[access_count]/10, 1) scored.append((score, m)) scored.sort(reverseTrue, keylambda x: x[0]) selected, used [], 0 for score, m in scored: cost len(m[summary]) // 2 if used cost budget_tokens: break selected.append(m) used cost return selected注入函数把选中的记忆格式化成带标签的文本块拼到系统提示后面。注意标签要统一别一会儿中文一会儿英文模型会困惑。4.5 命令行工具的日常使用我写了个简单的 CLI日常操作就靠它。python cli.py add --project myapp --type decision --summary 选用 PostgreSQL python cli.py search --project myapp --query 数据库选型 python cli.py list --project myapp --type pitfall python cli.py clean --project myapp --older-than 90add用于手动补录有时候自动抽取漏了手动加一条。search用来验证召回效果看看某条记忆能不能被正确检索到。clean定期跑清理过期和无效条目。5. 踩坑实录与常见问题排查5.1 召回不准的三种典型情况情况一召回了无关的旧记忆。原因通常是语义相似度阈值太低或者项目隔离没做好。排查方法是打印召回结果的分数明细看是哪一项拉高了总分。如果是相似度虚高调高阈值或换嵌入模型如果是项目串了检查project字段是否写入正确。情况二该召回的没召回。多半是写入时摘要写得太抽象或者关键词没覆盖到查询用的表达。解决办法是在抽取提示词里强调“摘要要包含具体名词”比如写“选用 PostgreSQL”而不是“选了数据库”。另外可以给记忆加同义词扩展查询时自动匹配。情况三召回了但模型没用。这是注入格式的问题。如果记忆块和当前对话混在一起没有明显边界模型容易忽略。用明确的标签和分隔符实测能显著提升利用率。5.2 记忆库膨胀的处理用久了记忆库会变大我遇到过三个月涨到几万条的情况。这时候要做分级处理。先看访问频次access_count为 0 且超过 60 天的直接归档。然后看类型todo 类过期就删decision 类保留但压缩。压缩用模型做摘要合并把同一主题的多条压成一条。我一般每月跑一次全量整理整理完记忆库能瘦身 40% 左右召回速度明显回升。5.3 多项目并行的隔离问题如果你同时维护多个项目隔离一定要做好。我的做法是物理隔离加逻辑隔离双保险。物理上每个项目一个独立的 db 文件逻辑上project字段再做一层过滤。这样即使某个项目配置错了也不会污染其他项目。跨项目共享的记忆单独放一个shared库比如通用的代码规范、常用工具配置这些。召回时先查项目库再查共享库合并排序。5.4 常见问题速查表问题现象可能原因排查方向解决手段召回结果全是旧记忆时效衰减权重过低检查 decay 参数调高时效权重或缩短半衰期记忆写入重复去重阈值太松看相似度分数分布收紧阈值加关键词重叠判断注入后模型答非所问记忆块格式混乱检查标签一致性统一标签加分隔符检索速度变慢索引未更新或库过大看查询耗时重建索引跑清理中文记忆召回差嵌入模型中文弱测试中文相似度换多语言模型5.5 几个我踩过的具体坑坑一时间戳时区混乱。早期我用本地时间存created_at结果跨时区协作时排序全乱。后来统一用 UTC 存储展示时再转本地问题解决。坑二向量维度不匹配。换嵌入模型时忘了重建索引新旧向量维度不一致查询直接报错。教训是换模型必须全量重建没有捷径。坑三过度依赖自动抽取。有段时间我完全信任自动抽取结果发现重要的口头约定经常漏掉。后来加了手动补录的习惯每周花十分钟过一遍本周对话把漏的补上记忆质量稳定了很多。坑四忽略记忆的“遗忘”。一开始我什么都想记结果记忆库成了垃圾场。后来想明白了记忆的价值在于精而不在于多主动遗忘和主动记忆同样重要。6. 效果验证与持续优化6.1 怎么衡量记忆层有没有用别凭感觉用数据说话。我跟踪三个指标。召回命中率随机抽 50 条记忆看它们在相关查询中能否被召回。低于 70% 说明检索有问题。注入利用率观察模型在回答中是否引用了注入的记忆。可以人工标注也可以看回答里是否出现了记忆中的关键词。低于 30% 说明注入格式或预算有问题。重复解释次数统计每周需要重复说明同一偏好的次数。这个数字应该持续下降如果没降说明记忆没生效。6.2 参数调优的实操方法参数没有万能值得根据自己的使用习惯调。我的方法是固定其他参数单变量扫描。比如调时效衰减的半衰期从 7 天到 90 天扫一遍每次跑一组标准查询看召回结果的人工评分。找到峰值后固定再调下一个参数。整个过程大概两小时但调完之后效果提升明显。权重方面语义相似度是主力别低于 0.4。重要度和时效性各占 0.2 左右比较均衡。访问频次权重别太高0.1 足够否则会形成马太效应热门记忆越来越热冷门好记忆永远出不来。6.3 后续可以扩展的方向这套东西跑通之后能扩展的地方不少。记忆可视化做一个简单的 Web 界面把记忆库按类型、时间、项目画成图直观看到知识沉淀的过程。团队共享协议把记忆库做成可合并的格式团队成员各自维护定期合并去重形成团队级记忆。自动摘要进化定期用更强的模型对记忆库做一次“重摘要”把零散记忆提炼成更高层的知识。与工作流集成把记忆层接到代码编辑器、任务管理工具里在写代码、建任务时自动带出相关记忆真正做到无感使用。我个人在实际操作中的体会是记忆层这东西前期投入大后期回报高。头两周搭架子、调参数确实费劲但一旦跑顺每天省下的重复解释时间、避免的上下文丢失事故远超投入。而且记忆库本身会随着使用越来越值钱它记录的不只是信息是你和 AI 协作的完整轨迹。最后分享一个小技巧每周花十分钟翻一遍本周新增的记忆你会发现很多自己都没意识到的决策模式这本身就是一种复盘。