Initialize cc-haha project mirror.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@@ -0,0 +1,277 @@
|
||||
# Claude Code 记忆系统 — 使用指南
|
||||
|
||||
> 让 Claude Code 跨会话记住你是谁、你偏好什么、项目正在发生什么。
|
||||
|
||||
<p align="center">
|
||||
<a href="#一什么是记忆系统">记忆系统</a> · <a href="#二四种记忆类型">四种记忆类型</a> · <a href="#三如何触发记忆保存">触发保存</a> · <a href="#四记忆存储在哪里">存储位置</a> · <a href="#五如何管理记忆">管理记忆</a> · <a href="#六记忆的生命周期">生命周期</a> · <a href="#七快速参考">快速参考</a>
|
||||
</p>
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 一、什么是记忆系统?
|
||||
|
||||
Claude Code 的记忆系统是一套**基于文件的持久化知识库**,让 Claude 能够跨越多次对话,持续积累对你和你的项目的理解。
|
||||
|
||||
核心理念:**只记住无法从代码中推断出来的东西。**
|
||||
|
||||
| 记住 | 不记住 |
|
||||
|------|--------|
|
||||
| 你是数据科学家,关注日志系统 | 代码架构、文件结构 |
|
||||
| "不要 mock 数据库" | Git 历史、谁改了什么 |
|
||||
| 周四后冻结非关键合并 | 已有的 CLAUDE.md 内容 |
|
||||
| Bug 跟踪在 Linear 的 INGEST 项目 | 调试方案(修复已在代码里) |
|
||||
|
||||
---
|
||||
|
||||
## 二、四种记忆类型
|
||||
|
||||

|
||||
|
||||
Claude Code 将记忆严格分为四类:
|
||||
|
||||
### 1. User(用户画像)
|
||||
|
||||
记录你的角色、目标、技能水平和偏好,帮助 Claude 调整协作方式。
|
||||
|
||||
```
|
||||
用户说:我写了十年 Go,但这是第一次碰这个仓库的 React 部分
|
||||
Claude 保存:深厚 Go 经验,React 新手 — 用后端类比解释前端概念
|
||||
```
|
||||
|
||||
### 2. Feedback(行为反馈)
|
||||
|
||||
你对 Claude 工作方式的纠正或肯定。这类记忆让 Claude 不会犯同样的错。
|
||||
|
||||
```
|
||||
用户说:别在回复末尾总结你做了什么,我能看 diff
|
||||
Claude 保存:用户要求简洁回复,不要尾部摘要
|
||||
```
|
||||
|
||||
**重要**:不只记录纠正,也记录肯定。如果 Claude 做了一个非显而易见的选择而你认可了,也会被记住。
|
||||
|
||||
### 3. Project(项目动态)
|
||||
|
||||
无法从代码或 Git 历史中推导出的项目上下文:谁在做什么、为什么、截止日期。
|
||||
|
||||
```
|
||||
用户说:我们周四后冻结所有非关键合并,移动团队要切发布分支
|
||||
Claude 保存:2026-03-05 起合并冻结,标记该日期后的非关键 PR 工作
|
||||
```
|
||||
|
||||
**注意**:Claude 会将相对日期("周四")转换为绝对日期("2026-03-05"),确保记忆不会过时失效。
|
||||
|
||||
### 4. Reference(外部引用)
|
||||
|
||||
指向外部系统中信息的指针:仪表板、工单系统、Slack 频道。
|
||||
|
||||
```
|
||||
用户说:oncall 看的是 grafana.internal/d/api-latency 这个面板
|
||||
Claude 保存:grafana.internal/d/api-latency 是 oncall 延迟仪表板 — 编辑请求路径代码时检查
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、如何触发记忆保存
|
||||
|
||||

|
||||
|
||||
### 方式一:自动提取(最常用)
|
||||
|
||||
这是最主要的方式。**你不需要做任何事情**,Claude 会在每次对话结束时自动分析对话内容,提取值得记住的信息。
|
||||
|
||||
工作流程:
|
||||
1. 你和 Claude 正常对话
|
||||
2. Claude 完成回复(没有工具调用时)
|
||||
3. 后台启动一个**记忆提取子代理**
|
||||
4. 子代理分析最近的对话内容
|
||||
5. 识别出值得保存的记忆
|
||||
6. 写入记忆文件 + 更新 MEMORY.md 索引
|
||||
|
||||
终端会显示通知:
|
||||
```
|
||||
Memory updated in ~/.claude/projects/.../memory/feedback_testing.md · /memory to edit
|
||||
```
|
||||
|
||||
### 方式二:显式要求
|
||||
|
||||
直接告诉 Claude "记住这个":
|
||||
|
||||
```
|
||||
用户:记住,这个项目部署前必须运行 bun test
|
||||
Claude:[立即保存为 feedback 类型记忆]
|
||||
```
|
||||
|
||||
### 方式三:/memory 命令
|
||||
|
||||
在终端输入 `/memory` 命令,会打开一个文件选择器,让你在编辑器中直接编辑记忆文件。
|
||||
|
||||
```
|
||||
> /memory
|
||||
```
|
||||
|
||||
这会列出所有可编辑的记忆文件(CLAUDE.md、CLAUDE.local.md、auto-memory 等),选择后用你的 `$EDITOR` 或 `$VISUAL` 打开。
|
||||
|
||||
### 方式四:/remember 命令
|
||||
|
||||
输入 `/remember` 触发记忆审查技能,它会:
|
||||
- 审查所有自动记忆条目
|
||||
- 提议将合适的条目提升到 CLAUDE.md 或 CLAUDE.local.md
|
||||
- 检测重复、过时和冲突的记忆
|
||||
- **不会直接修改**,所有变更需要你批准
|
||||
|
||||
---
|
||||
|
||||
## 四、记忆存储在哪里?
|
||||
|
||||
### 目录结构
|
||||
|
||||
```
|
||||
~/.claude/
|
||||
└── projects/
|
||||
└── {项目路径哈希}/
|
||||
└── memory/ ← 自动记忆目录
|
||||
├── MEMORY.md ← 索引文件(始终加载到上下文)
|
||||
├── user_role.md ← 用户画像记忆
|
||||
├── feedback_testing.md ← 行为反馈记忆
|
||||
├── project_freeze.md ← 项目动态记忆
|
||||
├── reference_linear.md ← 外部引用记忆
|
||||
└── team/ ← 团队共享记忆(如启用)
|
||||
├── MEMORY.md
|
||||
└── ...
|
||||
```
|
||||
|
||||
### 记忆文件格式
|
||||
|
||||
每个记忆文件使用 YAML frontmatter + Markdown 内容:
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: 测试策略偏好
|
||||
description: 集成测试必须使用真实数据库,不要 mock
|
||||
type: feedback
|
||||
---
|
||||
|
||||
集成测试必须使用真实数据库,不要 mock。
|
||||
|
||||
**Why:** 上季度 mock 测试通过但生产环境迁移失败,mock/生产差异掩盖了问题。
|
||||
|
||||
**How to apply:** 编写或审查测试时,确保数据库操作使用真实连接。
|
||||
```
|
||||
|
||||
### MEMORY.md 索引文件
|
||||
|
||||
MEMORY.md 是索引而不是内容。它**始终加载到上下文**中,每行一个条目:
|
||||
|
||||
```markdown
|
||||
- [用户角色](user_role.md) — 数据科学家,关注可观测性/日志
|
||||
- [测试策略](feedback_testing.md) — 集成测试用真实数据库,不 mock
|
||||
- [合并冻结](project_freeze.md) — 2026-03-05 起冻结非关键合并
|
||||
- [Bug 追踪](reference_linear.md) — 流水线 bug 在 Linear INGEST 项目
|
||||
```
|
||||
|
||||
**限制**:最多 200 行或 25KB,超出会被截断。
|
||||
|
||||
---
|
||||
|
||||
## 五、如何管理记忆
|
||||
|
||||
### 让 Claude 遗忘
|
||||
|
||||
```
|
||||
用户:忘记关于合并冻结的记忆
|
||||
Claude:[找到并删除相关记忆文件和索引条目]
|
||||
```
|
||||
|
||||
### 让 Claude 忽略记忆
|
||||
|
||||
```
|
||||
用户:忽略记忆,从零开始
|
||||
Claude:[本次对话中不使用任何记忆内容]
|
||||
```
|
||||
|
||||
### 手动编辑
|
||||
|
||||
直接编辑 `~/.claude/projects/{hash}/memory/` 下的文件,或使用 `/memory` 命令。
|
||||
|
||||
### 禁用自动记忆
|
||||
|
||||
| 方法 | 做法 |
|
||||
|------|------|
|
||||
| 环境变量 | `CLAUDE_CODE_DISABLE_AUTO_MEMORY=1` |
|
||||
| 设置文件 | `settings.json` 中 `"autoMemoryEnabled": false` |
|
||||
| 精简模式 | `--bare` 启动 / `CLAUDE_CODE_SIMPLE=1` |
|
||||
|
||||
### 自定义记忆目录
|
||||
|
||||
在 `~/.claude/settings.json` 中设置:
|
||||
|
||||
```json
|
||||
{
|
||||
"autoMemoryDirectory": "~/my-claude-memories"
|
||||
}
|
||||
```
|
||||
|
||||
支持 `~/` 展开。出于安全考虑,项目级 `.claude/settings.json` **不允许**设置此项。
|
||||
|
||||
---
|
||||
|
||||
## 六、记忆的生命周期
|
||||
|
||||

