Experience Replay & Dream Rollouts

Lesson 7 · SkillOpt & Agent Harnesses · ~20 minutes

Warm-up: retrieve

From Lesson 6: what is the single required method on a SkillOpt ModelBackend?
Solid. The backend is just the model interface — everything else (rollout, reflection, gating) is the engine's job. Now we'll tune the engine's consolidation phase.
The backend contract is minimal: generate() only. Rollout and reflection live in the env adapter and the engine respectively. Review Lesson 6's architecture diagram.

What you'll learn

SkillOpt-Sleep has three opt-in knobs that strengthen the nightly consolidation by drawing on past experience. They're all off by default — the basic cycle works without them. But turning them on is where the gains compound: the Sleep README shows +3–5 percentage points on SearchQA from replay scaling alone.

KnobDefaultWhat it does
dream_rollouts 1 Run each task K times → learn from good-vs-bad contrast (contrastive reflection)
recall_k 0 Pull the K most-similar past tasks from a persisted archive into tonight's dream
dream_factor 0 Generate N lightweight synthetic variants of each task

Step 1 — Understand the mechanism

Without replay, each night only sees today's tasks. The optimizer reflects on failures from those tasks alone. With replay enabled:

  1. Associative recall (recall_k) — searches the archive for past tasks similar to tonight's, pulling them into the dream batch. More relevant context → better reflection.
  2. Contrastive dreaming (dream_rollouts) — runs each task multiple times. Some runs succeed, some fail. The contrast between good and bad trajectories gives the optimizer a clearer signal about what specifically made the difference.
  3. Synthetic augmentation (dream_factor) — generates variations of each task (different inputs, same shape). Prevents overfitting to specific examples.
The data from the paper

SearchQA with dream_rollouts=5 and recall_k=20: baseline 0.803 → 0.848 (+4.5pp). The gain rises monotonically with recall depth. Without replay: +1–2pp. With full-history replay: +5.6pp. The validation gate keeps everything safe regardless.

Step 2 — Configure replay

Edit your ~/.skillopt/config.yaml (or pass as CLI flags):

# Start conservative — recall from recent history, moderate dreaming
skillopt-sleep run \
  --dream-rollouts 3 \
  --recall-k 10

# More aggressive — deeper recall, more contrast
skillopt-sleep run \
  --dream-rollouts 5 \
  --recall-k 20

Cost note: Each dream rollout calls your target model once per task. With dream_rollouts=5 and 10 tasks, that's 50 target-model calls per night. Budget accordingly — or use a cheaper model for dreaming.

Step 3 — Watch the archive grow

The experience archive persists between nights. After a few cycles with recall_k > 0, check it:

skillopt-sleep status --show-archive

You should see tasks accumulating over time. The recall mechanism uses embedding similarity — tonight's tasks pull in their most relevant ancestors. This is why more nights = better skills: the archive becomes a richer source of contrastive experience.

Step 4 — Compare with and without

Run two cycles and compare the proposals:

# Night 1: baseline (no replay)
skillopt-sleep run
skillopt-sleep status  # note the proposal quality + held-out score

# Night 2: with replay
skillopt-sleep run --dream-rollouts 5 --recall-k 10
skillopt-sleep status  # compare

Apply the rubric to both proposals. The replay version should produce more specific rules — because the optimizer has more contrastive signal to work with.

Don't set dream_factor high yet

Synthetic augmentation (dream_factor) generates tasks that don't exist in your real usage. Start with dream_factor=0 until you've validated that your real tasks produce good proposals. Synthetic variants help generalization but can dilute signal if your scoring function doesn't transfer well to generated tasks.

You set recall_k=10 but only have 3 nights of history. What happens?
Right — the recall is best-effort. If the archive has fewer items than K, it uses what's there. The gains scale with archive depth, which is why the system improves the more you use it. No error, no synthetic backfill from recall_k alone.
Recall is best-effort — it won't error on a small archive, and it won't synthesize to fill the gap (that's dream_factor's job). It just uses whatever history is available. The system gets stronger as the archive grows naturally through daily use.
Recommended Reading

SkillOpt-Sleep RESULTS.md — Microsoft Research. The gate-safety stress test, experience-replay scaling curves, and dream-diversity ablation. ~10 minutes. The SearchQA replay table is the key evidence.

Questions? If you're unsure what recall depth to start with for your task domain, or whether contrastive dreaming is worth the API cost for your use case — ask and I'll help you size it.
Prev Next