1. 项目概述:为Claude Code构建持久化记忆

每次打开Claude Code,都像是面对一个初次见面的助手。你得重新解释一遍项目结构:“后端API在 /api 目录下,前端用Vue 3,数据库是PostgreSQL,别再用MongoDB了。”昨天花了两小时调试的认证逻辑、上周定下的代码规范、那个你特别讨厌的第三方库——所有这些上下文,在新会话开始时都消失得无影无踪。这种重复劳动不仅浪费时间,更打断了深度工作的心流。

这正是 claude-mem 要解决的核心痛点。这个开源项目在发布48小时内就获得了46K的GitHub星标,因为它戳中了每个使用AI编程助手的开发者的痒点:如何让AI记住过去,成为真正理解你项目脉络的协作伙伴。我不仅安装体验了 claude-mem ,还在发现它之前,自己动手用两个PowerShell脚本搭建了一个轻量级的替代方案。本文将带你深入两者的架构、实现细节,并分享我在实际项目中构建的三层记忆体系实战经验。

无论你是独立开发者,还是团队协作,理解如何为Claude Code注入记忆,都能显著提升你的开发效率,让AI从一次性的代码生成器,转变为伴随项目成长的智能伙伴。

2. claude-mem深度解析:从安装到架构

2.1 claude-mem是什么?不仅仅是记忆插件

claude-mem 本质上是一个为Claude Code设计的记忆中间件。它不像传统插件那样直接修改编辑器行为,而是通过拦截和分析你与Claude Code的交互,构建一个可查询的记忆库。其核心价值在于“相关性检索”——它不仅能存储信息,还能在你提出问题时,智能地找出与之最相关的历史上下文。

它的工作原理基于一套精心设计的生命周期钩子(Lifecycle Hooks)系统。Claude Code在执行关键操作(如会话开始、用户提交提示、工具使用后等)时会触发这些钩子, claude-mem 则作为监听者捕获这些时刻的数据。捕获的原始数据(可能是冗长的终端输出或新文件内容)会经过压缩处理,然后被存储到一个混合检索数据库中,供未来会话查询使用。

2.2 核心架构拆解:五大组件如何协同工作

理解 claude-mem 的架构,有助于你判断它是否适合你的工作流,以及在出现问题时如何排查。

2.2.1 生命周期钩子:记忆的触发点

这是 claude-mem 的“传感器网络”。它注册了五个关键钩子:

  • SessionStart & SessionEnd :标记会话边界,用于初始化上下文和进行会话后清理。
  • UserPromptSubmit :在你每次向Claude发送消息时触发,记录你的意图和问题。
  • PostToolUse :这是最核心的钩子。每当Claude Code执行一个“工具”(如运行Bash命令、写入文件)后,它会立即捕获该工具的输出。这是构建“我做了什么”记忆的主要来源。
  • Stop :处理会话意外终止的情况,确保数据不丢失。

这些钩子确保了记忆的捕获是自动且无缝的,你无需改变任何操作习惯。

2.2.2 存储与检索引擎:SQLite + Chroma的混合策略

记忆的存储不是简单的文本堆积。 claude-mem 采用了混合检索策略:

  • SQLite :存储结构化的元数据,如会话ID、时间戳、工具类型、原始内容哈希等。它负责快速的精确匹配和关系查询。
  • Chroma :这是一个轻量级向量数据库。所有捕获的文本内容都会被转换为向量(即一组数字,表征语义)。当你后续提问“我之前是怎么处理用户认证的?”时, claude-mem 会将这个问题也转换为向量,并在Chroma中查找语义最相似的历史记录。这实现了超越关键词匹配的“理解”能力。

这种混合设计兼顾了效率与智能。SQLite处理“什么时候、谁、做了什么”这类事实查询,而Chroma处理“像什么、相关什么”这类语义查询。

2.2.3 Bun HTTP Worker:本地服务中枢

claude-mem 并非一个静态库,而是一个常驻的本地服务。它使用Bun运行时启动一个HTTP服务(默认在 localhost:37777 )。这个服务负责:

  • 接收来自Claude Code钩子的数据。
  • 调用LLM进行内容压缩(如果需要)。
  • 与SQLite和Chroma数据库交互,执行存储和查询。
  • 提供Web UI的后端接口。

选择Bun而非Node.js,主要是看中其更快的启动速度和更现代的API,这对于一个需要常驻、快速响应的本地服务很重要。