|
||||
|
||||
```
|
||||
对话中学到新信息
|
||||
↓
|
||||
自动提取 / 显式保存
|
||||
↓
|
||||
写入记忆文件 + 索引
|
||||
↓
|
||||
下次对话加载 MEMORY.md
|
||||
↓
|
||||
智能选择相关记忆(Sonnet)
|
||||
↓
|
||||
注入到对话上下文
|
||||
↓
|
||||
记忆变旧?验证后再使用
|
||||
↓
|
||||
过时?更新或删除
|
||||
↓
|
||||
(24h + 5个会话后)
|
||||
↓
|
||||
AutoDream 后台整合记忆
|
||||
```
|
||||
|
||||
### AutoDream —— "做梦"整理记忆
|
||||
|
||||
Claude Code 有一个隐藏的 **AutoDream** 功能,类比人类睡眠时大脑整理记忆的过程。当满足以下条件时,Claude 会在后台静默启动一个"做梦"子智能体:
|
||||
|
||||
- 距上次整合 **>= 24 小时**
|
||||
- 期间积累了 **>= 5 个会话**
|
||||
|
||||
做梦过程分四阶段:定向 → 收集 → 整合 → 修剪。底部状态栏会显示 **"dreaming"**,你可以按 `Shift+Down` 查看进度,按 `x` 终止。
|
||||
|
||||
详细技术分析见 [AutoDream 记忆整合](./03-autodream.md)。
|
||||
|
||||
### 新鲜度管理
|
||||
|
||||
- **今天/昨天的记忆**:直接使用
|
||||
- **超过 1 天的记忆**:附带陈旧警告,提醒 Claude 验证后再引用
|
||||
- **引用文件路径/函数名的记忆**:使用前先 grep 确认还存在
|
||||
|
||||
---
|
||||
|
||||
## 七、快速参考
|
||||
|
||||
| 操作 | 方法 |
|
||||
|------|------|
|
||||
| 让 Claude 记住 | "记住:这个项目用 bun 不用 npm" |
|
||||
| 让 Claude 忘记 | "忘记关于 XXX 的记忆" |
|
||||
| 编辑记忆 | `/memory` 命令 |
|
||||
| 审查和整理 | `/remember` 命令 |
|
||||
| 忽略记忆 | "忽略记忆" / "不要用记忆" |
|
||||
| 禁用自动记忆 | `CLAUDE_CODE_DISABLE_AUTO_MEMORY=1` |
|
||||
| 禁用 AutoDream | `settings.json` 中 `"autoDreamEnabled": false` |
|
||||
| 手动整合记忆 | `/dream` 命令 |
|
||||
| 查看记忆目录 | `~/.claude/projects/{hash}/memory/` |
|
||||
@@ -0,0 +1,472 @@
|
||||
# Claude Code 记忆系统 — 实现原理
|
||||
|
||||
> 从系统提示词注入到后台自动提取,拆解记忆系统的每一个技术细节。
|
||||
|
||||
<p align="center">
|
||||
<a href="#一整体架构">整体架构</a> · <a href="#二路径解析系统">路径解析</a> · <a href="#三系统提示词注入">提示词注入</a> · <a href="#四自动记忆提取">自动提取</a> · <a href="#五智能记忆检索">智能检索</a> · <a href="#六记忆扫描详解">记忆扫描</a> · <a href="#七代理记忆-agent-memory">代理记忆</a> · <a href="#八团队记忆同步">团队同步</a> · <a href="#九关键常量速查">常量速查</a> · <a href="#十数据流总览">数据流总览</a>
|
||||
</p>
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 一、整体架构
|
||||
|
||||
记忆系统由 5 个核心模块协作完成:
|
||||
|
||||
| 模块 | 源码位置 | 职责 |
|
||||
|------|----------|------|
|
||||
| **路径解析** | `src/memdir/paths.ts` | 计算记忆存储目录,处理覆盖和安全校验 |
|
||||
| **提示词构建** | `src/memdir/memdir.ts` | 将记忆指令注入系统提示词 |
|
||||
| **记忆扫描** | `src/memdir/memoryScan.ts` | 扫描目录、解析 frontmatter、排序 |
|
||||
| **智能检索** | `src/memdir/findRelevantMemories.ts` | 用 Sonnet 选择与当前查询相关的记忆 |
|
||||
| **自动提取** | `src/services/extractMemories/` | 后台分叉代理,从对话中提取记忆 |
|
||||
|
||||
辅助模块:
|
||||
|
||||
| 模块 | 源码位置 | 职责 |
|
||||
|------|----------|------|
|
||||
| **AutoDream** | `src/services/autoDream/` | 后台记忆整合("做梦"),详见 [03-autodream.md](./03-autodream.md) |
|
||||
| **类型定义** | `src/memdir/memoryTypes.ts` | 四种记忆类型的分类法和提示词模板 |
|
||||
| **新鲜度** | `src/memdir/memoryAge.ts` | 计算记忆年龄、生成陈旧警告 |
|
||||
| **文件检测** | `src/utils/memoryFileDetection.ts` | 判断路径是否属于记忆系统 |
|
||||
| **代理记忆** | `src/tools/AgentTool/agentMemory.ts` | 子代理专属的三级记忆目录 |
|
||||
| **团队同步** | `src/services/teamMemorySync/` | 记忆的远程上传/下载 |
|
||||
|
||||
---
|
||||
|
||||
## 二、路径解析系统
|
||||
|
||||

