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` | 记忆文件扫描 |