2.2.4 MCP工具层:渐进式信息获取

MCP(Model Context Protocol)是Anthropic推出的一套标准,用于让模型安全、可控地使用外部工具。 claude-mem 通过MCP向Claude Code暴露了三个工具,采用“渐进式披露”设计:

  1. search_memories :最常用的工具。Claude在回答你的问题前,可以主动用此工具查询相关记忆。例如,你问“我们项目的API路由结构是怎样的?”,Claude会先调用此工具搜索历史记录中关于“API”、“路由”的记忆,再将结果作为上下文融入回答。
  2. get_timeline :获取按时间排序的活动摘要,用于快速回顾“我过去几天做了什么”。
  3. get_observations :获取更详细的、经过LLM压缩后的观察记录(Observations)。

这种设计避免了每次都将所有记忆塞给模型,而是按需、精准地提供,节省了宝贵的上下文窗口。

2.2.5 Web UI:记忆的可视化仪表盘

通过访问 http://localhost:37777 ,你可以打开一个独立的浏览器窗口,查看所有捕获的记忆。这个仪表盘支持按时间、会话、工具类型过滤,并且可以直接进行语义搜索。这对于进行项目复盘、寻找特定代码片段、或者单纯了解AI助手“记住”了什么非常有用。它让记忆从黑盒变成了可审计、可管理的数据资产。

2.3 实战安装与配置指南

安装过程看似简单,但有几个细节决定了使用体验。

2.3.1 基础安装步骤

# 1. 安装claude-mem本身
npx claude-mem install
# 这个命令会下载claude-mem,并将其配置为Claude Code的插件。

# 2. 启动记忆服务
npx claude-mem start
# 这会启动Bun HTTP服务。你会看到输出提示服务运行在37777端口。

注意 : npx claude-mem start 会启动一个前台进程。如果你关闭终端,服务就会停止。对于长期使用,建议配置为后台服务或开机自启。

2.3.2 关键配置调优:成本与效果平衡

默认配置下, claude-mem 会使用Claude API来压缩(Summarize)捕获的冗长工具输出(如大段的终端日志),将其变成简明的“观察记录”。这虽然效果好,但会消耗你的Claude API额度。

强烈建议切换到免费的Gemini API进行压缩 :

  1. 前往Google AI Studio (aistudio.google.com) 申请一个免费的API密钥。
  2. 找到 claude-mem 的配置文件。通常位于 ~/.claude-mem/settings.json (Linux/macOS)或 %USERPROFILE%\.claude-mem\settings.json (Windows)。
  3. 编辑该文件,添加或修改如下配置:
{
  "CLAUDE_MEM_PROVIDER": "gemini",
  "CLAUDE_MEM_GEMINI_API_KEY": "你的_google_ai_studio_api_key_here",
  "CLAUDE_MEM_COMPRESSION_MODEL": "gemini-1.5-flash" // 推荐使用flash模型,速度快,免费额度足够
}
  1. 重启 claude-mem 服务。

这个改动能将运行成本降至零。Gemini 1.5 Flash模型对于文本压缩任务效果足够好,且免费配额对于个人开发者的使用频率而言绰绰有余。

2.3.3 验证安装是否成功 安装并启动后,你可以通过以下方式验证:

  1. 打开Claude Code,像平常一样操作,比如运行一个 ls 命令或创建一个新文件。
  2. 打开Web UI ( localhost:37777 ),你应该能看到刚刚的操作被记录为一条“Observation”。
  3. 在Claude Code中,直接提问:“我今天都创建了哪些文件?” 或 “我之前修改过 package.json 吗?”。如果Claude的回答中引用了具体的历史操作(例如“根据记录,你在上午10:15创建了 utils/helper.js 文件”),则说明 claude-mem 的MCP工具集成成功。

3. 轻量级DIY替代方案:手搓记忆系统

在了解到 claude-mem 之前,我被Claude Code的“失忆症”困扰,决定用最直接的方式解决。我的需求很明确:极简、零依赖、文件可读、能与团队通过Git共享。于是,我用两个PowerShell脚本和Claude Code的原生钩子API,搭建了一个轻量级记忆系统。

3.1 设计思路:聚焦关键事件,格式化为知识