|
||||
|
||||
### 核心函数:`getAutoMemPath()`
|
||||
|
||||
```
|
||||
路径解析优先级(从高到低):
|
||||
|
||||
1. CLAUDE_COWORK_MEMORY_PATH_OVERRIDE ← Cowork 环境变量(完整路径)
|
||||
2. settings.json → autoMemoryDirectory ← 用户设置(支持 ~/ 展开)
|
||||
3. {memoryBase}/projects/{sanitized-git-root}/memory/ ← 默认计算路径
|
||||
```
|
||||
|
||||
**关键源码** `src/memdir/paths.ts:223`:
|
||||
|
||||
```typescript
|
||||
export const getAutoMemPath = memoize(
|
||||
(): string => {
|
||||
const override = getAutoMemPathOverride() ?? getAutoMemPathSetting()
|
||||
if (override) return override
|
||||
const projectsDir = join(getMemoryBaseDir(), 'projects')
|
||||
return join(projectsDir, sanitizePath(getAutoMemBase()), AUTO_MEM_DIRNAME) + sep
|
||||
},
|
||||
() => getProjectRoot(), // 缓存 key = 项目根目录
|
||||
)
|
||||
```
|
||||
|
||||
### 路径安全校验
|
||||
|
||||
`validateMemoryPath()` 拒绝危险路径:
|
||||
|
||||
| 被拒路径 | 原因 |
|
||||
|----------|------|
|
||||
| `../foo` | 相对路径,CWD 相关 |
|
||||
| `/` 或 `/a` | 根路径或过短路径 |
|
||||
| `C:\` | Windows 驱动器根目录 |
|
||||
| `\\server\share` | UNC 网络路径 |
|
||||
| 含 `\0` | 空字节,可在系统调用中截断 |
|
||||
|
||||
**安全限制**:项目级 `.claude/settings.json` **不允许**设置 `autoMemoryDirectory`,防止恶意仓库通过此项获取对 `~/.ssh` 等敏感目录的写权限。
|
||||
|
||||
### 启用条件
|
||||
|
||||
`isAutoMemoryEnabled()` 的判断链:
|
||||
|
||||
```
|
||||
CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 → 关闭
|
||||
CLAUDE_CODE_SIMPLE (--bare) → 关闭
|
||||
远程模式 且 无 REMOTE_MEMORY_DIR → 关闭
|
||||
settings.json autoMemoryEnabled → 跟随设置
|
||||
默认 → 开启
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、系统提示词注入
|
||||
|
||||

|
||||
|
||||
### 入口:`loadMemoryPrompt()`
|
||||
|
||||
这是记忆系统与系统提示词的接口。启动时调用一次(通过 `systemPromptSection` 缓存)。
|
||||
|
||||
```
|
||||
loadMemoryPrompt()
|
||||
├─ KAIROS 模式?→ buildAssistantDailyLogPrompt() [日志追加模式]
|
||||
├─ TEAMMEM 开启?→ buildCombinedMemoryPrompt() [个人+团队双目录]
|
||||
├─ 正常模式 → buildMemoryLines() [单目录]
|
||||
└─ 禁用 → return null
|
||||
```
|
||||
|
||||
### `buildMemoryLines()` 构建的提示词结构
|
||||
|
||||
```
|
||||
# auto memory
|
||||
|
||||
你有一个持久化的文件记忆系统,位于 `{memoryDir}`...
|
||||
|
||||
## Types of memory ← 四种类型的定义和示例
|
||||
## What NOT to save ← 排除规则
|
||||
## How to save memories ← 两步保存流程
|
||||
## When to access memories ← 何时查阅
|
||||
## Before recommending ← 引用前验证
|
||||
## Memory and other forms ← 与 Plan/Task 的区别
|
||||
|
||||
## MEMORY.md ← 索引内容(或"当前为空")
|
||||
```
|
||||
|
||||
### MEMORY.md 截断策略
|
||||
|
||||
`truncateEntrypointContent()` 执行双重限制:
|
||||
|
||||
```typescript
|
||||
// 先截断行数
|
||||
if (lineCount > 200) → 截断到 200 行
|
||||
|
||||
// 再截断字节数(处理超长行)
|
||||
if (bytes > 25,000) → 在最后一个换行符处截断
|
||||
|
||||
// 附加警告
|
||||
"WARNING: MEMORY.md is {reason}. Only part of it was loaded."
|
||||
```
|
||||
|
||||
### 目录自动创建
|
||||
|
||||
`ensureMemoryDirExists()` 在加载提示词时确保目录存在:
|
||||
- 递归创建 `mkdir`(处理整个父链)
|
||||
- 吞掉 `EEXIST`(幂等)
|
||||
- 真正的权限错误只记日志不中断(Write 工具会显示真实错误)
|
||||
|
||||
提示词中明确告知模型目录已存在,避免浪费 turn 执行 `ls` 或 `mkdir`。
|
||||
|
||||
---
|
||||
|
||||
## 四、自动记忆提取
|
||||
|
||||

