跳到主要内容

Claude Code 的"记忆"是什么?memdir 设计理念

🟢 入门

引言:AI 的遗忘问题

大语言模型有一个本质的限制:每次对话都是独立的。昨天告诉 Claude "我们团队不用 Jest,用 Vitest",今天打开新会话,它又不记得了。你需要不断重复解释上下文,这是一种低效的协作方式。

Claude Code v2.1.88 引入了 memdir 记忆系统,目标是让 AI 助手真正拥有跨会话的持久记忆。这篇文章将解释这套系统的设计理念和整体架构。

两种"记忆"的根本区别

在理解 memdir 之前,需要先区分两种截然不同的记忆形式:

会话内上下文(Session Context)

在单次对话中,Claude 能"记住"本次对话的所有内容——这是 LLM 的 context window 机制。当你说"刚才那个函数有个 bug",Claude 知道你指的是哪个函数,因为它就在当前上下文里。

这种"记忆"是临时的:会话结束,上下文清空,一切归零。

跨会话持久记忆(Persistent Memory)

memdir 系统解决的是另一个问题:如何让 AI 在不同会话之间保留重要信息。

会话 A:  用户说 "我是后端工程师,主要写 Go"
→ Claude 将此写入记忆文件

会话 B: 用户问 "帮我看看这段代码"
→ Claude 读取记忆,知道用户是 Go 工程师
→ 用 Go 惯用语解释,不用从零介绍

以文件系统为记忆载体

memdir 最核心的设计决策:用普通文件(Markdown 文件)作为记忆的存储载体

这个选择看似简单,却有深刻的理由:

  1. 可读性:用户可以直接用文本编辑器查看、修改、删除记忆
  2. 可版本控制:团队记忆可以纳入 Git 管理
  3. 透明性:AI 做了什么记录,用户一目了然
  4. 可移植性:记忆文件可以备份、迁移

每条记忆都是一个独立的 .md 文件,包含 YAML frontmatter 元数据和正文内容:

---
name: user_is_go_engineer
description: 用户是后端工程师,主要使用 Go 语言,对 React 不熟悉
type: user
---

用户是有 10 年经验的 Go 工程师,首次接触这个项目的 React 前端部分。
在解释前端代码时,用后端类比(goroutine → async/await,interface → component props)。

**Why:** 用户明确告知 Go 背景,希望从已知知识出发理解新概念
**How to apply:** 每当解释前端概念时,优先使用 Go 的对应概念作为桥梁

记忆系统架构概览

记忆的三个层次

memdir 系统设计了三个层次的记忆,对应不同的共享范围:

个人记忆(Private Memory)

存储在 ~/.claude/projects/<项目路径>/memory/ 下,只有当前用户可见。

记录:

  • 用户的角色和技术背景
  • 个人工作偏好("不要用 mock,用真实数据库测试")
  • 用户给出的反馈和修正

项目记忆(Project Context Memory)

也存储在个人记忆目录下,但类型标注为 project,记录项目级别的上下文:

  • 当前进行中的工作和目标
  • 团队决策和技术选型的理由
  • 截止日期和里程碑
  • 已知的 bug 和技术债

团队记忆(Team Memory)

存储在 ~/.claude/projects/<项目路径>/memory/team/ 下,通过服务端同步在团队成员间共享。

记录:

  • 整个团队需要遵守的编码规范
  • 项目级别的技术决策
  • 共享的外部资源指针(Linear、Grafana 等)

与 CLAUDE.md 的关系和区别

很多用户可能已经了解 CLAUDE.md——在项目根目录放一个 Markdown 文件,Claude 会自动读取作为上下文。那么 memdir 系统和 CLAUDE.md 有什么区别?

维度CLAUDE.mdmemdir 记忆
写入者人类手动编写Claude 自动写入
内容性质静态的项目说明动态的交互积累
典型内容代码规范、架构说明用户偏好、项目进展
更新频率低(手动维护)高(每次对话后更新)
存储位置项目目录内~/.claude/ 外部
版本控制通常纳入 Git个人记忆不纳入 Git

源码中对这个区别有明确的说明:

// source/src/memdir/memoryTypes.ts
/**
* Memories are constrained to four types capturing context NOT derivable
* from the current project state. Code patterns, architecture, git history,
* and file structure are derivable (via grep/git/CLAUDE.md) and should NOT
* be saved as memories.
*/

核心原则:凡是可以通过读代码、读 Git 历史、读 CLAUDE.md 推导出来的信息,不应该存入记忆。记忆只存放"不可推导"的上下文——用户的个人特征、交互中形成的偏好、项目状态的当前快照。

目录结构实例

实际运行时,~/.claude/ 下的记忆目录结构如下:

~/.claude/
└── projects/
└── Users-admin-projects-myapp/ # 基于项目路径生成的键名
└── memory/
├── MEMORY.md # 索引文件(记忆目录)
├── user_role.md # 用户角色记忆
├── feedback_testing.md # 测试偏好反馈
├── project_migration.md # 当前项目迁移任务
├── reference_linear.md # Linear 项目指针
├── logs/ # 日志模式(KAIROS 功能)
│ └── 2026/
│ └── 04/
│ └── 2026-04-01.md
└── team/ # 团队记忆(TEAMMEM 功能)
├── MEMORY.md
└── team_coding_standards.md

记忆系统的设计哲学

memdir 的设计体现了几个重要的软件工程原则:

1. 可观察性(Observability)

记忆是透明的。用户随时可以 ls ~/.claude/projects/*/memory/ 查看所有记忆文件,没有黑箱。

2. 用户控制权(User Agency)

用户可以:

  • 直接编辑记忆文件
  • 使用 /forget 删除特定记忆
  • 通过环境变量 CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 完全禁用记忆
  • 在 settings.json 中配置 autoMemoryEnabled: false

3. 安全第一(Security First)

路径验证、symlink 检测、路径穿越防护——teamMemPaths.ts 中有大量安全相关代码,确保团队记忆不会被恶意项目利用来读写敏感目录。

4. 渐进降级(Graceful Degradation)

记忆系统的每个功能都有独立的 feature flag 控制(TEAMMEMKAIROSEXTRACT_MEMORIES 等),新功能可以通过 GrowthBook 远端配置逐步推送,出问题时可以快速关闭。

小结

memdir 是 Claude Code 从"无状态工具"向"有记忆助手"演化的关键基础设施。它的设计理念可以用一句话概括:

用文件系统作为记忆的载体,用 AI 模型的判断力决定什么值得记忆,用结构化分类确保记忆的可用性。

接下来的文章将深入每个模块的实现细节。

📄source/src/memdir/memoryTypes.tsL1-21查看源码 →
📄source/src/memdir/paths.tsL22-94查看源码 →
📄source/src/memdir/memdir.tsL34-48查看源码 →