我的核心洞察是:并非所有交互都需要记忆。对于编程会话,最有价值的记忆锚点是 代码变更 。而代码变更主要体现在两个地方:

  1. Git提交 :每一次 git commit 都代表一个逻辑完整的功能点、修复或重构。提交信息本身就是极佳的记忆摘要。
  2. 新建文件 :通过 Write 工具创建新文件,标志着项目结构的扩展或新模块的开始。

因此,我的DIY系统只捕获这两类事件,并将它们以纯文本Markdown格式,按日期记录到文件中。这样产生的记忆文件,人类和机器都能轻松阅读,也完美契合版本控制系统。

3.2 核心实现:两个脚本的魔法

3.2.1 自动捕获脚本: auto-capture.ps1

这个脚本由 PostToolUse 钩子触发。它的逻辑是:

  1. 判断工具类型 :检查刚执行完的工具是 Bash 还是 Write 。
  2. 针对Git提交 :如果是 Bash ,并且命令以 git commit 开头,则解析提交哈希和提交信息。
  3. 针对新建文件 :如果是 Write ,则获取被创建的文件路径。
  4. 写入日志 :将上述信息,连同当前时间,追加到以当天日期命名的Markdown文件中。
# auto-capture.ps1
param($eventData) # Claude Code会将工具使用事件的数据作为参数传入

$logDir = ".\memory\auto-capture\"
if (-not (Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir -Force }

$todayFile = Join-Path $logDir "$(Get-Date -Format 'yyyy-MM-dd').md"

# 解析eventData (JSON格式),获取工具类型和输出
$toolCall = $eventData | ConvertFrom-Json
$toolName = $toolCall.toolName
$output = $toolCall.output?.content?.text

$timestamp = Get-Date -Format "HH:mm"

if ($toolName -eq "Bash" -and $output -match "^git commit") {
    # 简单解析git提交哈希和消息(实际脚本会更健壮,处理多行消息等)
    if ($output -match '\[(?<hash>[a-f0-9]+)\]?\s*(?<msg>.+)') {
        $hash = $matches['hash'].Substring(0,7) # 取短哈希
        $msg = $matches['msg'].Trim()
        $logEntry = "- $timestamp [$hash] $msg"
        Add-Content -Path $todayFile -Value $logEntry
    }
}
elseif ($toolName -eq "Write") {
    # 解析写入的文件路径。Claude Code的Write输出通常包含路径。
    if ($output -match '`(.+?)`') {
        $filePath = $matches[1]
        $logEntry = "- $timestamp [Write] $filePath"
        Add-Content -Path $todayFile -Value $logEntry
    }
}

这个脚本运行后,你的 memory/auto-capture/ 目录下会产生如 2024-06-15.md 的文件,内容类似:

- 09:15 [abc1234] feat: Add user authentication middleware
- 09:32 [Write] lib/auth_middleware.dart
- 10:01 [def5678] fix: Token refresh logic in auth provider
- 11:20 [Write] test/auth_middleware_test.dart

3.2.2 会话恢复脚本: session-resume.ps1

这个脚本由 SessionStart 钩子触发。它的任务是在新会话开始时,将最近的记忆“喂”给Claude,作为初始上下文。

# session-resume.ps1
$logDir = ".\memory\auto-capture\"
if (-not (Test-Path $logDir)) {
    Write-Output "No memory directory found. Starting fresh."
    exit
}

# 获取最近3天的记忆文件
$files = Get-ChildItem -Path $logDir -Filter "*.md" | Sort-Object LastWriteTime -Descending | Select-Object -First 3

$context = "# Recent Project Activity`n`n"
foreach ($file in $files) {
    $date = $file.BaseName
    $content = Get-Content $file.FullName -Raw
    if ($content) {
        $context += "## $date`n$content`n`n"
    }
}

# 将上下文输出到标准输出,Claude Code会捕获并注入到新会话中。
Write-Output $context

当新Claude Code会话启动时,它会自动执行这个脚本,并将输出内容作为系统提示的一部分。于是,Claude一开场就会说:“我看到你最近三天在忙用户认证功能,创建了 auth_middleware.dart ,提交了关于token刷新的修复……” 这种无缝的上下文恢复体验,瞬间提升了协作的连贯性。

3.2.3 钩子注册:让Claude Code调用你的脚本

你需要编辑Claude Code的配置文件(通常位于用户目录下的 .claude 或Claude Code设置中),将这两个脚本注册到对应的钩子上。

// 在Claude Code的settings.json或类似配置文件中添加
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Bash|Write", // 只匹配Bash和Write工具
        "hooks": [
          {
            "type": "command",
            "command": "powershell -ExecutionPolicy Bypass -File C:/path/to/your/auto-capture.ps1"
          }
        ]
      }
    ],
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "powershell -ExecutionPolicy Bypass -File C:/path/to/your/session-resume.ps1"
          }
        ]
      }
    ]
  }
}