|
||||
|
||||
### 触发时机
|
||||
|
||||
在 `handleStopHooks` 中,当模型产生最终响应(无工具调用)时触发。
|
||||
|
||||
**关键源码** `src/services/extractMemories/extractMemories.ts`
|
||||
|
||||
### 完整提取流程
|
||||
|
||||
```
|
||||
1. 模型完成回复(无 tool_use)
|
||||
↓
|
||||
2. executeExtractMemories() 被调用
|
||||
↓
|
||||
3. 守卫检查:
|
||||
- 是主代理?(子代理不提取)
|
||||
- 功能门控开启?
|
||||
- 自动记忆启用?
|
||||
- 非远程模式?
|
||||
- 没有并行提取在进行?
|
||||
↓
|
||||
4. 频率控制:
|
||||
turnsSinceLastExtraction++
|
||||
if < tengu_bramble_lintel → 跳过
|
||||
↓
|
||||
5. 互斥检查:
|
||||
主代理自己写了记忆?→ 跳过,推进游标
|
||||
↓
|
||||
6. 扫描现有记忆目录(scanMemoryFiles)
|
||||
生成清单(formatMemoryManifest)
|
||||
↓
|
||||
7. 构建提取提示词(buildExtractAutoOnlyPrompt)
|
||||
↓
|
||||
8. 运行分叉代理(runForkedAgent)
|
||||
- 共享父会话的提示词缓存
|
||||
- 最多 5 个 turn
|
||||
- 限制工具权限
|
||||
↓
|
||||
9. 提取写入的文件路径
|
||||
推进游标到最新消息
|
||||
↓
|
||||
10. 通知用户:"Memory updated in ..."
|
||||
```
|
||||
|
||||
### 分叉代理(Forked Agent)
|
||||
|
||||
自动提取使用 `runForkedAgent` — 这是对主会话的完美分叉:
|
||||
|
||||
- **共享提示词缓存**:避免重复的 API 缓存创建费用
|
||||
- **隔离执行**:不影响主会话的消息历史
|
||||
- **受限工具**:只允许 Read、Grep、Glob、只读 Bash、以及对记忆目录的 Edit/Write
|
||||
- **不记录转录**:防止与主线程的竞争条件
|
||||
|
||||
### 工具权限(`createAutoMemCanUseTool`)
|
||||
|
||||
```
|
||||
✅ 允许:Read, Grep, Glob(无限制)
|
||||
✅ 允许:Bash(仅只读命令:ls, find, grep, cat, stat...)
|
||||
✅ 允许:Edit/Write(仅 auto-memory 目录内)
|
||||
❌ 拒绝:MCP, Agent, 非只读 Bash, 其他写操作
|
||||
```
|
||||
|
||||
### 互斥机制
|
||||
|
||||
主代理和提取代理是**互斥的**:
|
||||
|
||||
```typescript
|
||||
function hasMemoryWritesSince(messages, sinceUuid): boolean {
|
||||
// 扫描 sinceUuid 之后的所有 assistant 消息
|
||||
// 如果有任何 Edit/Write 的 tool_use 指向 auto-memory 目录
|
||||
// → return true(跳过提取,推进游标)
|
||||
}
|
||||
```
|
||||
|
||||
这避免了重复保存:主代理已经写了记忆时,后台提取直接跳过。
|
||||
|
||||
### 合并机制
|
||||
|
||||
如果前一次提取还在运行:
|
||||
1. 新的上下文被暂存(`pendingContext`)
|
||||
2. 旧提取完成后,立即启动一次**尾部提取**
|
||||
3. 尾部提取只处理两次调用之间新增的消息
|
||||
|
||||
---
|
||||
|
||||
## 五、智能记忆检索
|
||||
|
||||

|
||||
|
||||
### 工作原理
|
||||
|
||||
每次用户发送查询时,`findRelevantMemories()` 被触发:
|
||||
|
||||
```
|
||||
1. scanMemoryFiles(memoryDir)
|
||||
- 递归读取所有 .md 文件(排除 MEMORY.md)
|
||||
- 解析 frontmatter(前 30 行)
|
||||
- 按修改时间降序排序
|
||||
- 最多 200 个文件
|
||||
↓
|
||||
2. 过滤已展示过的记忆(alreadySurfaced)
|
||||
↓
|
||||
3. 格式化清单(formatMemoryManifest)
|
||||
- [type] filename (ISO timestamp): description
|
||||
↓
|
||||
4. Sonnet 模型选择(sideQuery)
|
||||
- 系统提示:你是记忆选择器...
|
||||
- 用户消息:Query + Available memories + Recently used tools
|
||||
- 输出:JSON { selected_memories: string[] }
|
||||
- 最多选 5 个
|
||||
↓
|
||||
5. 返回选中记忆的 { path, mtimeMs }
|
||||
```
|
||||
|
||||
### Sonnet 选择器的提示词
|
||||
|
||||
```
|
||||
你正在选择对 Claude Code 处理用户查询有用的记忆。
|
||||
你将收到用户查询和可用记忆文件列表(含文件名和描述)。
|
||||
|
||||
返回最多 5 个明确有用的记忆文件名。
|
||||
- 不确定是否有用就不要选
|
||||
- 没有明确有用的就返回空列表
|
||||
- 如果提供了最近使用的工具列表,不要选这些工具的使用文档
|
||||
(但 DO 选择关于这些工具的警告/陷阱/已知问题)
|
||||
```
|
||||
|
||||
### 新鲜度警告
|
||||
|
||||
选中的记忆在注入上下文时会附带新鲜度信息:
|
||||
|
||||
```typescript
|
||||
function memoryFreshnessText(mtimeMs: number): string {
|
||||
const d = memoryAgeDays(mtimeMs)
|
||||
if (d <= 1) return '' // 今天/昨天:无警告
|
||||
return `This memory is ${d} days old. Memories are point-in-time observations...
|
||||
Verify against current code before asserting as fact.`
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、记忆扫描详解
|
||||
|
||||
### `scanMemoryFiles()`
|
||||
|
||||
**关键设计**:单次遍历(read-then-sort),避免双重 stat 系统调用。
|
||||
|
||||
```typescript
|
||||
async function scanMemoryFiles(memoryDir, signal): Promise<MemoryHeader[]> {
|
||||
const entries = await readdir(memoryDir, { recursive: true })
|
||||
const mdFiles = entries.filter(f => f.endsWith('.md') && basename(f) !== 'MEMORY.md')
|
||||
|
||||
// 并行读取所有文件的 frontmatter(前 30 行)
|
||||
const headerResults = await Promise.allSettled(
|
||||
mdFiles.map(async (relativePath) => {
|
||||
const { content, mtimeMs } = await readFileInRange(filePath, 0, 30)
|
||||
const { frontmatter } = parseFrontmatter(content)
|
||||
return { filename, filePath, mtimeMs, description, type }
|
||||
})
|
||||
)
|
||||
|
||||
// 过滤成功的、按时间降序排序、取前 200
|
||||
return fulfilled.sort((a, b) => b.mtimeMs - a.mtimeMs).slice(0, 200)
|
||||
}
|
||||
```
|
||||
|
||||
### `formatMemoryManifest()`
|
||||
|
||||
生成供 Sonnet 或提取代理消费的清单格式:
|
||||
|
||||
```
|
||||
- [feedback] testing_policy.md (2026-03-15T10:30:00.000Z): 集成测试用真实数据库
|
||||
- [user] role.md (2026-03-14T08:00:00.000Z): 数据科学家,关注日志
|
||||
- [project] freeze.md (2026-03-10T15:00:00.000Z): 3/5 起合并冻结
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、代理记忆(Agent Memory)
|
||||
|
||||

