File size: 7,154 Bytes
eeeb2b6 96f34e3 eeeb2b6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | # 自动记忆系统
## 概述
Codev 拥有一个基于文件的持久化记忆存储系统(Memdir),允许 Agent 在不同会话间记住用户信息、偏好、项目上下文等。记忆存储在项目对应的 `~/.claude/projects/<slug>/memory/` 目录中。
---
## Memdir 系统
### 目录结构
```
~/.claude/projects/<project-slug>/memory/
├── MEMORY.md # 入口索引文件
├── user_role.md # 用户类型记忆文件
├── feedback_testing.md # 反馈类型记忆文件
├── project_deadlines.md # 项目类型记忆文件
└── reference_dashboards.md # 参考类型记忆文件
```
### 记忆类型
系统定义了四种记忆类型(`src/memdir/memoryTypes.ts`),限制为无法从项目当前状态推导出的信息:
| 类型 | 用途 | 示例 |
|------|------|------|
| **user** | 用户角色、职责、知识背景 | "用户是资深 Go 开发者,首次接触 React" |
| **feedback** | 用户对工作方式的指导 | "不要 mock 数据库——测试必须用真实数据库" |
| **project** | 项目上下文、目标、事件 | "2026-03-05 之后冻结所有非关键合并" |
| **reference** | 外部系统的指针 | "Pipeline bugs 在 Linear 项目 INGEST 中跟踪" |
### 不应该保存的内容
- 代码模式、架构、文件路径——这些可从当前项目状态推导
- Git 历史、最近的变更——`git log` / `git blame` 是权威来源
- 调试解决方案——修复在代码中,commit message 包含上下文
- 已在 CLAUDE.md 中记录的内容
- 临时任务细节——进行中的工作、临时状态
---
## MEMORY.md 入口索引
### 文件规范
MEMORY.md 是记忆系统的入口索引文件(非记忆本身):
- 路径:`<memoryDir>/MEMORY.md`
- 最大行数:**200 行**(`MAX_ENTRYPOINT_LINES`)
- 最大字节数:**25,000 字节**(`MAX_ENTRYPOINT_BYTES`)
- 格式:每行一个条目:`- [Title](file.md) — 简短描述`
- 超过限制时自动截断并追加警告
### 截断策略
定义于 `src/memdir/memdir.ts` 的 `truncateEntrypointContent()`:
1. 首先按行数截断(保留前 200 行)
2. 然后按字节数截断(在最后一个换行符处切割,避免中断行)
3. 追加截断警告说明原因
---
## 记忆生命周期
### 保存(Save)
两种保存方式:
1. **显式请求**:用户要求 Agent 记住某事时立即保存
2. **系统自动提取**:通过 `extractMemories`(`src/services/extractMemories/extractMemories.ts`)在后台自动提取有价值的记忆
保存是两步过程:
1. 写入记忆文件(如 `user_role.md`),使用 frontmatter 格式
2. 在 `MEMORY.md` 中添加指向该文件的索引条目
### Frontmatter 格式
```markdown
---
name: {{记忆名称}}
description: {{一行描述——用于判断相关性,越具体越好}}
type: {{user / feedback / project / reference}}
---
{{记忆内容 — 对于 feedback/project 类型,结构为:规则/事实,然后 **Why:** 和 **How to apply:** 行}}
```
### 检索(Recall)
`findRelevantMemories()`(`src/memdir/findRelevantMemories.ts`)使用 Sonnet 模型选择与当前查询相关的记忆:
1. 扫描记忆目录中的所有文件,提取文件名和描述
2. 将查询和可用记忆清单发送给 Sonnet 模型
3. 模型返回最相关的记忆文件名列表(最多 5 个)
4. 返回绝对文件路径和 mtime
```typescript
export async function findRelevantMemories(
query: string, // 用户查询
memoryDir: string, // 记忆目录路径
signal: AbortSignal, // 取消信号
recentTools?: string[], // 最近使用的工具(过滤不相关的 API 文档)
alreadySurfaced?: Set<string>, // 已展示的文件(避免重复选择)
): Promise<RelevantMemory[]>
```
**选择性过滤**:
- 排除已在对话中展示的文件(`alreadySurfaced`)
- 排除最近正在使用的工具的参考文档
- 仍选择包含警告、陷阱、已知问题的记忆
### 更新(Update)
- 记忆文件的内容可以直接覆盖
- MEMORY.md 中的索引条目保持最新
- 语义而非时间顺序组织记忆
### 清除(Delete)
用户要求忘记时,找到并删除相关条目(记忆文件 + MEMORY.md 索引)。
---
## 记忆 Age(新鲜度追踪)
### mtime 追踪
每个记忆文件都有 `mtimeMs`(修改时间戳),在检索时返回:
```typescript
export type RelevantMemory = {
path: string
mtimeMs: number
}
```
### 新鲜度提示
- `MEMORY_DRIFT_CAVEAT`:记忆会随时间过时。在基于记忆回答前,需验证记忆是否仍准确
- 如果回忆的记忆与当前信息冲突,信任当前观察,更新或移除过时记忆
### 记忆推荐前的验证
即使回忆到的记忆命名了特定函数、文件或标志,也只是"在写入时存在"的声明。在推荐前:
- 如果记忆提到文件路径:检查文件是否存在
- 如果记忆提到函数或标志:通过 grep 确认
- 如果用户即将基于推荐采取行动:先验证
---
## 高级特性
### 团队记忆(Team Memory)
通过 `TEAMMEM` feature gate 启用。使用 `getTeamMemPath()`(`src/memdir/teamMemPaths.ts`)获取团队记忆目录路径。
团队记忆和私有记忆使用不同的作用域标签(`<scope>`),共享相同的四种记忆类型。
### 助手模式每日日志(Assistant Daily Log)
通过 `KAIROS` feature gate 启用。长期运行的助手模式的记忆策略:
- 按日期追加到 `logs/YYYY/MM/YYYY-MM-DD.md`
- 夜间 `/dream` 技能将日志蒸馏为主题文件 + MEMORY.md
- 避免在长时间会话中频繁重写 MEMORY.md
### 自动 Dream(Auto Dream)
`src/services/autoDream/autoDream.ts` 在后台自动执行记忆整理,包括:
- 合并重复记忆
- 更新过时信息
- 清除无关条目
### 团队记忆同步(Team Memory Sync)
`src/services/teamMemorySync/` 提供团队记忆的实时同步功能,包括文件监控(watcher)和秘密保护(secret guard)。
---
## 配置文件
### 路径解析
`getAutoMemPath()`(`src/memdir/paths.ts`)的路径解析顺序:
1. `CLAUDE_COWORK_MEMORY_PATH_OVERRIDE` 环境变量(完全路径覆盖)
2. `autoMemoryDirectory` 设置(来自 settings.json 的可信源)
3. `<memoryBase>/projects/<sanitized-git-root>/memory/`
### 启用/禁用
禁用链(优先级从高到低):
1. `CLAUDE_CODE_DISABLE_AUTO_MEMORY=1/true` 环境变量
2. `CLAUDE_CODE_SIMPLE`(--bare 模式)
3. 远程模式但未设置 `CLAUDE_CODE_REMOTE_MEMORY_DIR`
4. `autoMemoryEnabled: false` 在 settings.json 中
5. 默认:启用
### 核心文件
| 文件 | 路径 | 用途 |
|------|------|------|
| memdir.ts | `src/memdir/memdir.ts` | 记忆提示构建、入口索引管理 |
| paths.ts | `src/memdir/paths.ts` | 路径解析、启停检查 |
| findRelevantMemories.ts | `src/memdir/findRelevantMemories.ts` | 基于 Sonnet 的相关记忆检索 |
| memoryTypes.ts | `src/memdir/memoryTypes.ts` | 记忆类型定义和提示文本 |
| memoryScan.ts | `src/memdir/memoryScan.ts` | 记忆文件扫描 |
|