注意 :确保提供PowerShell脚本的绝对路径,并设置 -ExecutionPolicy Bypass 参数以避免脚本执行策略的阻拦。在macOS或Linux上,你需要将脚本转换为Shell脚本(.sh),并使用相应的解释器(如 bash )。

3.3 DIY方案的优劣与适用场景

优势:

  • 零成本与零依赖 :无需安装任何额外服务(Bun, Chroma),不调用任何外部API,完全离线运行。
  • 极简透明 :所有记忆都是纯文本Markdown文件,你可以用任何编辑器查看、搜索(用 grep 或VS Code全局搜索)、甚至手动编辑。
  • Git友好 : memory/ 目录可以直接加入版本控制。团队成员拉取代码后,也就拉取了项目的“集体记忆”,新成员能快速了解项目近期动态。
  • 完全可控 :你可以精确决定捕获什么(例如,可以修改脚本只捕获特定路径下的文件创建,或忽略某些类型的提交)。

劣势:

  • 功能有限 :只有基于时间的简单检索(最近N天),缺乏 claude-mem 的语义搜索能力。你无法直接问“关于错误处理我们做过什么?”,只能自己浏览文件或进行关键词全文搜索。
  • 无压缩 :记录的是原始信息(提交信息、文件路径),对于冗长的终端输出无法进行智能摘要。
  • 无Web界面 :查看记忆需要打开文件浏览器和文本编辑器,体验上不如一个专门的仪表盘直观。

适用场景:

  • 个人开发者或小团队,追求极简主义。
  • 项目初期,记忆需求简单,主要是追踪文件变更和提交历史。
  • 对数据隐私和离线工作有严格要求的环境。
  • 作为理解Claude Code钩子机制和记忆系统原理的学习项目。

4. 双剑合璧:构建三层记忆架构实战

在实际工作中,尤其是参与一个中等规模的Flutter Web项目时,我发现单一的记忆方案无法满足所有需求。我和团队同时使用多个Claude Code实例(一个负责前端UI,一个负责后端逻辑,一个负责数据库设计),信息流复杂。为此,我们设计并实施了一个三层记忆架构,融合了 claude-mem 和DIY脚本的优势。

4.1 各层设计原理与工具选型

我们的核心思想是 分层缓存,各司其职 。将记忆分为会话内、会话间和项目间三个层次,分别用最合适的工具处理。

4.1.1 L1层:会话内实时记忆(claude-mem)

  • 工具 : claude-mem (SQLite + Chroma)
  • 目的 :捕获单次会话中所有细颗粒度的交互。例如,在调试一个复杂函数时,你可能会多次运行测试、查看日志、修改几行代码。 claude-mem 能实时记录这些步骤。当你在同一会话中稍后问“刚才那个错误是什么来着?”,它能立刻通过语义搜索找到相关的错误日志输出。
  • 配置要点 :我们为每个开发者的本地环境单独安装 claude-mem 。其数据库文件( .sqlite 和 chroma-data )被加入 .gitignore ,因为这是高度个人化、临时性的上下文,不适合共享。

4.1.2 L2层:会话间关键事件记忆(DIY Hooks)

  • 工具 :自定义PowerShell钩子脚本 + Markdown文件
  • 目的 :在会话之间传递 关键里程碑 信息。重点是Git提交和重要文件创建。这些信息结构化程度高、意义明确,且是团队协作的天然节点。当任何成员开启新会话时,都能自动加载最近几天团队整体的“关键事件摘要”。
  • 配置要点 :我们将 memory/auto-capture/ 目录纳入Git仓库。 session-resume.ps1 脚本被修改为读取该目录下所有Markdown文件(而不仅是本地三天),从而构建出团队的共享记忆。这相当于一个轻量级、自动更新的项目日志。