|
||||
|
||||
子代理(通过 Agent 工具启动的)有独立的三级记忆系统:
|
||||
|
||||
| 作用域 | 路径 | 说明 |
|
||||
|--------|------|------|
|
||||
| **user** | `~/.claude/agent-memory/{agentType}/` | 全局用户级 |
|
||||
| **project** | `.claude/agent-memory/{agentType}/` | 项目级(提交到 VCS) |
|
||||
| **local** | `.claude/agent-memory-local/{agentType}/` | 本地级(不提交) |
|
||||
|
||||
代理记忆与主记忆的差异:
|
||||
- 无 MEMORY.md 索引步骤(`skipIndex = true`)
|
||||
- 直接写文件即可,无需两步操作
|
||||
- 各代理类型隔离(explorer、planner 等各有各的目录)
|
||||
|
||||
---
|
||||
|
||||
## 八、团队记忆同步
|
||||
|
||||
当 `TEAMMEM` feature flag 开启时:
|
||||
|
||||
### 目录结构
|
||||
|
||||
```
|
||||
~/.claude/projects/{hash}/memory/
|
||||
├── MEMORY.md ← 个人记忆索引
|
||||
├── user_*.md ← 个人记忆
|
||||
└── team/ ← 团队共享目录
|
||||
├── MEMORY.md ← 团队记忆索引
|
||||
└── *.md ← 团队记忆
|
||||
```
|
||||
|
||||
### 同步 API
|
||||
|
||||
```
|
||||
GET /api/claude_code/team_memory?repo={owner/repo} ← 拉取
|
||||
PUT /api/claude_code/team_memory?repo={owner/repo} ← 推送
|
||||
```
|
||||
|
||||
### 同步语义
|
||||
|
||||
- **Pull**:服务器内容覆盖本地文件
|
||||
- **Push**:仅上传内容哈希不同的键(delta 上传)
|
||||
- **删除不传播**:本地删除不会删除远程
|
||||
- **限制**:单文件最大 250KB,上传体最大 200KB(分批)
|
||||
|
||||
### 团队 vs 个人的路由规则
|
||||
|
||||
在 `memoryTypes.ts` 中,每种类型有 `<scope>` 指导:
|
||||
|
||||
| 类型 | 默认作用域 |
|
||||
|------|-----------|
|
||||
| user | 始终个人 |
|
||||
| feedback | 默认个人,项目级规范放团队 |
|
||||
| project | 偏向团队 |
|
||||
| reference | 通常团队 |
|
||||
|
||||
---
|
||||
|
||||
## 九、关键常量速查
|
||||
|
||||
```typescript
|
||||
// 索引文件
|
||||
ENTRYPOINT_NAME = 'MEMORY.md'
|
||||
MAX_ENTRYPOINT_LINES = 200
|
||||
MAX_ENTRYPOINT_BYTES = 25_000
|
||||
|
||||
// 扫描
|
||||
MAX_MEMORY_FILES = 200
|
||||
FRONTMATTER_MAX_LINES = 30
|
||||
|
||||
// 路径
|
||||
AUTO_MEM_DIRNAME = 'memory'
|
||||
|
||||
// 提取
|
||||
maxTurns = 5 // 分叉代理最多 5 个 turn
|
||||
|
||||
// 检索
|
||||
最多返回 5 个相关记忆
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 十、数据流总览
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ 会话启动 │
|
||||
│ │
|
||||
│ loadMemoryPrompt() │
|
||||
│ → ensureMemoryDirExists() │
|
||||
│ → buildMemoryLines() + MEMORY.md 内容 │
|
||||
│ → 注入系统提示词 │
|
||||
└────────────────────────┬────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ 用户提问 │
|
||||
│ │
|
||||
│ findRelevantMemories() │
|
||||
│ → scanMemoryFiles() [扫描 + frontmatter] │
|
||||
│ → Sonnet 选择最多 5 个相关记忆 │
|
||||
│ → 注入对话上下文 + 新鲜度警告 │
|
||||
└────────────────────────┬────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Claude 回复 │
|
||||
│ │
|
||||
│ 模型可能直接写记忆(遵循系统提示词指导) │
|
||||
│ 或者不写 → 触发后台提取 │
|
||||
└────────────────────────┬────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ 后台自动提取 │
|
||||
│ │
|
||||
│ executeExtractMemories() │
|
||||
│ → 互斥检查(主代理已写?跳过) │
|
||||
│ → 构建提取提示词 + 记忆清单 │
|
||||
│ → runForkedAgent() [共享缓存, 限制工具, 5 turns] │
|
||||
│ → 写入新记忆文件 + 更新 MEMORY.md │
|
||||
│ → 通知用户 │
|
||||
└────────────────────────┬────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ 后台记忆整合(AutoDream) │
|
||||
│ │
|
||||
│ executeAutoDream() [每 24h + 5个会话触发] │
|
||||
│ → 五重门控检查(开关/时间/节流/会话/锁) │
|
||||
│ → buildConsolidationPrompt() │
|
||||
│ → runForkedAgent() [只读 Bash, 仅记忆目录写入] │
|
||||
│ → 四阶段:定向 → 收集 → 整合 → 修剪 │
|
||||
│ → 合并重复 / 修正过时 / 压缩索引 │
|
||||
│ → 通知用户:"Improved N memories" │
|
||||
│ │
|
||||
│ 详见 03-autodream.md │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -0,0 +1,316 @@
|
||||
# Claude Code 记忆系统 — AutoDream 记忆整合
|
||||
|
||||
> Claude 会"做梦"——在后台静默回顾近期会话,整合、更新、修剪记忆,就像人类睡眠中整理白天的记忆一样。
|
||||
|
||||
<p align="center">
|
||||
<a href="#一什么是-autodream">AutoDream</a> · <a href="#二触发条件">触发条件</a> · <a href="#三四阶段整合流程">整合流程</a> · <a href="#四安全限制">安全限制</a> · <a href="#五ui-展示">UI 展示</a> · <a href="#六配置与开关">配置开关</a> · <a href="#七与-extractmemories-的关系">对比</a> · <a href="#八源码导航">源码导航</a>
|
||||
</p>
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 一、什么是 AutoDream?
|
||||
|
||||
AutoDream 是 Claude Code 的 **后台记忆整合机制**,内部代号 **"Dream: Memory Consolidation"**。
|
||||
|
||||
核心隐喻:
|
||||
|
||||
| 人类 | Claude Code |
|
||||
|------|-------------|
|
||||
| 白天随手记笔记 | `extractMemories` — 每次对话后提取新记忆 |
|
||||
| 晚上睡觉时整理笔记本 | `autoDream` — 定期回顾多个会话,整合全部记忆 |
|
||||
|
||||
当你不活跃时(默认间隔 24 小时、积累 5 个会话后),Claude 会在后台静默启动一个 **"做梦"子智能体**(forked subagent),回顾所有近期会话记录,将零散的记忆整合为结构化的、去重的、去过时的持久化知识。
|
||||
|
||||
**关键源码**:`src/services/autoDream/autoDream.ts`
|
||||
|
||||
```typescript
|
||||
// Background memory consolidation. Fires the /dream prompt as a forked
|
||||
// subagent when time-gate passes AND enough sessions have accumulated.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、触发条件
|
||||
|
||||

