Dream 记忆巩固
Dream 是记忆的垃圾回收 + 归档:把近似重复的记忆按向量聚类合并(相似度 ≥ 阈值),把长期没被用到的记忆降权,把既旧又没用的记忆忘掉。它是唯一会删除记忆的自动化流程,所以参数默认值都偏保守。
触发方式
| 方式 | 行为 |
|---|---|
| 手动 | POST /api/memories/dream,立即执行并返回统计 |
| 后台 | DreamMemoryService 作为常驻后台服务:启动即检查一次,之后每 30 分钟轮询一次 |
| 执行条件 | Enabled = true 且距上次运行已超过 IntervalHours(默认 24 小时) |
配置与默认值
| 配置项 | 默认 | 约束 |
|---|---|---|
Enabled | true | 关闭后后台不再执行,手动仍可用 |
IntervalHours | 24 | 1–720 |
MergeThreshold | 0.85 | 0.5–0.99 |
DecayDays | 30 | 1–3650 |
ForgetDays | 180 | 必须 ≥ DecayDays |
ForgetBelowImportance | 0.15 | 0.01–1 |
LastRunAt | — | 由执行流程写回;保存配置不会覆盖它(否则每次改配置都会重置周期) |
配置键是 DreamConfig。
聚类与合并
- 取出全部未删除记忆,按 embedding 相似度做贪心聚类,阈值即
MergeThreshold。 - 每个簇选一个代表(keeper),选择顺序:
Importance更高 → 作用域更公共(Global<Project<Session)→CreatedAt更早。 - 保留代表并更新:
Importance += 0.05(上限 1)、AccessCount累加被吸收记忆的次数、LastAccessedAt取簇内最新。 - 被吸收的记忆被移除(含向量行)。
合并偏好「更公共、更早」的那条:项目级或会话级的重复表述会被吸进全局记忆,这也是为什么合并后要检查一下原文表述是否还准确。
衰减与遗忘
| 阶段 | 条件 | 动作 |
|---|---|---|
| 衰减 | 距上次访问 > DecayDays 且 Importance > 0.05 | Importance ×= 0.8,下限 0.05 |
| 遗忘 | 距上次访问 > ForgetDays 且 Importance < ForgetBelowImportance | 软删并移除 embedding |
结果与观测
- 返回统计
DreamResultDto:Merged/Decayed/Forgotten/Remaining/DurationMs/RanAt。 - 日志:启动
记忆 Dream 巩固服务已启动;自动执行[Dream] 自动巩固完成:…;手动完成[Dream] 记忆巩固完成:…;失败Dream 自动巩固失败/Dream 记忆巩固失败。 - 失败不会拖死后台服务:异常在服务层被捕获并记录,仅本次不生效。
实作要点
- Dream 是不可逆的:没有记忆版本历史,合并与遗忘都直接落库。调低阈值前先确认能接受合并后果。
- 「记忆莫名变少」通常不是 bug:查
ForgetDays与ForgetBelowImportance,以及这些记忆的LastAccessedAt(长期不召回就会被衰减到阈值以下)。 - 想保留某条记忆,把
Importance提到0.2以上并偶尔让它被召回,两个信号都能挡住遗忘。 - 换 embedding 模型后聚类阈值语义会变,建议先手动跑一次看
Merged数量再让后台自动执行。