4.1.3 L3层:跨项目深度知识记忆(NotebookLM/其他知识库)

  • 工具 :NotebookLM、Obsidian、企业Wiki等
  • 目的 :存储超越单次开发会话的深度知识。包括项目架构决策文档、核心业务逻辑说明、第三方库深度研究笔记、性能优化报告等。这些是项目的“长期记忆”或“核心知识资产”。
  • 操作方式 :这不是自动化的。当我们在开发中产生值得沉淀的深度知识(例如,通过多次会话与Claude Code探讨后,确定了一套状态管理方案),我们会手动(或半自动)地将对话精华、最终代码片段和解释整理到NotebookLM或团队的共享文档中。在开始一个相关的新功能时,我们可以主动将这些文档作为上下文提供给Claude Code。

4.2 共存配置与避坑指南

让 claude-mem 和DIY钩子在同一Claude Code实例中和平共处,是可行的,因为它们的注册机制不同。

4.2.1 配置共存

  1. 安装 claude-mem :按照前述步骤,使用 npx claude-mem install 。这会将其注册为Claude Code的 插件 。
  2. 配置DIY钩子 :如前所述,在Claude Code的 settings.json 中手动配置 hooks 字段。
  3. 启动 :先启动 claude-mem 服务 ( npx claude-mem start ),再启动Claude Code。

Claude Code会同时加载插件系统的 claude-mem 和配置文件中的钩子。当 PostToolUse 事件发生时,两者会按某种内部顺序被触发,互不干扰。我们的实测中,DIY脚本记录Git提交, claude-mem 记录所有工具输出,两者并行不悖。

4.2.2 潜在冲突与解决

  • 事件重复处理 :如果DIY脚本和 claude-mem 都处理完全相同的工具事件,可能会导致重复记录。在我们的设计中,我们通过DIY脚本的 matcher 做了限制(只捕获 Bash 和 Write 中的特定模式),而 claude-mem 默认捕获所有,这实际上形成了互补而非冲突。
  • 性能影响 :同时运行两个钩子处理器,理论上会增加微小延迟。但在实际开发中,这种延迟(毫秒级)对于工具执行后的回调来说几乎无感。如果遇到性能问题,可以检查DIY脚本的效率,避免在其中进行复杂的同步网络请求或重型计算。
  • 上下文超载 : session-resume.ps1 注入的Markdown内容加上 claude-mem 通过MCP工具动态添加的记忆,可能会占用较多模型上下文。需要关注Claude Code的上下文窗口限制。我们的策略是:DIY脚本只提供最近3天的关键事件摘要(精简列表),而 claude-mem 的搜索是精准、按需的,从而控制总上下文量。

4.3 实战工作流示例

假设我们正在开发一个“用户上传头像”的功能。

  1. 会话开始 :我打开Claude Code。 session-resume.ps1 自动运行,将最近几天团队关于“用户配置”、“文件存储”的Git提交摘要注入上下文。Claude开场白:“我看到你们最近在完善用户配置页面,并讨论了云存储选项。”
  2. 会话中探索 :我让Claude帮我写一个图片压缩函数。过程中,我多次使用Bash运行测试、用Write创建了 image_processor.dart 和 image_processor_test.dart 。所有这些细碎的交互都被 claude-mem 实时记录到它的向量数据库中。
  3. 遇到问题 :测试失败,报了一个模糊的格式错误。我直接问Claude:“刚才运行 test image_processor 时具体的错误输出是什么?” Claude通过 claude-mem 的 search_memories 工具,找到了几分钟前的那条测试日志,并精准地引用给我。
  4. 完成功能 :功能开发完毕,我通过Bash执行 git commit -m "feat: add image compression and validation for avatar upload" 。这个提交事件被我的DIY钩子捕获,记录到 memory/auto-capture/2024-06-15.md 中。
  5. 沉淀知识 :在解决一个关于Dart图像库内存管理的棘手问题时,我和Claude进行了深入讨论。我将最终解决方案和原理总结复制到了团队的NotebookLM项目中,标题为“Flutter Web中高效处理用户上传图片的最佳实践”。
  6. 次日继续 :第二天,我或我的同事开启新会话。DIY钩子会提供“昨天添加了头像上传的图片压缩功能”这个关键节点。如果需要深入回忆压缩算法的具体实现细节,我们可以通过 claude-mem 的Web UI进行语义搜索,或者直接打开NotebookLM查看沉淀下来的深度文档。

这个工作流让记忆在不同时间维度和知识深度上流动起来,确保了信息的持续性和可用性。