|
||||
|
||||
AutoDream 采用 **五重门控** 机制,按开销从低到高逐级检查:
|
||||
|
||||
### 门控链
|
||||
|
||||
| 序号 | 门控 | 说明 | 开销 |
|
||||
|------|------|------|------|
|
||||
| 1 | **功能开关** | `isAutoDreamEnabled()` + 非 KAIROS + 非远程模式 + autoMemory 已启用 | 内存读取 |
|
||||
| 2 | **时间门控** | 距上次整合 >= `minHours`(默认 24h) | 1 次 stat |
|
||||
| 3 | **扫描节流** | 上次扫描后至少等 10 分钟再重新扫描 | 时间戳比较 |
|
||||
| 4 | **会话门控** | 自上次整合后至少 `minSessions` 个新会话(默认 5 个,排除当前) | 目录扫描 |
|
||||
| 5 | **锁门控** | 没有其他进程正在做梦(PID 锁文件) | stat + read |
|
||||
|
||||
**关键源码** `src/services/autoDream/autoDream.ts:63-66`:
|
||||
|
||||
```typescript
|
||||
const DEFAULTS: AutoDreamConfig = {
|
||||
minHours: 24, // 距离上次整合至少 24 小时
|
||||
minSessions: 5, // 期间至少积累了 5 个会话
|
||||
}
|
||||
```
|
||||
|
||||
### 扫描节流
|
||||
|
||||
当时间门控通过但会话门控未通过时,锁文件的 mtime 不会更新,导致时间门控在后续每个 turn 都会通过。为避免频繁的目录扫描,设有 **10 分钟的扫描节流**:
|
||||
|
||||
```typescript
|
||||
const SESSION_SCAN_INTERVAL_MS = 10 * 60 * 1000
|
||||
```
|
||||
|
||||
### 执行入口
|
||||
|
||||
AutoDream 在每次 AI 回复完成后的 stop hook 阶段被触发(fire-and-forget,不阻塞主线程):
|
||||
|
||||
**关键源码** `src/query/stopHooks.ts:154-156`:
|
||||
|
||||
```typescript
|
||||
if (!toolUseContext.agentId) {
|
||||
void executeAutoDream(stopHookContext, toolUseContext.appendSystemMessage)
|
||||
}
|
||||
```
|
||||
|
||||
### 阻止条件
|
||||
|
||||
以下情况不会触发 AutoDream:
|
||||
|
||||
- **KAIROS 模式**:使用独立的 disk-skill dream
|
||||
- **远程模式**:`getIsRemoteMode() === true`
|
||||
- **autoMemory 未启用**
|
||||
- **`--bare` / SIMPLE 模式**
|
||||
- **子代理内**:只有主代理才触发
|
||||
|
||||
---
|
||||
|
||||
## 三、四阶段整合流程
|
||||
|
||||

