跳转到内容

抗压缩状态持久化——Notepad 与 Project Memory

学习目标

  • 理解上下文压缩(Context Compaction)对 Agent 持续性的影响
  • 掌握 Notepad 和 Project Memory 的两层抗压缩设计
  • 设计自己的 PreCompact Hook 策略
  • 识别 Notepad 膨胀和信息遗漏的陷阱

前置知识

短期/长期记忆分层与文件系统存储方案已在通用知识中介绍:

下文假设你已理解记忆分层的基础概念,直接聚焦 OMC 的 抗压缩持久化模式——如何在上下文被截断时保留关键信息。

项目实践

上下文压缩的本质问题

当 Agent 对话过长时,系统会自动压缩上下文——删除早期消息以腾出空间。这导致 Agent 丢失:

  • 关键决策记录
  • 正在进行的工作状态
  • 用户偏好和约束
  • 多 Agent 编队的进度

OMC 的解决方案是主动保存 + 自动恢复:在压缩发生前写入持久化存储,压缩后通过 Hook 恢复。

三层抗压缩存储

层级存储文件保留策略典型内容
Notepad.omc/notepad.md永久保留(手动清理)工作记忆、高优先级笔记
Project Memory.omc/project-memory.json跨会话持久化项目知识、架构决策
Plan Notepad.omc/notepads/{plan-name}/按 Plan 隔离每个执行计划的 learnings、decisions

PreCompact Hook 的工作流程

  1. 触发:Claude Code 决定压缩上下文前,触发 PreCompact 事件
  2. 收集:OMC 的 pre-compact.mjs Hook 在 10 秒超时内收集关键信息
  3. 写入:通过 notepad_write_working 写入工作记忆,通过 project-memory-precompact 快照项目记忆
  4. 压缩:Claude Code 执行压缩——早期消息被删除
  5. 恢复SessionStart Hook 读取 Notepad 内容,通过 <system-reminder> 注入恢复的信息

控制面与数据面的分离

OMC 将状态分为两类:

  • 控制面.omc/state/):队列状态、Worker 分配、会话状态——小且频繁读写
  • 数据面.omc/plans/.omc/notepads/.omc/prompts/):大持久化产物——通过 Descriptor 引用

Artifact Descriptor 模式:当控制面需要引用大产物时,使用 Descriptor 而非直接内联内容:

字段用途
kind产物类别(plan、prompt、result、trace)
path持久化路径
sizeBytes?负载大小(用于阈值决策)
retention清理/归属生命周期提示

边界规则:小负载内联(当调用方阈值允许时),大负载使用 Descriptor + 简短人类可读摘要。

会话级状态隔离

OMC 支持多个会话同时运行同一项目,通过 .omc/state/sessions/{sessionId}/ 实现状态隔离:

.omc/state/sessions/abc123/prd.json ← 会话 A 的 PRD
.omc/state/sessions/def456/prd.json ← 会话 B 的 PRD(互不干扰)

问题与规避

问题 1:Notepad 膨胀

如果不定期清理,Notepad 会积累过时信息,浪费上下文窗口。

规避策略:OMC 提供了 notepad_prune 工具自动清理旧条目。notepad_write_priority 写入的条目不受自动清理影响。

问题 2:关键信息遗漏

PreCompact Hook 只有 10 秒超时,可能来不及收集所有关键信息。

规避策略:Hook 按优先级收集信息——Notepad 内容优先,Project Memory 次之。如果时间不足,至少保留最高优先级的信息。

问题 3:Descriptor 过期

Descriptor 引用的实际文件可能被删除或修改,导致引用失效。

规避策略:Descriptor 包含 retention 生命周期提示和可选的 contentHash 完整性校验。清理脚本会检查 Descriptor 引用关系。

设计取舍

为什么选择文件系统而非数据库?

维度文件系统数据库
可读性高——人类可直接阅读和编辑低——需要工具查询
版本控制高——Git 可追踪变更低——数据库变更不在 Git 中
查询能力低——需要解析文件高——SQL 查询
并发性低——需要文件锁高——事务隔离

OMC 的选择:Notepad 和 Project Memory 使用文件系统(.omc/ 目录),因为它们是面向人类可审计的设计决策。对于需要高并发查询的状态(如 Team 编队状态),OMC 使用 SQLite(better-sqlite3)。

为什么不使用 <remember> 标签作为主要持久化?

<remember> 标签(7 天/永久保留)由 Claude Code 原生支持,但 OMC 选择了 Notepad + Project Memory 作为主要持久化。原因是 <remember> 标签在压缩时可能不被正确处理,而 Notepad 是确定性恢复的。

参考来源