1. 前言
记忆体是Agent从无状态工具 升级为持续智能体的核心基础设施,直接决定自主决策、长期交互与迭代进化能力。
1.1. 记忆体的核心重要性
- 突破上下文限制
弥补LLM固定窗口短板,支持长对话、多步骤任务与跨会话信息复用,避免"中途遗忘"。 - 实现持续学习与经验沉淀
记录成功策略、失败教训与环境规则,让Agent不重复犯错,逐步提升任务成功率。 - 支撑个性化与拟人交互
持久化用户偏好、历史需求与场景习惯,提供连贯、贴心的长期服务体验。 - 赋能自主决策与复杂规划
基于历史记忆做推理、反思与路径优化,完成多跳任务、工具协同与目标拆解。 - 降低计算与Token成本
通过结构化记忆替代全量历史灌入,减少冗余计算,提升响应效率。
1.2. 当前面临的核心挑战
- 容量与效率的平衡难题
记忆库膨胀导致检索延迟飙升;精简记忆又易丢失关键信息,难以兼顾规模与实时性。 - 检索精准度不足
模糊查询下易召回无关记忆,引入噪声;语义匹配与权重分配难以做到类人级精准。 - 记忆一致性与时效性差
新旧信息冲突、偏好更新后旧记忆未失效、事实失真,导致决策矛盾或输出错误。 - 遗忘机制缺失
缺乏类人"主动遗忘"能力,无效信息堆积,关键记忆被淹没,推理效率持续下降。 - 隐私与安全风险
长期记忆存储大量用户敏感数据,面临泄露、滥用与合规风险,权限管控复杂。 - 多Agent协同同步困难
跨智能体记忆不一致、信息不对称,影响团队协作与全局决策可靠性。 - 工程落地成本高
向量库、分层存储、实时更新与清洗链路复杂,开发与运维门槛高。
记忆体是Agent智能化、拟人化、规模化 的必要条件;但在存储、检索、一致性、遗忘、隐私 上仍有显著工程与算法瓶颈,是下一代Agent进化的核心攻坚方向。
我们可以通过学习Claude Code 的内存管理机制,使大模型应用系统在速度、成本和保真度之间寻求动态平衡。
2. 记忆基本信息
2.1. 记忆文件类型
索引文件:MEMORY.md、summary.md
主题文件:各种 .md 记忆文件
配置文件:CLAUDE.md 及其变体
会话记录:.jsonl 格式的对话日志
2.2. 记忆类型(memoryTypes.ts)
系统定义了四种记忆类型:
| 类型 | 用途 | 作用域 |
|---|---|---|
user |
关于用户的身份、角色、目标 | private/team |
feedback |
用户的反馈、偏好、纠正 | private/team |
project |
项目相关的信息、决策、截止日期 | private/team (偏向team) |
reference |
外部系统的指针 (Linear, Slack等) | team (通常) |
2.3. 记忆存储路径(paths.ts)
text
.claude/
├── memory/ # 自动记忆目录
│ ├── MEMORY.md # 记忆索引文件
│ ├── user_role.md # 用户类型记忆
│ ├── feedback_testing.md # 反馈记忆
│ ├── project_release.md # 项目记忆
│ ├── reference_linear.md # 引用记忆
│ ├── logs/ # 日志目录 (KAIROS模式)
│ │ └── YYYY/MM/YYYY-MM-DD.md
│ └── team/ # 团队记忆子目录
│ ├── MEMORY.md
│ └── *.md
└── agent-memory/ # 代理记忆 (用户级)
└── *.md
2.3.1. 会话记忆文件
会话记忆文件系统:
└── {projectDir}/{sessionId}/session-memory/summary.md # 会话摘要
2.3.2. 交互的信息存储位置(sessionStorage.ts)
~/.claude/projects/<project>/transcripts/
└── <session-id>.jsonl
- 每条消息存储为一行 JSON:
json
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"type": "user" | "assistant" | "tool" | "system",
"content": [...],
"parent_uuid": "previous-message-uuid",
"timestamp": "2026-04-09T12:00:00.000Z"
}
2.3.3. 锁文件结构
text
<memoryDir>/.consolidate-lock
├─ mtime: lastConsolidatedAt // 文件修改时间 = 上次整合时间
└─ body: PID // 持有者的进程 ID
2.4. 主要数据结构
typescript
// 记忆文件头信息
export type MemoryHeader = {
filename: string // 文件名 (相对路径)
filePath: string // 完整文件路径
mtimeMs: number // 修改时间 (毫秒时间戳)
description: string | null // 描述 (从 frontmatter)
type: MemoryType | undefined // 类型 (user|feedback|project|reference)
}
// 记忆类型
type MemoryType = 'user' | 'feedback' | 'project' | 'reference'
// 提取上下文
type REPLHookContext = {
messages: Message[]
systemPrompt: SystemPrompt
userContext: { [k: string]: string }
systemContext: { [k: string]: string }
toolUseContext: ToolUseContext
querySource?: QuerySource
}
// 记录 MEMORY.md 截断信息
export type EntrypointTruncation = {
content: string // 截断后的内容
lineCount: number // 行数
byteCount: number // 字节数
wasLineTruncated: boolean // 是否被行截断
wasByteTruncated: boolean // 是否被字节截断
}
// DreamTaskState 类型
export type DreamTaskState = TaskStateBase & {
type: 'dream'
phase: 'starting' | 'updating' // 执行阶段
sessionsReviewing: number // 审查的会话数
filesTouched: string[] // 修改的文件路径
turns: DreamTurn[] // 助手回合
abortController?: AbortController // 中止控制器
priorMtime: number // 锁的先前 mtime
}
2.5. 主要配置和限制
-
ENTRYPOINT_NAME = 'MEMORY.md' // 入口文件名
-
MAX_ENTRYPOINT_LINES: 200行 // 入口文件最大行数
-
MAX_ENTRYPOINT_BYTES: 25KB
-
MAX_MEMORY_FILES: 200个 // 最大记忆文件数
-
MAX_RELEVANT_MEMORIES: 5个
-
MAX_FILE_SIZE_BYTES: 250KB (团队记忆)
-
MAX_PUT_BODY_BYTES: 200KB (团队同步)
-
特性门控
| 特性 | 门控 | 说明 |
|---|---|---|
| 自动记忆 | CLAUDE_CODE_DISABLE_AUTO_MEMORY |
默认启用 |
| 团队记忆 | tengu_herring_clock |
需要自动记忆启用 |
| 记忆提取 | tengu_passport_quail + EXTRACT_MEMORIES |
后台提取 |
| 自动整合 | tengu_onyx_plover |
定期整合 |
| 跳过索引 | tengu_moth_copse |
直接写入文件 |
3. 记忆系统架构
3.1. 记忆流程简图
整个流程图分为三个主要阶段:
- 对话前 -- 加载已有记忆,注入系统提示词。
- 对话中 -- 实时查询相关记忆、回答用户问题、并根据 token 使用情况执行多级压缩。
- 对话后 -- 提取新知识存入记忆,并定期执行 Dream 压缩(合并、修剪、优化记忆)。
对话后
对话中
对话前
注入 MEMORY.md
相关记忆
是
否
是
否
记忆加载
开始对话
用户提问
记忆查询
模型回答
Token 超阈值?
上下文压缩
对话结束
记忆存储
满足 Dream 条件?
记忆压缩 Dream
结束
3.2. 记忆流程详图
这个流程图展示了完整的记忆系统工作流程:
对话后
对话中
对话前
记忆压缩
记忆查询
是
否
达到压缩阈值
是
否
未达到阈值
通过
跳过
满足
不满足
用户发起对话
加载记忆提示词:loadMemoryPrompt()
检查 auto memory 启用状态
读取索引文件:读取 MEMORY.md
构建记忆行与提示词:buildMemoryLines() / buildMemoryPrompt()
注入系统提示词:注入 system prompt
跳过记忆加载
开始对话
用户提出问题
查找相关记忆:findRelevantMemories(query)
扫描记忆文件:scanMemoryFiles()
解析前置元数据:解析 frontmatter
格式化记忆清单:formatMemoryManifest()
模型选择相关记忆 ≤5 个
注入上下文并回答
检查 token 使用情况
HISTORY_SNIP:移除旧消息 【HISTORY_SNIP】
CACHED_MICROCOMPACT:清理过期/大工具结果 【CACHED_MICROCOMPACT】
CONTEXT_COLLAPSE:投影折叠视图 【CONTEXT_COLLAPSE】
token 使用率 ≥87% ?
AutoCompact:调用 compactConversation() 运行压缩代理 【REACTIVE_COMPACT】
生成系统压缩边界消息:SystemCompactBoundaryMessage
对话结束
提取记忆并存储:executeExtractMemories()
检查 feature gate 与频率限制
运行分支代理提取记忆:runForkedAgent() (Extract Agent)
读取对话记录:读取 transcript
写入记忆文件:写入 .md
更新索引:更新 MEMORY.md
跳过记忆提取,直接结束
执行自动梦想压缩:executeAutoDream()
检查时间门 (24h) 与会话门 (≥5 会话)?
获取文件锁:获取锁
运行分支代理整理记忆:runForkedAgent() (Dream Agent)
四阶段压缩:Orient → Gather → Consolidate → Prune
释放锁:释放锁
跳过 Dream 压缩
结束
3.2.1. 对话前:记忆加载
| 节点 | 作用:函数名 | 说明 |
|---|---|---|
| 用户发起对话 | -- | 对话开始 |
| 加载记忆提示词 | loadMemoryPrompt() |
入口函数,负责读取并格式化记忆内容 |
| 检查 auto memory 启用状态 | 条件判断 | 若未启用,跳过记忆加载 |
| 读取索引文件 | 读取 MEMORY.md |
获取记忆索引(所有记忆文件的清单) |
| 构建记忆行与提示词 | buildMemoryLines() / buildMemoryPrompt() |
将 MEMORY.md 内容转换成可注入的文本 |
| 注入系统提示词 | 注入 system prompt | 将记忆提示词合并到系统消息中 |
| 开始对话 | -- | 进入对话循环 |
作用:确保模型在对话开始时已经具备历史记忆的全局视角(例如用户偏好、项目约定等)。
3.2.2. 对话中:记忆查询与多级压缩
3.2.2.1. 记忆查询
| 节点 | 作用:函数名 | 说明 |
|---|---|---|
| 用户提出问题 | -- | 用户输入新消息 |
| 查找相关记忆 | findRelevantMemories(query) |
根据当前查询内容检索相关记忆 |
| 扫描记忆文件 | scanMemoryFiles() |
遍历记忆目录下所有 .md 文件(排除 MEMORY.md) |
| 解析前置元数据 | 解析 frontmatter | 提取 type、description、mtime 等字段 |
| 格式化记忆清单 | formatMemoryManifest() |
将扫描结果整理成模型可读的清单 |
| 模型选择相关记忆 | ≤5 个 | 模型根据清单自主选择最相关的记忆 |
| 注入上下文并回答 | -- | 将选中记忆与当前对话一起提交给模型生成回答 |
作用:实现按需检索,避免将全部记忆塞入上下文,节省 token 并提高相关性。
3.2.2.2. 多级上下文压缩
当 token 使用量达到预设阈值时,按顺序执行四种压缩模式(受各自 feature gate 控制):
| 顺序 | 模式 / 函数 | 作用 |
|---|---|---|
| 1 | HISTORY_SNIP |
移除最早的对话消息,快速释放 token 空间 |
| 2 | CACHED_MICROCOMPACT |
清理过期的工具调用结果,并将体积大的工具结果替换为摘要 |
| 3 | CONTEXT_COLLAPSE |
投影折叠视图:将长对话压缩成更紧凑的表示形式 |
| 4 | AutoCompact(REACTIVE_COMPACT) |
当 token 使用率 ≥87% 时,调用 compactConversation() 运行压缩代理,最终生成 SystemCompactBoundaryMessage 替换原有上下文 |
压缩完成后,对话继续回到用户提问环节,模型基于压缩后的上下文工作。
作用:在长对话中自动管理上下文窗口,防止溢出,同时尽量保留关键信息。
3.2.3. 对话后:记忆存储与 Dream 压缩
3.2.3.1. 记忆提取与存储
| 节点 | 作用:函数名 | 说明 |
|---|---|---|
| 对话结束 | -- | 一轮或多轮对话完成 |
| 提取记忆并存储 | executeExtractMemories() |
入口函数,判断是否执行记忆提取 |
| 检查 feature gate 与频率限制 | 条件判断 | 需要 EXTRACT_MEMORIES 启用,且每 N 轮对话执行一次 |
| 运行分支代理提取记忆 | runForkedAgent() (Extract Agent) |
独立代理,分析对话记录,提取值得长期保存的信息 |
| 读取对话记录 | 读取 transcript | 获取完整的消息历史 |
| 写入记忆文件 | 写入 <memory-name>.md |
每个记忆一个文件,包含 frontmatter 和内容 |
| 更新索引 | 更新 MEMORY.md |
将新记忆的引用添加到索引文件中 |
作用:将对话中的新事实、用户偏好、反馈等转化为持久化记忆文件。
3.2.3.2. Dream 压缩(记忆整理)
| 节点 | 作用:函数名 | 说明 |
|---|---|---|
| 执行自动梦想压缩 | executeAutoDream() |
后台任务,定期整理记忆库 |
| 检查时间门与会话门 | 24h 且 ≥5 个会话 | 防止过于频繁运行 |
| 获取文件锁 / 释放锁 | 获取锁 / 释放锁 | 避免并发冲突 |
| 运行分支代理整理记忆 | runForkedAgent() (Dream Agent) |
执行四阶段压缩: 1. Orient :读取现有记忆 2. Gather :收集新对话日志、检查过时记忆 3. Consolidate :合并相似记忆、删除矛盾事实 4. Prune :精简 MEMORY.md 索引,移除无效指针 |
| 结束 | -- | 流程完成 |
作用:防止记忆库无限膨胀,合并冗余信息,保持记忆库的高质量和可读性。
3.3. 记忆系统总体架构图
Claude Code 记忆架构图
文件系统
记忆处理层 (L1-L5)
交互与编排
Layer 4: 记忆存储层
Layer 3: 记忆压缩层
Layer 5: 记忆整合层
Layer 1: 记忆检索层
Layer 2: 记忆提取层
通过
>= 24h
>= 10min
>= 5 sessions
成功
失败
记忆索引文件
MEMORY.md
用户发起查询
主循环启动
queryLoop
调用大模型 API
queryModel
执行工具调用
runTools
查询结束处理
handleStopHooks
提取入口
executeExtractMemories
执行提取
runExtraction
提示词模板
prompts.ts
自动记忆提示
buildExtractAutoOnlyPrompt
组合记忆提示
buildExtractCombinedPrompt
查找相关记忆
findRelevantMemories
扫描文件
scanMemoryFiles
格式化清单
formatMemoryManifest
选择相关记忆
selectRelevantMemories
初始化整合器
initAutoDream
运行整合流程
runAutoDream
Feature Gate 检查
isGateOpen
时间门检查
readLastConsolidatedAt
扫描节流
10分钟间隔
会话门检查
listSessionsTouchedSince
获取整合锁
tryAcquireConsolidationLock
注册整合任务
registerDreamTask
构建整合提示
buildConsolidationPrompt
运行 Dream Agent
runForkedAgent
完成整合任务
completeDreamTask
记录整合成功
recordConsolidation
失败处理
failDreamTask
回滚锁文件
rollbackConsolidationLock
自动压缩入口
autocompact
自动压缩协调器
autoCompact
压缩核心逻辑
compact
响应式压缩
reactiveCompact
缓存编辑压缩
microcompact
Snip 压缩
snipCompact
Snip 压缩入口
snip
Session Memory 压缩
trySessionMemoryCompaction
获取路径
getAutoMemPath
确保目录存在
ensureMemoryDirExists
截断内容
truncateEntrypointContent
验证路径安全
validateTeamMemWritePath
Agent 记忆提示
loadAgentMemoryPrompt
具体记忆内容
主题文件.md
整合锁文件
.consolidate-lock
对话记录
transcripts
每日日志
daily logs
3.4. 架构层次
| 层次 | 核心文件 | 主要功能 | 关键函数 | 输入 | 输出 |
|---|---|---|---|---|---|
| 记忆检索 | memoryScan.ts, findRelevantMemories.ts | 扫描记忆文件、查找相关记忆 | scanMemoryFiles, formatMemoryManifest, findRelevantMemories, selectRelevantMemories |
记忆目录、查询、已展示记忆 | MemoryHeader[]、相关记忆列表 |
| 记忆提取 | extractMemories.ts, prompts.ts, agentMemory.ts | 从对话中提取持久化记忆、管理 Agent 记忆 | executeExtractMemories, runExtraction, loadAgentMemoryPrompt, buildExtractAutoOnlyPrompt, buildExtractCombinedPrompt |
对话记录、现有记忆、Agent 配置 | 新的记忆文件、Agent 记忆提示 |
| 记忆压缩 | query.ts, autoCompact.ts, compact.ts, reactiveCompact.ts, snipCompact.ts, sessionMemoryCompact.ts | 自动压缩对话上下文、管理 Token 预算 | autocompact, microcompact, snip, trySessionMemoryCompaction, compactConversation |
消息列表、Token 使用情况 | 压缩后的消息、摘要 |
| 记忆存储 | paths.ts, memdir.ts, teamMemPaths.ts | 管理记忆路径、文件存储、路径验证 | getAutoMemPath, ensureMemoryDirExists, truncateEntrypointContent, validateTeamMemWritePath |
路径配置、记忆内容 | 文件路径、截断内容、验证结果 |
| 记忆整合 | autoDream.ts, consolidationPrompt.ts, consolidationLock.ts, memdir.ts | 整合和优化记忆结构、构建记忆提示、管理整合锁 | runAutoDream, buildConsolidationPrompt, readLastConsolidatedAt, tryAcquireConsolidationLock, listSessionsTouchedSince, recordConsolidation, rollbackConsolidationLock |
记忆文件、会话记录、Feature Gate | 整合后的记忆、系统提示、锁状态 |
3.5. 层间关系
交互与编排层
├─ 查询开始 → 记忆检索层(加载记忆提示)
├─ 调用大模型 → 记忆压缩层(Token 预算检查)
├─ 调用大模型 → 记忆检索层(查找相关记忆)
└─ 查询结束 → 记忆提取层(提取新记忆)
记忆提取层
├─ 查询结束 → 记忆检索层(扫描现有记忆)
└─ 写入记忆 → 记忆存储层(更新文件)
记忆检索层
├─ 扫描记忆 → 记忆整合层(提供候选记忆)
└─ 查找相关记忆 → 交互与编排层(返回相关记忆)
记忆压缩层
└─ 压缩消息 → 记忆存储层(更新消息存储)
记忆整合层
├─ 读取记忆 → 记忆检索层(扫描记忆文件)
└─ 整合记忆 → 记忆存储层(更新文件和索引)
记忆存储层
└─ 提供服务 → 所有层(路径管理、文件存储)
4. Layer 1: 记忆检索层
4.1. 模块主要功能
扫描记忆文件,查找相关记忆
4.2. 核心文件和函数
| 函数名 | 文件 | 调用者 | 被调用者 | 作用 |
|---|---|---|---|---|
| scanMemoryFiles | memoryScan.ts | runExtraction, findRelevantMemories, runAutoDream | - | 扫描记忆文件 |
| formatMemoryManifest | memoryScan.ts | runExtraction, findRelevantMemories | scanMemoryFiles | 格式化记忆清单 |
| findRelevantMemories | findRelevantMemories.ts | 模型需要回忆时 | scanMemoryFiles, selectRelevantMemories | 查找相关记忆 |
| selectRelevantMemories | findRelevantMemories.ts | findRelevantMemories | - | 选择相关记忆 |
4.3. 触发条件
- 查询开始时 - 预注入现有记忆列表到提取代理
- 模型需要回忆时 - 查找相关记忆(
findRelevantMemories) - 记忆提取时 - 扫描现有记忆避免重复写入
- 记忆整合时 - 扫描现有记忆供整合代理参考
4.4. 主要参数、约束
- 文件数量限制 : 最多扫描200个文件(
MAX_MEMORY_FILES = 200) - 读取深度限制 : 仅读取前30行获取frontmatter(
FRONTMATTER_MAX_LINES = 30) - 排除规则 : 排除
MEMORY.md文件(索引文件) - 排序规则: 按修改时间降序排列(最新的在前)
- 记忆数量限制: 最多返回5个相关记忆
- 去重过滤 : 排除已经展示过的记忆(
alreadySurfaced) - 工具使用过滤: 如果最近使用了某个工具,不返回该工具的参考文档
4.5. 主要流程
对话记忆
扫描记忆文件
否
是
否
是
排除 MEMORY.md
是
否
是
否
记忆检索请求
检索类型?
findRelevantMemories
scanMemoryFiles
scanMemoryFiles
扫描记忆文件
过滤已展示记忆
alreadySurfaced
有候选记忆?
返回空列表
selectRelevantMemories
Sonnet 选择
formatMemoryManifest
格式化清单
sideQuery
调用 Sonnet 模型
选择成功?
过滤有效文件名
返回 RelevantMemory[]
最多5个
readdir memoryDir
递归扫描
过滤 .md 文件
mdFiles 列表
Promise.allSettled
并行读取文件
readFileInRange
读取前30行
parseFrontmatter
解析元数据
构建 MemoryHeader
成功解析?
添加到结果集
跳过该文件
按 mtimeMs 降序排序
超过 MAX_MEMORY_FILES?
slice 0:200
截断到200个
返回全部
返回 MemoryHeader[]
formatMemoryManifest
格式化为文本清单
5. Layer 2: 记忆提取层
5.1. 模块主要功能
从对话中提取持久化记忆,管理 Agent 记忆
5.2. 核心文件和函数
| 函数名 | 文件 | 调用者 | 被调用者 | 作用 |
|---|---|---|---|---|
| executeExtractMemories | extractMemories.ts | handleStopHooks | runExtraction | 提取入口函数 |
| runExtraction | extractMemories.ts | executeExtractMemories | scanMemoryFiles, buildExtractAutoOnlyPrompt, buildExtractCombinedPrompt, runForkedAgent | 执行提取逻辑 |
| loadAgentMemoryPrompt | agentMemory.ts | Agent 启动 | getAutoMemPath, ensureMemoryDirExists | 加载 Agent 记忆提示 |
| buildExtractAutoOnlyPrompt | prompts.ts | runExtraction | - | 构建自动记忆提示 |
| buildExtractCombinedPrompt | prompts.ts | runExtraction | - | 构建组合记忆提示 |
5.3. 触发条件
- 查询结束 - 通过
handleStopHooks在每次查询循环结束时触发 - Agent 启动时 - 加载 Agent 记忆(
loadAgentMemoryPrompt) - Feature Gate -
EXTRACT_MEMORIES功能必须启用 - 频率限制 - 每N轮查询执行一次(通过
turnsSinceLastExtraction计数) - 互斥检查 - 如果主代理已经直接写入记忆文件,则跳过提取(
hasMemoryWritesSince)
5.4. 主要参数、约束
- Token预算 : 最多5轮(
maxTurns: 5) - 消息范围: 仅处理自上次提取以来的新消息
- 工具权限: 只允许 Read/Grep/Glob/只读 Bash/Edit/Write(仅在记忆目录内)
- 互斥性: 与主代理写入记忆互斥
- Agent 记忆范围: user(用户级)、project(项目级)、local(本地级)
- MEMORY.md 截断: 最多200行/25KB
5.5. 主要流程
否
是
未达到
达到
是
否
是
否
是
否
查询结束
handleStopHooks 触发
Feature Gate 启用?
跳过
频率限制检查
turnsSinceLastExtraction++
主代理已写记忆?
跳过提取
advance cursor
runExtraction
scanMemoryFiles
获取现有记忆
formatMemoryManifest
格式化清单
TEAMMEM 启用?
buildExtractCombinedPrompt
buildExtractAutoOnlyPrompt
构建组合提取提示
构建自动提取提示
runForkedAgent
运行提取代理
提取成功?
extractWrittenPaths
提取写入路径
advance cursor
更新消息UUID
记录事件日志
完成
错误处理
6. Layer 3: 记忆压缩层
6.1. 模块主要功能
自动压缩对话上下文,管理 Token 预算
6.2. 核心文件和函数
| 函数名 | 文件 | 调用者 | 被调用者 | 作用 |
|---|---|---|---|---|
| autocompact | autoCompact.ts | Token 预算检查 | shouldAutoCompact, microcompact, snip, trySessionMemoryCompaction, compactConversation | 自动压缩入口 |
| autoCompact | autoCompact.ts | autocompact | - | 自动压缩协调器 |
| compact | compact.ts | autoCompact, reactiveCompact | - | 压缩核心逻辑 |
| reactiveCompact | reactiveCompact.ts | Prompt Too Long | stripSignatureBlocks, stripRetry | 响应式压缩 |
| snipCompact | snipCompact.ts | - | snip | Snip 压缩 |
| microcompact | microcompact.ts | autocompact | snip | 缓存编辑压缩 |
| snip | snipCompact.ts | microcompact, 手动 /compact | - | Snip 压缩入口 |
| trySessionMemoryCompaction | sessionMemoryCompact.ts | autocompact, 手动 /compact | - | Session Memory 压缩 |
6.3. 触发条件
- Token 预算检查 - 在每次查询迭代开始时检查(
calculateTokenWarningState) - 自动压缩阈值 - 达到
autoCompactThreshold时触发(isAboveAutoCompactThreshold) - 响应式压缩 - 收到
prompt_too_long错误时触发(reactiveCompact) - 手动压缩 - 用户调用
/compact命令时触发
6.4. 主要参数、约束
- 自动压缩缓冲 : 13,000 tokens(
AUTOCOMPACT_BUFFER_TOKENS) - 警告阈值缓冲 : 20,000 tokens(
WARNING_THRESHOLD_BUFFER_TOKENS) - 错误阈值缓冲 : 20,000 tokens(
ERROR_THRESHOLD_BUFFER_TOKENS) - 失败限制 : 最多3次连续失败后停止自动压缩(
MAX_CONSECUTIVE_AUTOCOMPACT_FAILURES = 3) - 摘要输出限制 : 最多20,000 tokens(
MAX_OUTPUT_TOKENS_FOR_SUMMARY) - 递归保护 :
session_memory和compact查询源不触发压缩(避免死锁) - 压缩顺序: Microcompact → Snip → AutoCompact(按此顺序应用)
- Session Memory Compaction 配置 :
minTokens: 压缩后保留的最小 token 数(默认:10,000)minTextBlockMessages: 保留的最小文本块消息数(默认:5)maxTokens: 压缩后保留的最大 token 数(默认:40,000)
6.5. 主要流程
否
是
Microcompact
Snip
AutoCompact
session_memory
是
否
普通会话
是
否
是
否
ReactiveCompact
是
是
否
否
调用大模型 API
Token 预算检查
calculateTokenWarningState
需要压缩?
继续查询循环
压缩策略选择
压缩类型?
deps.microcompact
缓存编辑压缩
基于 tool_use_id
创建边界消息
deps.snip
移除低价值消息
计算释放的 tokens
deps.autocompact
shouldAutoCompact
检查是否需要压缩
会话类型?
trySessionMemoryCompaction
Session Memory Compaction 成功?
使用 Session Memory 作为摘要
compactConversation
setLastSummarizedMessageId undefined
runPostCompactCleanup
更新 tracking 状态
生成摘要消息
构建后压缩消息
runPostCompactCleanup
markPostCompaction
压缩成功?
记录事件日志
更新 messagesForQuery
增加 consecutiveFailures
达到最大失败次数?
停止自动压缩
reactiveCompact.tryReactiveCompact
Prompt Too Long?
stripSignatureBlocks
移除签名块
stripRetry
重试
成功?
返回错误
跳过
7. Layer 4: 记忆存储层
7.1. 模块主要功能
管理记忆路径,文件存储,路径验证
7.2. 核心文件和函数
| 函数名 | 文件 | 调用者 | 被调用者 | 作用 |
|---|---|---|---|---|
| getAutoMemPath | paths.ts | 所有需要记忆路径的操作 | - | 获取自动记忆路径 |
| ensureMemoryDirExists | memdir.ts | getAutoMemPath, loadAgentMemoryPrompt | - | 确保记忆目录存在 |
| truncateEntrypointContent | memdir.ts | 写入 MEMORY.md | - | 截断 MEMORY.md 内容 |
| validateTeamMemWritePath | teamMemPaths.ts | 写入团队记忆前 | - | 验证团队记忆路径安全 |
7.3. 触发条件
- 系统启动时 - 创建记忆目录(
ensureMemoryDirExists) - 写入记忆时 - 代理调用 Write/Edit 工具
- 读取记忆时 - 加载 MEMORY.md 到系统提示
- 路径验证时 - 写入团队记忆前验证路径安全
7.4. 主要参数、约束
- MEMORY.md 行数限制 : 最多200行(
MAX_ENTRYPOINT_LINES = 200) - MEMORY.md 字节数限制 : 最多25KB(
MAX_ENTRYPOINT_BYTES = 25_000) - 路径安全验证 :
- 拒绝相对路径(防止
..遍历) - 拒绝根路径或近根路径
- 拒绝 UNC 路径
- 拒绝包含 null byte 的路径
- 拒绝 URL 编码的遍历攻击
- 拒绝 Unicode 规范化攻击
- 拒绝相对路径(防止
- 团队记忆额外验证 :
- 符号链接解析(
realpathDeepestExisting) - 防止符号链接逃逸攻击
- 检测悬挂符号链接
- 符号链接解析(
7.5. 主要流程
路径验证流程
通过
失败
通过
失败
validateTeamMemWritePath
sanitizePathKey
清理路径键
resolve
解析路径
字符串级包含检查
realpathDeepestExisting
解析最深存在祖先
抛出 PathTraversalError
isRealPathWithinTeamDir
检查真实路径包含
返回验证路径
存储路径
Auto Memory
Team Memory
Agent Memory
CLAUDE_COWORK_MEMORY_PATH_OVERRIDE
autoMemoryDirectory setting
默认
是
否
行数 > 200
字节数 > 25KB
否
记忆存储请求
路径类型?
getAutoMemPath
getTeamMemPath
getAgentMemoryDir
路径覆盖?
使用覆盖路径
使用设置路径
计算默认路径
memoryBase/projects/gitRoot/memory/
validateTeamMemWritePath
验证路径安全
getAgentMemoryDir
user/project/local
ensureMemoryDirExists
确保目录存在
写入 MEMORY.md?
truncateEntrypointContent
截断内容
直接写入主题文件
超过限制?
截断到200行
截断到25KB
保持原样
添加警告信息
写入文件
完成
8. Layer 5: 记忆整合层
8.1. 模块主要功能
整合和优化记忆结构,管理整合锁
8.2. 核心文件和函数
| 函数名 | 文件 | 调用者 | 被调用者 | 作用 |
|---|---|---|---|---|
| initAutoDream | autoDream.ts | 系统启动 | - | 初始化整合器 |
| runAutoDream | autoDream.ts | 后台任务 | isGateOpen, readLastConsolidatedAt, listSessionsTouchedSince, tryAcquireConsolidationLock, registerDreamTask, buildConsolidationPrompt, runForkedAgent | 运行整合流程 |
| isGateOpen | autoDream.ts | runAutoDream | - | Feature Gate 检查 |
| readLastConsolidatedAt | consolidationLock.ts | runAutoDream | - | 时间门检查 |
| listSessionsTouchedSince | consolidationLock.ts | runAutoDream | - | 会话门检查 |
| tryAcquireConsolidationLock | consolidationLock.ts | runAutoDream | - | 获取整合锁 |
| registerDreamTask | DreamTask.ts | runAutoDream | - | 注册整合任务 |
| buildConsolidationPrompt | consolidationPrompt.ts | runAutoDream | - | 构建整合提示 |
| runForkedAgent | forkedAgent.ts | runAutoDream | - | 运行 Dream Agent |
| completeDreamTask | DreamTask.ts | runAutoDream | - | 完成整合任务 |
| failDreamTask | DreamTask.ts | runAutoDream | - | 失败处理 |
| rollbackConsolidationLock | consolidationLock.ts | runAutoDream | - | 回滚锁文件 |
| recordConsolidation | consolidationLock.ts | 手动 /dream | - | 记录整合成功 |
8.3. 触发条件
- 时间门 : 距离上次整合 >= 24小时(
minHours: 24) - 会话门 : 至少有5个新会话(
minSessions: 5) - 锁机制: 成功获取整合锁(避免并发冲突)
- Feature Gate :
tengu_onyx_plover和isAutoDreamEnabled()启用 - 手动触发 : 用户调用
/dream命令时触发
8.4. 主要参数、约束
- 扫描节流 : 10分钟内不重复扫描会话(
SESSION_SCAN_INTERVAL_MS = 10min) - 四阶段流程 :
- Phase 1: Orient - 读取现有记忆和索引
- Phase 2: Gather - 收集daily logs和transcript
- Phase 3: Consolidate - 合并相似记忆,删除矛盾事实
- Phase 4: Prune - 精简MEMORY.md索引
- 工具权限: 与提取层相同的限制
- 锁机制 : 使用文件锁(
.consolidate-lock)防止并发 - 记忆提示模式 :
- TEAMMEM: 组合提示(auto + team)
- KAIROS: 每日日志提示(append-only)
- 标准: 标准提示(MEMORY.md 索引)
8.5. 主要流程
锁文件机制
.consolidate-lock
内容: 进程 PID
mtime = 上次整合时间
路径: getAutoMemPath/.consolidate-lock
运行流程
否
是
< 24h
>= 24h
< 10min
>= 10min
< 5 sessions
>= 5 sessions
失败
成功
是
否
runAutoDream 触发
Feature Gate 启用?
跳过
readLastConsolidatedAt
时间门检查
>= 24h?
扫描节流
>= 10min?
listSessionsTouchedSince
会话门检查
>= 5 sessions?
tryAcquireConsolidationLock
获取锁成功?
buildConsolidationPrompt
runForkedAgent
运行 Dream Agent
Phase 1: Orient
读取 MEMORY.md
Phase 2: Gather
读取 daily logs
Phase 3: Consolidate
合并记忆
Phase 4: Prune
精简索引
整合成功?
recordConsolidation
更新锁文件 mtime
显示改进消息
完成
rollbackConsolidationLock
回滚锁文件 mtime
9. 总结
这套系统让它可以:
- 做大型项目开发
- 连续几天迭代同一个代码库
- 记住你的习惯、项目结构、踩过的坑
- 真正像一个工程师一样工作
这才是 Claude Code 强于其他代码助手的根本原因,而不只是模型底座更强。