5. 深度对比与决策指南

面对 claude-mem 和DIY方案,如何选择?下表从多个维度进行了详细对比,并附上了我的场景化建议。

特性维度 claude-mem DIY Hooks (PowerShell + Markdown)
核心能力 语义搜索 :能理解问题意图,找到相关记忆。
自动压缩 :用LLM提炼冗长输出为观察记录。
可视化仪表盘 :集中查看和搜索所有记忆。
关键词/时间线检索 :基于文件内容的简单文本搜索或按时间浏览。
原始记录 :保存未经加工的原始事件(提交信息、文件路径)。
文件系统视图 :记忆以普通文件形式存在,用任何编辑器管理。
安装与依赖 需要安装Node.js/Bun运行时,以及 claude-mem 本身。需要运行一个本地HTTP服务。 零依赖 。只需操作系统自带的脚本解释器(如PowerShell、Bash)和文本编辑器。无需常驻服务。
配置复杂度 相对简单,主要是一行安装命令和API密钥配置。Web UI开箱即用。 中等,需要手动编写脚本、理解Claude Code钩子API、编辑配置文件。
运行成本 潜在API成本 :默认使用Claude API压缩记忆,消耗token。可配置为免费Gemini API。 零成本 :完全离线运行,无任何API调用。
数据格式与共享 数据存储在二进制数据库文件(SQLite/Chroma)中,不易直接阅读和版本控制。适合个人使用。 纯文本Markdown ,人类可读, 天然适合Git 。团队可通过共享仓库轻松同步项目记忆。
可控性与扩展性 通过配置调整压缩模型、钩子过滤条件等,但核心逻辑是封装的。扩展需要修改其源代码。 完全可控 。你可以编写任何逻辑来决定捕获什么、如何格式化、存储到哪里。轻松扩展新的事件类型或输出格式。
适用场景 个人开发者或小团队,追求开箱即用的智能记忆和检索,需要语义搜索能力,不介意轻度依赖和配置。 极简主义者、对隐私和离线有强需求、希望记忆文件可版本控制并团队共享、享受动手定制过程的开发者。

5.1 决策流程图与建议

为了更直观地做出选择,你可以遵循以下决策路径:

  1. 首要问题:是否需要语义搜索?

    • 是 -> 选择 claude-mem 。这是它无法被简单脚本替代的核心优势。当你记不清具体关键词,只能用自然语言描述需求时(如“我之前是怎么优化那个慢查询的?”),语义搜索至关重要。
    • 否 -> 进入下一步。
  2. 次要问题:是否要求零依赖、数据完全可控并可Git共享?

    • 是 -> 选择 DIY方案 。它给你最大的透明度和控制权,特别适合纳入团队的标准开发流程。
    • 否 -> 进入下一步。
  3. 权衡问题:是否愿意为了便利性接受轻度依赖和配置?

    • 是 -> 可以尝试 claude-mem ,并按照前文指南配置免费Gemini API以消除成本顾虑。
    • 否 -> 选择 DIY方案 。

我的综合建议:采用渐进式策略 对于大多数开发者,我推荐一个“从简到繁”的路径:

  • 第一步:从DIY开始 。花一小时实现基础的Git提交和文件创建捕获。这能立即解决“上次会话做了什么”的失忆问题,成本为零,且能立刻体会到上下文延续带来的流畅感。这也是一个绝佳的学习过程,让你彻底理解记忆系统的工作原理。
  • 第二步:评估痛点 。使用DIY方案一段时间后,问自己:我是否经常需要搜索非关键词的具体对话内容?我是否觉得手动浏览Markdown文件低效?我是否希望AI能更主动地关联过去的讨论?
  • 第三步:引入claude-mem 。如果第二步的回答是肯定的,那么就是时候引入 claude-mem 了。此时你可以让两者共存。用DIY脚本管理团队共享的关键里程碑(L2记忆),用 claude-mem 管理个人会话内的细颗粒度记忆(L1记忆)。这样既保留了团队协作的透明性,又享受了智能检索的便利。
  • 第四步:建立L3知识库 。对于任何项目,都鼓励建立一个人工维护的深度知识库(如NotebookLM、Confluence页面)。将通过与Claude Code探讨得出的重要架构决策、解决方案沉淀下来。这是AI记忆无法替代的、结构化的团队智慧。

5.2 高级技巧与优化

