Claude Code 记忆系统设计调研报告
基于
/Users/wufan/workspace/claude-code源码分析调研日期:2026-04-10
1. 架构概览
Claude Code 采用 基于文件系统的分层记忆架构,记忆以 Markdown 文件形式存储,通过 frontmatter 元数据进行分类,由 LLM 自身负责记忆的创建和管理。核心设计哲学是"让 LLM 成为记忆系统的操作者"——通过 system prompt 中的详细指令引导模型读写记忆文件。
核心模块

2. 存储架构
2.1 作用域层级
~/.claude/ # 用户全局目录├── projects/{sanitized-git-root}/│ └── memory/ # 项目级私有记忆(核心)│ ├── MEMORY.md # 索引文件,始终加载到 system prompt│ ├── user_role.md # 独立记忆文件│ ├── feedback_testing.md│ ├── project_deadline.md│ └── team/ # 团队共享记忆(可选特性)│ ├── MEMORY.md│ └── ...├── agent-memory/{agentType}/ # 跨项目的代理专用记忆└── CLAUDE.md # 用户全局指令(非记忆,但互补){project}/├── .claude/│ ├── agent-memory/{agentType}/ # 项目内代理记忆│ └── agent-memory-local/{agentType}/ # 不纳入版本控制的代理记忆├── CLAUDE.md # 项目级指令└── CLAUDE.local.md # 个人本地指令路径解析 (src/memdir/paths.ts): - getAutoMemPath() — 返回 ~/.claude/projects/{sanitized-git-root}/memory/,已 memoize - getAutoMemEntrypoint() — 返回 MEMORY.md 路径 - getTeamMemPath() — 返回 team/ 子目录路径启用逻辑 (isAutoMemoryEnabled()): 1. 环境变量 CLAUDE_CODE_DISABLE_AUTO_MEMORY 优先级最高 1. --bare 模式强制禁用 1. CCR(Cloud Code Runner)无持久存储时禁用 1. settings.json 中的 autoMemoryEnabled 字段 1. 默认启用
2.2 单条记忆的数据格式
每条记忆是一个独立的 .md 文件,使用 YAML frontmatter:
---name: user-role-and-expertisedescription: 用户是有 10 年 Go 经验但第一次做 React 的工程师type: user---用户是一位资深后端工程师,Go 经验丰富(10 年),但这是第一次接触 React 前端代码。解释前端概念时,应使用后端类比来帮助理解。Frontmatter 字段: - name: 记忆名称(语义化标识) - description: 一行描述(用于 MEMORY.md 索引和相关性判断) - type: 记忆类型(user | feedback | project | reference)
2.3 MEMORY.md 索引
MEMORY.md 是记忆系统的一级索引,始终加载到 system prompt 中:
- [User Role](user_role.md) — 资深 Go 工程师,React 新手- [Testing Policy](feedback_testing.md) — 不 mock 数据库,需要真实连接- [Release Freeze](project_deadline.md) — 2026-03-05 起冻结非关键合并约束: - 最多 200 行(MAX_ENTRYPOINT_LINES) - 最多 25 KB(MAX_ENTRYPOINT_BYTES) - 超限时自动截断并显示警告 - 截断时不切割中文字符
3. 记忆类型系统
3.1 四种核心类型
定义于 src/memdir/memoryTypes.ts:
export type MemoryType = 'user' | 'feedback' | 'project' | 'reference'
3.2 类型设计的考量
feedback 类型的结构化要求:
规则本身**Why:** 用户给出的原因(通常是过去的事故或强烈偏好)**How to apply:** 何时/何处应用此指导这种结构确保 LLM 在遇到边缘情况时能做判断,而非盲目遵循规则。project 类型的日期规范:所有相对日期必须转为绝对日期("Thursday" → "2026-03-05"),避免时间推移后记忆失效。
3.3 明确排除的内容
git log/git blame 是权威来源4. 记忆的生命周期
4.1 创建:双路径机制
路径一:主 Agent 直接写入 LLM 在对话过程中通过 Write/Edit 工具直接创建记忆文件,system prompt 提供了详细的写入指令(两步流程:写文件 + 更新 MEMORY.md 索引)。路径二:后台自动提取(src/services/extractMemories/) 当主 Agent 未直接写入记忆时,extractMemories 子代理在每个查询循环结束时自动触发:
主 Agent 完成回复(model 输出,无 tool 调用) ↓检查 hasMemoryWritesSince() → 若已写,跳过 ↓创建 forked agent(共享 prompt cache,避免 cache busting) ↓子代理分析对话,提取值得保存的记忆 ↓写入 memory 目录(最多 5 轮交互)子代理权限模型 (createAutoMemCanUseTool()): - 允许:Read/Grep/Glob 无限制 - 允许:只读 Bash(ls/find/cat/stat 等) - 允许:Edit/Write 仅限 memory 目录 - 拒绝:rm、MCP 工具、具有写能力的 Bash
4.2 读取:三层召回机制
第一层:MEMORY.md 静态加载 MEMORY.md 索引始终嵌入在 system prompt 中,LLM 可以随时查看所有记忆的概要。第二层:LLM 自主读取 LLM 根据 MEMORY.md 中的描述判断需要哪条记忆,使用 Read 工具直接读取文件。第三层:Sonnet 智能选择(src/memdir/findRelevantMemories.ts) 在每个用户查询开始时,通过独立的 Sonnet API 调用自动选择相关记忆:
scanMemoryFiles() → 获取所有记忆文件头部 ↓Sonnet 模型评估相关性(JSON schema 输出) ↓去重(过滤已在本会话中 surfaced 的记忆) ↓最多选择 5 条记忆 ↓作为 system-reminder 附件注入新鲜度标注 (src/memdir/memoryAge.ts): - 超过 1 天的记忆附带新鲜度警告 - 格式:Memory (saved 5 days ago): path/to/file.md
4.3 更新与清理
更新:语义化组织,LLM 先检查是否存在同主题记忆再决定更新或新建。清理: - 无自动过期机制 - /remember skill 提供审查功能:将记忆推广到 CLAUDE.md(项目级指令)或 CLAUDE.local.md(个人指令) - 用户可手动编辑/删除记忆文件
4.4 记忆验证
System prompt 中明确要求验证记忆的时效性: - 记忆提到的文件路径 → 检查文件是否存在 - 记忆提到的函数/flag → grep 确认 - 架构快照视为时间冻结状态,不作为当前状态引用
5. 上下文注入
5.1 System Prompt 结构
src/constants/prompts.ts 和 src/memdir/memdir.ts 共同构建记忆 prompt:
## auto memoryYou have a persistent, file-based memory system at `~/.claude/projects/.../memory/`.## Types of memory[四种类型的详细说明和使用指南]## What NOT to save in memory[排除规则]## How to save memoriesStep 1: 写入带 frontmatter 的 .md 文件Step 2: 在 MEMORY.md 添加一行指针(~150 字符)## When to access memories[访问规则]## Before recommending from memory[验证规则]## Memory and other forms of persistence[与 Plan、Tasks 的区分]## MEMORY.md[MEMORY.md 的实际内容,或 "currently empty"]5.2 三种模式

