第14章 · 四层记忆架构
第14章 · 四层记忆架构
Claude Code实现了一个四层记忆系统,从短期会话记忆到长期团队知识,形成了一个完整的AI认知记忆层次结构。
14.1 Session Memory:会话内周期性提取
services/SessionMemory/sessionMemory.ts实现了会话级别的记忆提取,维护一个Markdown文件记录会话中的关键信息。
触发阈值(sessionMemoryUtils.ts):
minimumMessageTokensToInit: 10,000 tokens — 初始阈值,上下文达到此规模才开始提取minimumTokensBetweenUpdate: 5,000 tokens — 两次提取之间的最小上下文增长toolCallsBetweenUpdates: 3 — 两次提取之间的最小工具调用次数
触发决策逻辑:
export function shouldExtractMemory(messages: Message[]): boolean {
// 阶段1:初始化检查
if (!isSessionMemoryInitialized()) {
if (!hasMetInitializationThreshold(currentTokenCount)) return false
markSessionMemoryInitialized()
}
// 阶段2:双条件触发
const hasMetTokenThreshold = hasMetUpdateThreshold(currentTokenCount)
const hasMetToolCallThreshold =
toolCallsSinceLastUpdate >= getToolCallsBetweenUpdates()
const hasToolCallsInLastTurn = hasToolCallsInLastAssistantTurn(messages)
return (hasMetTokenThreshold && hasMetToolCallThreshold) ||
(hasMetTokenThreshold && !hasToolCallsInLastTurn)
}这个双条件设计非常精妙:
- Token增长 且 工具调用足够多 → 触发(活跃的工具使用阶段)
- Token增长 且 最后一轮没有工具调用 → 触发(对话转折点,适合总结)
Forked Agent模式:
记忆提取通过runForkedAgent()执行,创建一个隔离的子Agent:
- 共享父级的prompt cache以提高效率
- 通过
createMemoryFileCanUseTool()限制编辑范围仅限记忆文件 querySource标记为'session_memory'用于分析追踪- 提取超时:
EXTRACTION_WAIT_TIMEOUT_MS = 15,000(15秒) - 过期阈值:
EXTRACTION_STALE_THRESHOLD_MS = 60,000(1分钟后视为过期)
特性门控:
- GrowthBook标志:
tengu_session_memory(缓存读取,非阻塞) - 远程配置:
tengu_sm_config提供动态阈值调整 - 通过memoized的
initSessionMemoryConfigIfNeeded()实现懒初始化
14.2 Memdir:MEMORY.md入口与结构化目录
memdir/模块实现了持久化的记忆目录系统。
目录定位(paths.ts):
// 解析优先级:
// 1. CLAUDE_COWORK_MEMORY_PATH_OVERRIDE 环境变量
// 2. settings.json 中的 autoMemoryDirectory
// 3. ~/.claude/projects/<sanitized-git-root>/memory/MEMORY.md约束(memdir.ts):
- 入口文件名:
MEMORY.md - 最大行数:200行(超出时截断并附加警告)
- 最大字节数:25,000(防止超长行导致的索引问题)
- 截断提示:
> WARNING: MEMORY.md is X lines (limit: 200). Only part of it was loaded.
记忆类型分类法(memoryTypes.ts):
export const MEMORY_TYPES = [
'user', // 用户角色、目标、偏好、知识(始终私有)
'feedback', // 工作方式指导(私有或团队)
'project', // 进行中的工作、目标、Bug(偏向团队)
'reference', // 外部系统的指针(通常团队)
] as const每种类型都有明确的作用域定义:
user— 始终私有,不同步到团队feedback— 默认私有,可选择共享project— 偏向团队共享reference— 通常为团队级别
记忆新鲜度追踪(memoryAge.ts):
export function memoryAgeDays(mtimeMs: number): number {
return Math.max(0, Math.floor((Date.now() - mtimeMs) / 86_400_000))
}超过1天的记忆会附加新鲜度警告,提醒Claude记忆可能已过期。这解决了"AI幻觉记忆"的问题——Claude不会盲目信任陈旧的记忆,而是以适当的置信度使用它们。
记忆指导Section中包含了一个特别值得注意的"不应保存"清单:
- 不保存代码模式(代码本身就是最好的文档)
- 不保存Git历史(可以随时查询)
- 不保存架构(应该从CLAUDE.md获取)
以及"信任召回"验证指南:在使用记忆进行推荐之前,先验证记忆内容是否仍然准确。
14.3 Magic Docs:AI自动维护的文档
services/MagicDocs/magicDocs.ts实现了一个独特的概念——AI自动维护的文档。
检测模式:
const MAGIC_DOC_HEADER_PATTERN = /^#\s*MAGIC\s+DOC:\s*(.+)$/im
const ITALICS_PATTERN = /^[_*](.+?)[_*]\s*$/m当Claude读取一个文件时,如果文件头部包含# MAGIC DOC: [标题]标记,该文件就会被注册为Magic Doc。之后,Claude会使用专门的Sonnet模型Agent定期更新这些文件。
更新流程:
- 通过
registerFileReadListener()在文件被读取时注册 - 克隆
FileStateCache隔离操作 - 重新读取文件内容,检测header和instructions
- 如果header丢失,取消跟踪
- 构建更新prompt,包含检测到的标题和指令
- 使用Sonnet模型和仅FileEdit工具的Agent执行更新
Agent约束:
- 模型:强制使用
'sonnet' - 工具:仅允许
FILE_EDIT_TOOL_NAME - 文件范围:通过
canUseTool检查精确匹配文件路径
Magic Docs的设计理念是让AI维护一类"活的文档"——例如变更日志、依赖版本追踪、或API端点清单,这些文档需要随代码变化而更新,但人类开发者经常忘记维护。
14.4 Team Memory Sync:团队知识同步
services/teamMemorySync/实现了跨团队成员的记忆同步。
同步语义:
export type SyncState = {
lastKnownChecksum: string | null
serverChecksums: Map<string, string> // 每个key的sha256哈希
serverMaxEntries: number | null // 413响应时的服务端上限
}- Pull:服务端优先(per-key覆盖本地)
- Push:增量上传(仅哈希不同的key)
- 删除:不传播(本地删除不等于服务端删除)
API契约:
GET /api/claude_code/team_memory?repo={owner/repo}
→ TeamMemoryData(包含entryChecksums)
PUT /api/claude_code/team_memory?repo={owner/repo}
→ 上传条目(upsert语义)大小限制:
- 单条目上限:250,000字节
- PUT请求体上限:200,000字节(超出时分批发送)
- 最大重试次数:3次(冲突重试2次)
14.5 秘密扫描:上传前的安全屏障
teamMemorySync/secretScanner.ts实现了35+条基于gitleaks规则的秘密扫描,在记忆上传到团队服务器之前进行安全检查。
覆盖的秘密类型包括:
- 云提供商:AWS、GCP、Azure、DigitalOcean
- AI API:Anthropic、OpenAI、HuggingFace
- 版本控制:GitHub、GitLab
- 通信:Slack、Twilio、SendGrid
- 开发工具:npm、PyPI、Databricks、Terraform
- 可观测性:Grafana、Sentry
- 支付:Stripe、Shopify
- 加密:私钥
扫描流程:
export function scanForSecrets(content: string): SecretMatch[] {
const matches: SecretMatch[] = []
const seen = new Set<string>()
for (const rule of getCompiledRules()) {
if (seen.has(rule.id)) continue // 每条规则最多一个匹配
if (rule.re.test(content)) {
seen.add(rule.id)
matches.push({ ruleId: rule.id, label: ruleIdToLabel(rule.id) })
}
}
return matches
}如果检测到秘密,上传被阻止并警告用户。redactSecrets()函数用于将匹配的秘密替换为[REDACTED]标记以供安全持久化。
14.6 记忆提取Agent
services/extractMemories/extractMemories.ts是记忆系统的"收割者"——在每次查询循环结束时(最终响应中无工具调用时),通过handleStopHooks触发记忆提取。
工具范围: 提取Agent拥有比Dream更宽泛的工具权限:FileEdit、FileRead、FileWrite、Glob、Grep、Bash、REPL。
智能去重:
// 如果主Agent已经写入了自动记忆目录,跳过后台提取
if (hasMemoryWritesSince(messages, lastExtractionUuid)) {
runExtraction.skip()
lastExtractionUuid = lastMessageUuid
return
}这个保护机制避免了重复记忆写入——如果主Agent在对话中已经主动保存了记忆(主Agent的prompt包含完整的保存指令),后台提取Agent就没有必要再次运行。
14.7 四层记忆架构总结
| 层级 | 存储位置 | 触发机制 | 生命周期 | 共享范围 |
|---|---|---|---|---|
| Session Memory | 临时文件 | 10K tokens初始化 + 5K增量 | 会话内 | 仅当前会话 |
| Memdir (MEMORY.md) | ~/.claude/projects/.../memory/ | 手动或提取Agent | 持久化 | 个人 |
| Magic Docs | 项目内文件 | 文件读取时注册 | 持久化 | 项目 |
| Team Memory Sync | 云端API | 手动或后台同步 | 持久化 | 团队 |
| Dream巩固 | ~/.claude/projects/.../memory/ | 24h + 5会话 | 持久化 | 个人 |
这个四层架构的设计灵感明显来自认知科学中的记忆层次理论:
- Session Memory ≈ 工作记忆(Working Memory):容量有限、快速衰减
- Memdir ≈ 情景记忆(Episodic Memory):个人经历的记录
- Magic Docs ≈ 语义记忆(Semantic Memory):结构化的知识
- Team Memory ≈ 集体记忆(Collective Memory):团队共享的知识
- Dream ≈ 记忆巩固(Memory Consolidation):从短期到长期的转化过程