对于claude-mem用户:

  • 钩子过滤 :在 ~/.claude-mem/settings.json 中,你可以配置 HOOK_INCLUDE_PATTERNS 或 HOOK_EXCLUDE_PATTERNS 来过滤哪些工具的输出需要被记录。例如,你可以忽略所有 ls 、 pwd 这样的简单命令,只记录 git , npm , docker 等有实质内容的命令,减少噪音。
  • 观察记录调优 :调整压缩LLM的提示词(Prompt),以生成更符合你阅读习惯的观察记录。这需要一些对 claude-mem 代码的修改能力。
  • 定期清理 : claude-mem 的数据库会随时间增长。可以设置一个定时任务,定期归档或清理过于陈旧的记忆,以保持检索速度。

对于DIY方案用户:

  • 增强捕获逻辑 :除了Git提交和文件创建,你可以考虑捕获:
    • 通过 Bash 运行的特定测试命令(如 npm test 、 pytest )及其结果摘要。
    • 通过 Write 工具修改的 特定重要文件 (如 package.json , pubspec.yaml )。
    • 在会话中由Claude生成的、你明确标记为“重要”的代码块(这需要更复杂的脚本交互)。
  • 改进检索 : session-resume.ps1 可以变得更智能。例如,它可以分析当前项目目录下的文件,如果发现正在打开一个关于 auth 的文件,就优先注入与认证相关的历史记忆,而不是简单的时间倒序。
  • 格式化美化 :将Markdown日志输出得更美观,加入表格、代码块等,提升可读性。

6. 常见问题与故障排查实录

在实际部署和使用这两种记忆方案的过程中,我遇到并解决了一系列典型问题。这里记录下最常遇到的几个坑及其解决方案。

6.1 claude-mem 常见问题

