feat: 引入动态记忆系统(append-only 原子记忆 + 溯源 + 上下文预算召回)作为 Maker Memory 演进方向
- Dominant language
- TypeScript
- Stars
- 2.7k
- Forks
- 401
- Avg merge
- 21h 48m
- Merged PRs (30d)
- 776
Description
### 使用场景 / Use case
Cindy 的跨会话记忆(Maker Memory,`cindy_memory` MCP)是「共享、跨 agent、按工作目录隔离」的长期记忆层,但按 `#205` 的 14 天实测审计,当前实现存在系统性结构问题:**写多读少、召回近乎为零、纯发现开销占全部记忆调用近 40%**;`#1537` 又暴露 FTS5 对中文查询几乎完全失效。
这背后的深层原因是存储模型本身:记忆以「分片文件 + 扁平索引」组织,缺少**稳定原子标识、来源溯源、变更历史与删除墓碑**,导致 agent 只能反复整片重读、无法按名召回、无法解释「这条记忆从哪来、为何可信」。希望引入一套**追加式(append-only)、原子化、可溯源、上下文预算受限**的动态记忆系统,把记忆从「可读的文件」升级为「可解释、可纠错、可回滚、可重建的资产」。
### 当前问题 / Current limitation
- **召回近乎为零**:`#205` 审计中 299 个 Codex 会话 **0 次**按名引用记忆分片;真正的「回忆式消费」接近 0,写入侧却有 55 次 `memory_write` + 大量同分片重复写。
- **发现开销巨大**:`list_tools` + `tool_search` 等渐进发现占全部记忆调用近 40%,每次记忆操作都走 4~5 次发现。
- **检索不可靠**:`#1537` 表明 FTS5 `unicode61` tokenizer 不分词 CJK,中文查询几乎全部失效(`#1912` 已用 LIKE 兜底修复部分场景,但索引切词仍不健康)。
- **无溯源、无历史**:更新即覆盖、删除即消失,没有稳定 atom ID / event 链,无法回答「这条记忆何时、由谁、在哪个会话确认的」,也无法回滚。
- **无上下文预算**:召回没有 token 预算约束,长记忆直接膨胀上下文(相关 `#1853`:1M 上下文在约 250k tokens 即提前触发压缩)。
- **接管冲突**:`#1652` 显示 maker-memory 接管后,原生 per-cwd memory 的 96 条历史规则静默失效且无提示。
### 期望方案 / Proposed solution
参照设计文档 **dynamic-memory-system.md**(append-only 原子记忆 + 溯源 + 墓碑 + 上下文预算召回),分阶段适配到现有 Maker Memory,保持工具面兼容:
1. **原子模型**:每条记忆 = 一个 atom(`id / kind / scope / statement / confidence / state / source / links / timestamps`)。现有分片文件可投影为 atom,不丢历史数据。
2. **追加式日志(journal)**:写入走 append-only event;**更新 = 创建 successor**(`supersedes` 链接),**删除 = 写 tombstone**,保留原始事件与 hash,支持重建与回滚。
3. **作用域细化**:`global / project / session / private`;`project` 默认对齐现有 per-cwd 隔离,`global` 承载跨目录用户偏好。
4. **召回改造**:FTS(顺带修正中文切词 / 保留 LIKE 兜底)+ 可选向量/图增强 → 按 scope/state/权限过滤 → 重排 → **按 token 预算注入**(小索引 + 顶部 atoms + 稳定引用),不整片灌入。
5. **集群与摘要**:`clusters/` 动态聚合相关原子,大簇生成 `summary` atom(`derived_from` 链接),替代「单个 MEMORY.md 越滚越大」。
6. **工具面兼容**:保留 `memory_write / memory_read / memory_search`,按 `#205` 建议给 `memory_write` 增加 upsert 语义、压缩「create 撞名 → update → 先 read」的多轮仪式。
7. **索引可重建**:journal 为唯一真相源,`atoms / clusters / views / INDEX` 均可从 journal 重放重建,故障时可恢复。
本 issue 定位为**方向与兼容性讨论**(遵循 CONTRIBUTING 对较大架构变更先讨论的建议),欢迎维护者与社区对存储模型、迁移路径、工具语义发表意见;确认方向后再进入实现。
### 已考虑的替代方案 / Alternatives considered
- **维持现状 + 增量优化**(采纳 `#205` 的顶层注册、upsert 等建议):可短期止血,但无法解决溯源、回滚、上下文预算等结构性问题,属于治标。
- **直接引入向量库做语义召回**:对「可解释、可溯源、可重建」的要求并非必需,且增加部署与模型成本;更适合作为 FTS 之上的增强层而非主存储。
- **引入外部记忆服务 / 专用记忆 API**:与 Cindy 本地优先、开箱即用的定位冲突,且引入新的运行时依赖。
- **依赖各 agent 原生记忆**(Claude Code / Codex 各自记忆):无法跨 agent 共享,与「Cindy 主开关 = 共享记忆」的产品设计直接矛盾。
Contributor guide
Research direction
Start with dynamic-memory-system.md, then trace the existing memory_write, memory_read, and memory_search entry points and the FTS5/LIKE search behavior described in the issue. Done means reaching a maintainer-approved storage model and migration plan that preserves tool compatibility, supports provenance and tombstones, and enforces context budgets; implementation should follow only after that discussion.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- sqlite, typescript
- Domain
- ai, backend, databases
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100