Dream consolidation
Dream is garbage collection for memories: near-duplicates are clustered by vector similarity and merged, memories that have not been used for a long time lose weight, and memories that are both old and unimportant are forgotten. It is the only automated flow that deletes memories, which is why the defaults stay conservative.
Triggers
| Mode | Behaviour |
|---|---|
| Manual | POST /api/memories/dream runs immediately and returns the stats |
| Background | DreamMemoryService checks once on startup and then polls every 30 minutes |
| Precondition | Enabled = true and more than IntervalHours (default 24 h) since the last run |
Configuration and defaults
| Setting | Default | Constraint |
|---|---|---|
Enabled | true | Disabling stops the background run; manual execution still works |
IntervalHours | 24 | 1–720 |
MergeThreshold | 0.85 | 0.5–0.99 |
DecayDays | 30 | 1–3650 |
ForgetDays | 180 | Must be ≥ DecayDays |
ForgetBelowImportance | 0.15 | 0.01–1 |
LastRunAt | — | Written by the run; saving settings never overwrites it, otherwise every edit would reset the cadence |
The settings key is DreamConfig.
Clustering and merging
- Load every non-deleted memory and cluster greedily by embedding similarity, using
MergeThresholdas the cutoff. - Pick one keeper per cluster: higher
Importance→ more public scope (Global<Project<Session) → earlierCreatedAt. - Update the keeper:
Importance += 0.05capped at 1,AccessCountadds the absorbed counts,LastAccessedAttakes the newest in the cluster. - Absorbed memories are removed along with their vectors.
The merge prefers the more public and older wording: project- or session-scoped duplicates get absorbed into a global memory — worth a glance afterwards to confirm the surviving text is still accurate.
Decay and forgetting
| Stage | Condition | Action |
|---|---|---|
| Decay | Not accessed for > DecayDays and Importance > 0.05 | Importance ×= 0.8, floor 0.05 |
| Forget | Not accessed for > ForgetDays and Importance < ForgetBelowImportance | Soft-delete and remove the embedding |
Results and observability
- Stats returned as
DreamResultDto:Merged/Decayed/Forgotten/Remaining/DurationMs/RanAt. - Logs: startup
记忆 Dream 巩固服务已启动; automatic runs[Dream] 自动巩固完成:…; manual runs[Dream] 记忆巩固完成:…; failuresDream 自动巩固失败/Dream 记忆巩固失败. - Failures never kill the background service: exceptions are caught and logged, and only that run is skipped.
Practice notes
- Dream is irreversible: there is no memory version history, so merges and forgetting hit the database directly. Understand the consequences before lowering thresholds.
- "Memories disappeared" is usually not a bug: check
ForgetDays,ForgetBelowImportanceand those memories'LastAccessedAt— never-recalled memories decay below the cutoff. - To keep a memory, raise
Importanceabove0.2and let it be recalled occasionally; both signals block forgetting. - Switching embedding models changes what a similarity threshold means; run one manual pass and read
Mergedbefore re-enabling the schedule.