问题1:服务启动失败,提示端口占用或Bun错误。

  • 现象 :执行 npx claude-mem start 后,进程立刻退出,或报错 Address already in use 、 bun: command not found 。
  • 排查 :
    1. 检查端口: netstat -ano | findstr :37777 (Windows) 或 lsof -i :37777 (macOS/Linux)。如果37777端口被其他程序占用,可以在 settings.json 中修改 CLAUDE_MEM_PORT 配置。
    2. 检查Bun安装:运行 bun --version 。如果未安装,需要先安装Bun( curl -fsSL https://bun.sh/install | bash 或通过包管理器)。
    3. 查看详细日志:有时启动失败会有更详细的错误输出到控制台。确保在干净的终端中运行,并仔细阅读错误信息。
  • 解决 :根据排查结果,关闭占用端口的进程、安装Bun,或根据错误日志调整配置。

问题2:Claude Code似乎没有“记忆”,提问历史问题无反应。

  • 现象 :在Claude Code中提问关于过去操作的问题,Claude的回答没有引用任何历史记录。
  • 排查 :
    1. 检查服务状态 :首先确认 claude-mem 服务正在运行(Web UI localhost:37777 能否打开)。
    2. 检查插件连接 :在Claude Code的设置中,查看已安装插件列表,确认 claude-mem 插件已启用。
    3. 检查MCP工具 :在Claude Code会话中,尝试直接让Claude使用工具,例如输入:“请搜索一下我今天的记忆。” 观察Claude是否会调用 search_memories 工具。如果它不知道这个工具,说明MCP连接可能有问题。
    4. 检查Web UI :打开Web UI,看看是否有最近的记忆被记录。如果没有,说明钩子没有正确捕获事件。
  • 解决 :
    • 重启 claude-mem 服务和Claude Code。
    • 重新运行 npx claude-mem install 以确保插件正确注册。
    • 检查Claude Code的配置,确保没有禁用MCP或插件功能。

问题3:记忆压缩消耗了大量API Token,成本激增。

  • 现象 :发现Claude API的使用量异常高。
  • 排查 :检查 claude-mem 的配置文件,确认 CLAUDE_MEM_PROVIDER 设置。如果它是 claude 或未设置,并且你进行了大量产生长文本输出的操作(如运行测试套件、安装大量依赖),就会触发频繁的LLM压缩调用。
  • 解决 :如前文所述, 立即切换到Gemini免费API 。如果仍想使用Claude,可以尝试调整 CLAUDE_MEM_COMPRESSION_MODEL 为更小、更便宜的模型(如 claude-3-haiku ),并严格设置钩子过滤模式,避免对无关紧要的输出进行压缩。

6.2 DIY钩子脚本常见问题

问题1:PowerShell脚本无法执行,提示执行策略错误。

  • 现象 :Claude Code启动时报错,或钩子事件后无任何记录。
  • 排查 :在PowerShell中直接运行你的脚本文件,看是否报错“无法加载文件...,因为在此系统上禁止运行脚本”。
  • 解决 :有两种方法:
    1. (推荐)在命令中绕过 :在 settings.json 的 command 中,始终使用 powershell -ExecutionPolicy Bypass -File ... 。
    2. 修改执行策略 :以管理员身份打开PowerShell,运行 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser 。但这降低了安全性。

问题2:脚本执行了,但Markdown文件没有内容或格式错误。

  • 现象 : memory/ 目录下生成了文件,但内容是空的,或者不是预期的Markdown列表。
  • 排查 :
    1. 添加日志 :在脚本开头和关键逻辑处,使用 Write-Output "Debug: ..." 或 Add-Content -Path "debug.log" -Value "..." 输出调试信息,查看 $eventData 的实际结构。
    2. 检查事件数据 :Claude Code传递给钩子的 $eventData JSON结构可能因版本而异。确保你的脚本正确解析了 toolName 和 output 字段。最可靠的方法是先打印出完整的 $eventData 看看。
    3. 检查路径和权限 :确保脚本有权限在目标目录创建和写入文件。使用绝对路径。
  • 解决 :根据调试信息修正解析逻辑。确保脚本对 $eventData 的解析是健壮的,例如使用 Select-String 或更复杂的正则表达式来匹配git提交信息。

问题3:SessionStart钩子注入的上下文过长,影响Claude响应。

  • 现象 :新会话启动慢,或者Claude的响应开始变得迟缓、不完整。
  • 排查 :检查 session-resume.ps1 输出的内容大小。如果记忆文件积累了几个月,一次性注入可能占用大量上下文令牌。
  • 解决 :修改脚本逻辑,限制注入的内容。例如:
    • 只注入最近7天(而非3天)的记忆。
    • 对每条记忆进行字数截断(例如,只取提交信息的前50个字)。
    • 更智能地,只注入与当前打开的项目目录或文件可能相关的记忆(这需要更复杂的脚本分析)。

6.3 通用问题与优化

问题:两者共存时,感觉Claude Code变慢了。

  • 分析 :每个 PostToolUse 事件都会触发两个处理程序( claude-mem 的服务调用和你的DIY脚本执行)。如果DIY脚本逻辑复杂或 claude-mem 服务响应慢,可能会有感知延迟。
  • 优化 :
    1. 精简DIY脚本 :确保脚本逻辑高效,避免同步的、耗时的操作(如网络请求)。
    2. 异步执行 :如果可能,将DIY脚本设计为异步执行(例如,只将事件放入一个队列,由另一个后台进程处理),避免阻塞Claude Code的主线程。但这需要更复杂的架构。
    3. 评估必要性 :如果 claude-mem 已经满足了大部分需求,可以考虑简化或停用DIY的 PostToolUse 钩子,只保留 SessionStart 钩子用于加载共享记忆。

问题:记忆包含了敏感信息(如API密钥、密码)。

  • 风险 :无论是 claude-mem 的数据库还是DIY的Markdown文件,如果捕获了终端中回显的敏感信息,都可能造成泄露。
  • 防护 :
    1. 钩子过滤 :在 claude-mem 中配置 HOOK_EXCLUDE_PATTERNS ,排除包含 password 、 api_key 、 secret 等关键词的命令行。在DIY脚本中,增加逻辑过滤掉包含敏感信息的行。
    2. 环境变量 :始终使用环境变量管理敏感信息,避免在命令行中直接输入。
    3. 定期审查 :定期检查记忆存储的内容,手动清理可能的敏感信息。对于 claude-mem ,可以通过Web UI进行搜索和删除。

记忆系统的构建是一个持续迭代的过程。无论是选择功能强大的 claude-mem ,还是灵活可控的DIY方案,抑或是将两者结合,其最终目的都是打破AI助手“金鱼脑”的局限,让它真正成为你项目旅程中一个持久的、不断进化的伙伴。从今天开始,尝试为你的Claude Code注入第一段记忆吧,你会发现,那些曾经需要反复解释的上下文,将自然而然地成为你们之间默契的基石。

更多推荐