Memory 去重与冲突检测
wesgine 记忆系统的内容去重机制和条目间冲突检测。
内容去重
ContentDedupKey
saveCore 在持久化前强制生成 ContentDedupKey:
显式 Key 存在?
├── 是 → 使用显式 Key
└── 否 → 从 content hash 生成 ContentDedupKey
去重键组成
行身份:(scope, namespace, actor, key_)
- 同一行身份的写入 → upsert(覆盖旧内容)
- 不同行身份的相同内容 → 各自独立
覆盖已有名字
覆盖已存在的名字 delta=0(upsert 是编辑手势)。
卡在上限的 Cell 必须还能轮换凭据——否则唯一动作是删了重建。
冲突检测(detectSupersession)
Digest 中的 detectSupersession 检测"较新条目显式否定较旧条目"。
机制
Digest 扫描
↓
detectSupersession(entries)
↓ 检测否定信号
标记旧条目 Conflicted = true
↓
从全部自动注入面排除
否定判据
必须是作为子串无歧义的整词(strings.Contains,不是词边界)。
CJK 否定词修正(INV-MEM-30)
negationMarkers 曾含裸字 不,导致:
- "不错" → 否定信号 ❌
- "差不多" → 否定信号 ❌
- "不仅" → 否定信号 ❌
修正:CJK 单字不作为否定判据。
阈值
SupersessionThreshold = 0.4
CJK 逐字分词下容易命中——阈值必须是命名常量并有定量标定测试。
Stale 检测(markStaleEntries)
INV-MEM-29:30+ 天零召回的 L4 条目标记 stale。
Digest 扫描
↓
markStaleEntries()
↓ 30 天未召回
标记 Stale = true
↓
从全部自动注入面排除(RecallQualityOK)
显式检索路径不受此门约束。
质量门(RecallQualityOK)
INV-MEM-50 定义的单点质量检查:
RecallQualityOK(entry)
├── Conflicted = true → 排除
├── Stale = true → 排除
└── 通过 → 注入
GC 豁免 vs 质量门
IsGCExempt():Constraint / Instruction / Environment → GC 不删RecallQualityOK:对KindCollective不豁免
一条被取代的部门共识会留在每个 actor 的系统提示词里直到 Cell 消亡——这正是 RecallQualityOK 要消灭的。
Digest 分区
Digest 按 (Namespace, CognitiveOwner) 分区(INV-MEM-42):
- 同一分区内条目互相比较
- 不同分区的条目不互相干扰
- 跨主体的认知判断是不可逆损坏
去重与写入管线
去重在写入管线的第 3 步:
1. 层映射
2. Actor 验证
3. ContentDedupKey 生成 ← 这里
4. Kind / SessionID 检查
5. 威胁扫描
...
相关文档
- Memory 写入管线 →
memory-write-pipeline.md - Memory GC 与 Digest →
memory-gc-digest.md - Memory 自动注入 →
memory-auto-injection.md - Memory 威胁扫描 →
memory-threat-scan.md