|
||||
|
||||
一旦所有门控通过,AutoDream 启动一个 **分叉子智能体**,按照 `consolidationPrompt.ts` 定义的 4 阶段提示词工作:
|
||||
|
||||
### Phase 1 — Orient(定向)
|
||||
|
||||
```
|
||||
- ls 记忆目录,查看已有文件
|
||||
- 读取 MEMORY.md 索引,理解当前知识结构
|
||||
- 浏览现有主题文件,避免创建重复
|
||||
- 如存在 logs/ 或 sessions/ 子目录,检查最近条目
|
||||
```
|
||||
|
||||
### Phase 2 — Gather recent signal(收集近期信号)
|
||||
|
||||
按优先级从高到低搜集信息:
|
||||
|
||||
1. **Daily logs** — `logs/YYYY/MM/YYYY-MM-DD.md`(追加流日志)
|
||||
2. **漂移的记忆** — 与代码库现状矛盾的旧事实
|
||||
3. **会话记录搜索** — 用 `grep` 在 JSONL 转录文件中窄范围检索
|
||||
|
||||
```
|
||||
不要穷尽读取转录文件。只查找你已经怀疑重要的内容。
|
||||
```
|
||||
|
||||
### Phase 3 — Consolidate(整合)
|
||||
|
||||
- **合并**新信号到已有主题文件(而非创建新的近似文件)
|
||||
- **转换**相对日期为绝对日期("昨天" → "2026-04-03")
|
||||
- **删除**被推翻的旧事实
|
||||
|
||||
### Phase 4 — Prune and index(修剪与索引)
|
||||
|
||||
- 更新 `MEMORY.md`,保持 ≤ 规定行数且 ≤ 25KB
|
||||
- 删除指向过时记忆的指针
|
||||
- 压缩冗长条目(>200 字符的索引行,将内容移入主题文件)
|
||||
- 新增指向重要记忆的指针
|
||||
- 解决矛盾(两个文件意见不一致时,修复错误的那个)
|
||||
|
||||
**关键源码** `src/services/autoDream/consolidationPrompt.ts:10-64`
|
||||
|
||||
---
|
||||
|
||||
## 四、安全限制
|
||||
|
||||
AutoDream 子智能体受到严格的工具权限限制:
|
||||
|
||||
### Bash 仅限只读
|
||||
|
||||
```
|
||||
允许:ls, find, grep, cat, stat, wc, head, tail
|
||||
拒绝:所有写入、重定向、修改状态的命令
|
||||
```
|
||||
|
||||
### 文件操作仅限记忆目录
|
||||
|
||||
`createAutoMemCanUseTool()` 是 `extractMemories` 和 `autoDream` 共享的权限函数:
|
||||
|
||||
```
|
||||
允许 Read / Grep / Glob — 无限制
|
||||
允许 Edit / Write — 仅 auto-memory 目录内
|
||||
拒绝 MCP / Agent / 非只读 Bash / 其他写操作
|
||||
```
|
||||
|
||||
**关键源码** `src/services/extractMemories/extractMemories.ts:167-171`
|
||||
|
||||
### 锁文件机制
|
||||
|
||||
使用 `.consolidate-lock` 文件实现进程级互斥:
|
||||
|
||||
| 机制 | 说明 |
|
||||
|------|------|
|
||||
| **锁内容** | 持有者 PID |
|
||||
| **时间戳** | 锁文件 mtime = 上次整合时间 |
|
||||
| **过期** | 持有超过 1 小时视为过期(防 PID 复用) |
|
||||
| **竞争** | 两个进程同时写入 → 最后写入者获胜,失败者在 re-read 时退出 |
|
||||
| **回滚** | 失败时回退 mtime 到获取前的值,让下次尝试不受影响 |
|
||||
| **崩溃恢复** | mtime 卡住 + 死 PID → 下个进程回收锁 |
|
||||
|
||||
**关键源码** `src/services/autoDream/consolidationLock.ts`
|
||||
|
||||
---
|
||||
|
||||
## 五、UI 展示
|
||||
|
||||
### 底部状态栏
|
||||
|
||||
当 AutoDream 运行时,底部状态栏会显示 **"dreaming"** 标签:
|
||||
|
||||
```typescript
|
||||
// src/tasks/pillLabel.ts:61-62
|
||||
case 'dream':
|
||||
return 'dreaming'
|
||||
```
|
||||
|
||||
### 任务详情对话框
|
||||
|
||||
用户按 `Shift+Down` 可打开后台任务对话框,查看梦境的实时进度:
|
||||
|
||||
- **DreamDetailDialog** 组件展示:
|
||||
- 正在回顾的会话数量
|
||||
- 当前阶段:`starting`(正在分析)→ `updating`(正在修改记忆文件)
|
||||
- 最近的助手文本响应和工具调用次数
|
||||
- 已触碰的文件路径列表
|
||||
|
||||
- **用户可按 `x` 键终止**正在进行的梦境(触发 abort + 锁回滚)
|
||||
|
||||
### 完成通知
|
||||
|
||||
梦境完成后,如果有文件被修改,会在主会话中显示内联通知:
|
||||
|
||||
```typescript
|
||||
appendSystemMessage({
|
||||
...createMemorySavedMessage(dreamState.filesTouched),
|
||||
verb: 'Improved',
|
||||
})
|
||||
```
|
||||
|
||||
**关键源码**:
|
||||
- `src/tasks/DreamTask/DreamTask.ts` — 任务状态管理
|
||||
- `src/components/tasks/DreamDetailDialog.tsx` — UI 组件
|
||||
|
||||
---
|
||||
|
||||
## 六、配置与开关
|
||||
|
||||
### settings.json
|
||||
|
||||
```json
|
||||
{
|
||||
"autoDreamEnabled": true
|
||||
}
|
||||
```
|
||||
|
||||
- **显式设置时**:直接使用用户的值
|
||||
- **未设置时**:由远程 GrowthBook feature flag `tengu_onyx_plover` 控制
|
||||
|
||||
**关键源码** `src/services/autoDream/config.ts:13-21`:
|
||||
|
||||
```typescript
|
||||
export function isAutoDreamEnabled(): boolean {
|
||||
const setting = getInitialSettings().autoDreamEnabled
|
||||
if (setting !== undefined) return setting
|
||||
const gb = getFeatureValue_CACHED_MAY_BE_STALE<{ enabled?: unknown } | null>(
|
||||
'tengu_onyx_plover', null,
|
||||
)
|
||||
return gb?.enabled === true
|
||||
}
|
||||
```
|
||||
|
||||
### 远程配置参数
|
||||
|
||||
`tengu_onyx_plover` feature flag 可配置:
|
||||
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `enabled` | boolean | — | 功能总开关 |
|
||||
| `minHours` | number | 24 | 最小间隔(小时) |
|
||||
| `minSessions` | number | 5 | 最小会话数 |
|
||||
|
||||
### 手动触发 `/dream`
|
||||
|
||||
除了自动触发,用户可以通过 `/dream` 命令手动触发记忆整合。手动触发会调用 `recordConsolidation()` 更新锁文件时间戳。
|
||||
|
||||
---
|
||||
|
||||
## 七、与 extractMemories 的关系
|
||||
|
||||
| 维度 | extractMemories | autoDream |
|
||||
|------|----------------|-----------|
|
||||
| **触发频率** | 每次对话回合结束 | 每 24h + 5 个会话 |
|
||||
| **触发位置** | `stopHooks.ts` L149 | `stopHooks.ts` L155 |
|
||||
| **处理范围** | 当前对话最近的消息 | 多个会话的历史记录 |
|
||||
| **目标** | 提取新记忆 | 整合/去重/修剪已有记忆 |
|
||||
| **人类类比** | 白天随手记笔记 | 睡觉时整理笔记本 |
|
||||
| **共享组件** | `createAutoMemCanUseTool` | `createAutoMemCanUseTool` |
|
||||
| **分叉代理** | 最多 5 turns | 无 turn 限制 |
|
||||
| **转录** | 不记录(`skipTranscript`) | 不记录(`skipTranscript`) |
|
||||
|
||||
### 协作流
|
||||
|
||||
```
|
||||
每次对话结束
|
||||
↓
|
||||
extractMemories → 提取新记忆片段 → 写入 *.md + MEMORY.md
|
||||
↓
|
||||
(积累 24h + 5个会话后)
|
||||
↓
|
||||
autoDream → 回顾所有记忆 + 会话记录
|
||||
↓
|
||||
合并重复 / 修正过时 / 删除矛盾 / 压缩索引
|
||||
↓
|
||||
MEMORY.md 和主题文件焕然一新
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 八、源码导航
|
||||
|
||||
| 文件 | 职责 |
|
||||
|------|------|
|
||||
| `src/services/autoDream/autoDream.ts` | 主逻辑:门控检查、启动分叉代理、进度监控 |
|
||||
| `src/services/autoDream/config.ts` | 开关控制:settings.json 或 GrowthBook |
|
||||
| `src/services/autoDream/consolidationPrompt.ts` | 梦境提示词:4 阶段整合工作流 |
|
||||
| `src/services/autoDream/consolidationLock.ts` | 锁文件机制:防并发、时间戳、回滚 |
|
||||
| `src/tasks/DreamTask/DreamTask.ts` | UI 任务注册:状态管理、终止、回滚 |
|
||||
| `src/tasks/pillLabel.ts` | 底部状态栏标签:"dreaming" |
|
||||
| `src/components/tasks/DreamDetailDialog.tsx` | 梦境详情对话框 UI |
|
||||
| `src/query/stopHooks.ts` | 执行入口:每次回复后触发 |
|
||||
| `src/utils/backgroundHousekeeping.ts` | 初始化入口:`initAutoDream()` |
|
||||
| `src/services/extractMemories/extractMemories.ts` | 共享的 `createAutoMemCanUseTool` |
|
||||
|
||||
---
|
||||
|
||||
## 九、分析事件
|
||||
|
||||
AutoDream 通过以下事件记录运行状态:
|
||||
|
||||
| 事件 | 时机 | 附带数据 |
|
||||
|------|------|----------|
|
||||
| `tengu_auto_dream_fired` | 梦境启动 | `hours_since`, `sessions_since` |
|
||||
| `tengu_auto_dream_completed` | 梦境完成 | `cache_read`, `cache_created`, `output`, `sessions_reviewed` |
|
||||
| `tengu_auto_dream_failed` | 梦境失败 | — |
|
||||
|
After Width: | Height: | Size: 632 KiB |
|
After Width: | Height: | Size: 507 KiB |
|
After Width: | Height: | Size: 474 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 3.5 MiB |
|
After Width: | Height: | Size: 1019 KiB |
|
After Width: | Height: | Size: 1.7 MiB |
|
After Width: | Height: | Size: 2.2 MiB |
|
After Width: | Height: | Size: 816 KiB |
|
After Width: | Height: | Size: 523 KiB |
|
After Width: | Height: | Size: 759 KiB |
|
After Width: | Height: | Size: 482 KiB |
|
After Width: | Height: | Size: 588 KiB |
@@ -0,0 +1,121 @@
|
||||
# Claude Code 记忆系统文档
|
||||
|
||||
> 完整的记忆系统使用指南和实现原理文档
|
||||
|
||||
---
|
||||
|
||||
## 📚 文档目录
|
||||
|
||||
### [01-usage-guide.md](./01-usage-guide.md) — 使用指南
|
||||
|
||||
面向用户的完整使用手册,涵盖:
|
||||
|
||||
- **四种记忆类型**:User(用户画像)、Feedback(行为反馈)、Project(项目动态)、Reference(外部引用)
|
||||
- **四种触发方式**:自动提取、显式请求、`/memory` 命令、`/remember` 命令
|
||||
- **存储格式**:YAML frontmatter + Markdown 内容
|
||||
- **管理操作**:遗忘、忽略、手动编辑、禁用、自定义目录
|
||||
- **生命周期**:从学习到注入,新鲜度管理
|
||||
|
||||
**适合人群**:所有 Claude Code 用户
|
||||
|
||||
---
|
||||
|
||||
### [02-implementation.md](./02-implementation.md) — 实现原理
|
||||
|
||||
面向开发者的技术深度解析,涵盖:
|
||||
|
||||
- **5 大核心模块**:路径解析、提示词构建、记忆扫描、智能检索、自动提取
|
||||
- **路径解析系统**:优先级链、安全校验、启用条件
|
||||
- **系统提示词注入**:`loadMemoryPrompt()` → `buildMemoryLines()`,MEMORY.md 截断策略
|
||||
- **自动记忆提取**:分叉代理、互斥机制、工具权限、合并机制
|
||||
- **智能检索**:`scanMemoryFiles()` → Sonnet 选择 → 新鲜度警告
|
||||
- **代理记忆**:三级作用域(user/project/local)
|
||||
- **团队记忆同步**:Pull/Push API、合并语义
|
||||
- **完整数据流**:从会话启动到上下文注入
|
||||
|
||||
**适合人群**:贡献者、架构师、想深入了解实现的开发者
|
||||
|
||||
---
|
||||
|
||||
### [03-autodream.md](./03-autodream.md) — AutoDream 记忆整合
|
||||
|
||||
Claude 的"做梦"机制——后台静默整合记忆的深度解析,涵盖:
|
||||
|
||||
- **核心概念**:像人类睡眠整理记忆一样,定期回顾多个会话整合知识
|
||||
- **五重门控**:功能开关 → 时间门控(24h) → 扫描节流(10min) → 会话门控(5个) → 锁门控
|
||||
- **四阶段流程**:Orient(定向)→ Gather(收集)→ Consolidate(整合)→ Prune(修剪)
|
||||
- **安全限制**:Bash 只读、写操作仅限记忆目录、PID 锁文件互斥
|
||||
- **UI 展示**:底部 "dreaming" 标签、Shift+Down 详情对话框、完成通知
|
||||
- **配置控制**:settings.json 本地开关 + GrowthBook 远程 feature flag
|
||||
- **与 extractMemories 对比**:白天记笔记 vs 睡觉整理笔记本
|
||||
|
||||
**适合人群**:贡献者、架构师、对 Claude 自动化记忆管理感兴趣的开发者
|
||||
|
||||
---
|
||||
|
||||
## 🖼️ 配图说明
|
||||
|
||||
所有配图采用深色背景(#1a1a2e)+ Anthropic 品牌橙铜色(#D97757)风格,与 Claude Code 官方文档一致。
|
||||
|
||||
| 图片 | 说明 | 尺寸 |
|
||||
|------|------|------|
|
||||
| `01-memory-overview.png` | 记忆系统概览 — 四层架构(触发/类型/存储/检索) | 632 KB |
|
||||
| `02-memory-types.png` | 四种记忆类型 — 2x2 网格展示 User/Feedback/Project/Reference | 507 KB |
|
||||
| `03-memory-trigger.png` | 记忆触发流程 — 从对话到存储的四种路径 | 474 KB |
|
||||
| `04-memory-lifecycle.png` | 记忆生命周期 — 完整循环流程 + 新鲜度判断 | 1.0 MB |
|
||||
| `05-architecture-overview.png` | 实现架构总览 — 5 个核心模块 + 辅助模块 | 3.5 MB |
|
||||
| `06-path-resolution.png` | 路径解析流程 — 三层优先级 + 安全校验 | 1.0 MB |
|
||||
| `07-prompt-injection.png` | 提示词注入流程 — loadMemoryPrompt 分发逻辑 | 1.1 MB |
|
||||
| `08-auto-extraction.png` | 自动提取流程 — 分叉代理完整流程 | 1.2 MB |
|
||||
| `09-memory-retrieval.png` | 智能检索流程 — Sonnet 选择 + 新鲜度管理 | 816 KB |
|
||||
| `10-agent-memory.png` | 代理记忆作用域 — 三级嵌套结构 | 523 KB |
|
||||
| `11-autodream-overview.png` | AutoDream 概览 — 做梦机制的核心架构与人类睡眠类比 | 777 KB |
|
||||
| `12-autodream-trigger.png` | AutoDream 触发流程 — 五重门控检查链 | 493 KB |
|
||||
| `13-autodream-phases.png` | AutoDream 四阶段 — Orient/Gather/Consolidate/Prune | 602 KB |
|
||||
|
||||
---
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 用户
|
||||
|
||||
1. 阅读 [使用指南](./01-usage-guide.md)
|
||||
2. 了解四种记忆类型和触发方式
|
||||
3. 尝试 `/memory` 和 `/remember` 命令
|
||||
|
||||
### 开发者
|
||||
|
||||
1. 阅读 [实现原理](./02-implementation.md)
|
||||
2. 查看源码位置:
|
||||
- `src/memdir/paths.ts` — 路径解析
|
||||
- `src/memdir/memdir.ts` — 提示词构建
|
||||
- `src/memdir/memoryScan.ts` — 记忆扫描
|
||||
- `src/memdir/findRelevantMemories.ts` — 智能检索
|
||||
- `src/services/extractMemories/` — 自动提取
|
||||
3. 理解数据流和模块交互
|
||||
|
||||
---
|
||||
|
||||
## 📝 核心概念速查
|
||||
|
||||
| 概念 | 说明 |
|
||||
|------|------|
|
||||
| **MEMORY.md** | 索引文件,始终加载到上下文(最多 200 行 / 25KB) |
|
||||
| **主题文件** | `*.md` 文件,包含 frontmatter + 内容 |
|
||||
| **自动提取** | 每次回复后后台运行,分叉代理分析对话 |
|
||||
| **AutoDream** | 每 24h + 5 个会话后,后台整合/去重/修剪全部记忆 |
|
||||
| **智能检索** | Sonnet 模型从所有记忆中选择最多 5 个相关的 |
|
||||
| **新鲜度** | ≤1 天无警告,>1 天附带陈旧警告 |
|
||||
| **分叉代理** | 共享提示词缓存,限制工具权限,最多 5 turns |
|
||||
| **三级作用域** | 代理记忆:user(全局)> project(项目)> local(本地) |
|
||||
|
||||
---
|
||||
|
||||
## 🔗 相关资源
|
||||
|
||||
- [Claude Code Haha 主页](/)
|
||||
- [记忆系统源码](https://github.com/NanmiCoder/cc-haha/tree/main/src/memdir/)
|
||||
- [自动提取服务](https://github.com/NanmiCoder/cc-haha/tree/main/src/services/extractMemories/)
|
||||
- [AutoDream 服务](https://github.com/NanmiCoder/cc-haha/tree/main/src/services/autoDream/)
|
||||
- [DreamTask 任务](https://github.com/NanmiCoder/cc-haha/tree/main/src/tasks/DreamTask/)
|
||||
- [GitHub Issues](https://github.com/NanmiCoder/cc-haha/issues)
|
||||