5.3 动态附件注入
通过 src/utils/attachments.ts 实现预取和注入:
用户发送消息 ↓startRelevantMemoryPrefetch() → 后台启动,不阻塞主 turn ↓findRelevantMemories(query, memoryDir, signal, recentTools, alreadySurfaced) ↓Sonnet 选择最多 5 条记忆 ↓作为 relevant_memories 类型的 system-reminder 附件注入6. 安全设计
6.1 团队记忆安全
src/memdir/teamMemPaths.ts 实现了多层防护: - symlink 逃逸防护:realpathDeepestExisting() 递归解析 - null 字节检查:防止路径注入 - URL 编码/Unicode 规范化攻击防护 - 路径范围验证:isRealPathWithinTeamDir()
6.2 数据隔离
7. 遥测与监控
关键事件: - tengu_memdir_loaded — 记忆目录加载 - tengu_extract_memories_extraction — 提取完成(含 token 使用、文件数、耗时) - tengu_extract_memories_skipped_direct_write — 因主 Agent 已写而跳过 - tengu_memory_recall_shape — 选择统计(候选数/选中数) 特性门控(GrowthBook 标志): - tengu_herring_clock — 启用 team memory - tengu_passport_quail — 启用 extract 模式 - tengu_moth_copse — 跳过索引模式(启用智能选择) - tengu_coral_fern — 启用"搜索过去上下文"section
8. 设计亮点与权衡
亮点
/remember skill 支持从记忆到指令的晋升。权衡
/remember skill 审查。9. 关键文件索引



