---
url: https://docs.nemo12.com/architecture/sdd-017-retention.md
description: >-
  Retention Engine (SDD-017): vì sao Mastery khác Retention, mô hình ghi nhớ,
  suy giảm theo thời gian và lịch ôn tập.
---

# SDD-017 — Retention Engine & Memory Retention System

Mastery cao trong quá khứ không có nghĩa learner vẫn làm được hôm nay. Nếu chỉ lưu `Mastery = 0.90`, Recommendation Engine hiểu sai rằng learner vẫn chắc. Hệ cần trả lời: *"những gì learner đã học, hiện tại còn bao nhiêu thực sự available trong trí nhớ — và thứ gì đáng củng cố ngay bây giờ?"* North Star: **giữ đúng kiến thức cần thiết, ở mức đủ chắc, tại đúng thời điểm, với chi phí học tập thấp nhất** — không phải "bắt learner ôn mọi thứ mãi mãi".

## 1. Core rule: Mastery ≠ Retention (REQ-INT-23)

Hai dimension **khác nhau, không mâu thuẫn**:

* **Mastery** — learner đã đạt mức nào khi được quan sát gần nhất (SDD-002 §2, không đổi).
* **Retention** — xác suất ước tính learner còn truy xuất & sử dụng được kiến thức đó *ở thời điểm hiện tại* (estimated probability of successful retrieval — không khẳng định "đã quên 45%").

**Cấm** làm mastery tự giảm theo thời gian (`Mastery 0.90 → 30 ngày → 0.64`). Đúng: `historical_mastery = 0.90` giữ nguyên, `current_retention = 0.64` là số riêng. Nhờ tách hai dimension, hệ phân biệt được "cần học lại từ đầu" với "chỉ cần đánh thức trí nhớ". (Recency decay của *effective_confidence* — SDD-007 §12 — vẫn đúng và độc lập: confidence là độ tin của estimate, retention là trạng thái trí nhớ.)

## 2. Retention Model (REQ-INT-23)

Áp dụng ở nhiều cấp `target_type: node | skill | unit | module | package`; **tính ở cấp nhỏ nhất có đủ evidence** (Phase 1: node), aggregate lên unit/subject khi hiển thị — không lưu bản aggregate riêng (Q-112). Mỗi Retention State:

```text
learner_retention: learner_id · target_type · target_id
· historical_mastery          -- mastery đỉnh đã quan sát (không decay)
· current_retention 0–1      · retention_confidence 0–1
· stability_days             -- S: forgetting rate nghịch đảo (S lớn = quên chậm)
· last_exposure_at · last_successful_retrieval_at · last_strong_evidence_at
· retrieval_count · successful_retrieval_count
· review_urgency (NONE|LOW|MEDIUM|HIGH|CRITICAL)
· next_review_earliest/ideal/latest   -- window, không phải timestamp (§7)
· updated_at · model_version ("retention-v1")
```

`forgetting_rate` biểu diễn bằng `stability_days` — có thể tồn tại nhiều cấp (global learner → domain → knowledge-type → node); v1 chỉ node-level + default population params, learner-specific là Phase 2 (§12).

## 3. Retention Engine — decay (REQ-INT-24)

Trả lời "*giờ này learner còn nhớ đến mức nào?*". Input: Learner Model + Evidence Registry + Retention State cũ + elapsed time (+ Knowledge Graph cho dependency_weight). Output: Retention State mới. Thuật toán `retention-v1` — deterministic, versioned, params configurable một chỗ:

```text
R(t) = R₀ × exp(−Δt / S)          -- Δt ngày từ lần exposure/retrieval cuối
S₀   = 6 + 14 × initial_mastery    -- mastery 0.90 → S ≈ 18.6 ngày
```

**Không chạy liên tục.** Tính lại **lazy/event-driven**: khi API đọc (summary/review-queue/Home), khi có evidence mới, khi Recommendation cần, khi window đến hạn (Q-113). Không recompute toàn Knowledge Graph theo lịch; xử lý hàng nghìn states/learner bằng lazy evaluation + chỉ ghi khi thay đổi đáng kể.

## 4. Evidence tiers & retrieval strength (REQ-INT-24)

Không phải exposure nào cũng bồi trí nhớ như nhau. Phân tầng (map từ evidence hiện có: đọc lời giải = exposure; đúng có hint = assisted; đúng độc lập = independent; đúng sau spacing dài / context lạ = transfer):

| Tier | Ví dụ | Retention sau update | Stability |
| --- | --- | --- | --- |
| exposure | đọc lại lời giải | +nhẹ (≤0.05) | ×1.05 |
| recognition | chọn đúng câu recognition | R → max(R, 0.70) | ×1.15 |
| assisted | đúng với hint | R → max(R, 0.80) | ×1.25 |
| independent | tự retrieval đúng, không hint | R → 0.90–0.96 | ×(1.5 + 0.5×min(Δt/S, 2)) |
| transfer | đúng trong context lạ / interleaved | R → 0.94–0.97 | ×(1.8 + 0.6×min(Δt/S, 2)) |

* **Spacing effect**: retrieval thành công sau khoảng cách dài (Δt/S lớn) tăng S nhiều hơn → interval review sau **giãn dần** (1d → 7d → 21d → 60d…). Review càng hiệu quả, càng ít phải review.
* **Retrieval fail** (v1 đang chạy, `retention/engine.ts`): `R → R − (R − min(R×0.5, 0.45))·w`, `S → max(3, S·(1 − 0.5·spacingWeight·w))` với `w` = trọng số theo reliability và `spacingWeight` = lớp giảm chấn lặp-cùng-ngày → interval **co lại** (learner quên nhanh hơn expected → spacing cá nhân ngắn hơn). Bản đầu của dòng này viết `S → max(3, S×0.5)`, `R → min(R, observed)` — đó là ý đích, không phải cái đang chạy (Audit #013, T-12); công thức đang chạy chi tiết ở [retention-model §3.4–3.5](../reference/retention-model.md#34-trình-tự-tính). Nhưng **không hạ mạnh vì một evidence đơn lẻ** khi Context Model cho thấy stress/ốm/vội (context-failure — §5); reliability per attempt (SDD-002 §18) nhân vào boost: đúng-nhanh-bừa gần như không bồi trí nhớ.
* **Interleaving**: mixed retrieval (A→C→B→A) là evidence mạnh hơn recognition trong block đồng dạng → tier transfer.
* **Độ tin cậy của ước lượng** (`retention_confidence`, khác confidence của mastery): `volume = 1 − exp(−successes/3)`, `recency = exp(−Δt / (4·S))`, `confidence = volume × recency` — phai dần khi lâu không quan sát (v1, `retentionConfidence()`).
* **Learner tự khai cách làm** (justification taxonomy — SDD-012 §4, SRC-072): `guessed` + đáp án đúng bị hạ xuống mức `assisted`, **không** tính là retrieval độc lập — trí nhớ không được bồi bằng may mắn. `derived`/`recalled` giữ nguyên tier theo reliability. Mastery không đổi cách tính (self-report .50 chỉ điều chỉnh retention).

## 5. Ba phân biệt bắt buộc (REQ-INT-24, REQ-INT-27)

| Case | Dấu hiệu | Đáp ứng |
| --- | --- | --- |
| **Forgotten** | historical_mastery cao, performance hiện tại yếu | quick retrieval restoration (1–3 câu), không dạy lại từ đầu |
| **Never learned** | mastery chưa từng được chứng minh thuyết phục | full Learning Experience (đường học bình thường) |
| **Context failure** | sai nhưng có stress/fatigue/misread/time-pressure (Context Model + evidence pattern) | không giảm retention mạnh; chờ thêm evidence |

**Retention confidence** (REQ-INT-27): estimate không phải chân lý. `confidence = (1 − exp(−successful_retrievals/3)) × recency_factor` (tăng theo số observation, consistency, recency, diversity). Khi `retention thấp NHƯNG confidence thấp` (vd 0.55/0.31) → **assessment probe 1–3 câu retrieval** thay vì relearning: đúng dễ dàng → `0.55 → 0.88` ngay; thất bại → confirm forgetting → review theo Ladder (§7). Đây là cơ chế chống "ôn thừa".

## 6. Review urgency & priority (REQ-INT-25)

Retention thấp **không tự động** = review ngay (node 0.60 ngoài goal = LOW; node 0.68 thi sau 5 ngày = CRITICAL).

```text
review_urgency = f(current_retention, importance, goal_relevance,
                   exam_proximity, dependency_weight, cost_of_forgetting)
ReviewPriority = ForgettingRisk × Importance × GoalRelevance
               × DependencyValue × TimingUrgency        -- score cho Recommendation
```

* **Prerequisite protection**: node có `dependency_weight` cao trong Knowledge Graph (Basic Algebraic Manipulation chặn hàng chục units) được review sớm hơn node độc lập có retention thấp hơn.
* **Goal-aware**: hai node cùng retention 0.60 — SAT (12 ngày) thắng CSP (9 tháng) vì goal urgency (Goal Model SDD-002 §16, exam targets/deadlines), không phải vì quên nhiều hơn.

## 7. Review Ladder & next_review_window (REQ-INT-25, REQ-INT-27)

Thresholds configurable trong `retention-v1` config (personalize dần — Phase 3):

```text
R > 0.85        → không làm gì          0.60–0.75 → active review
0.75–0.85      → light retrieval        0.40–0.60 → targeted relearning
                                        < 0.40    → possible remediation
```

`next_review_window` là **khoảng**, không phải timestamp ("không bắt review đúng 14:32 ngày 21/8") — deterministic từ decay curve: `earliest` = ngày R cắt 0.85, `ideal` = R cắt 0.75, `latest` = R cắt 0.65. Recommendation xếp lịch linh hoạt trong window theo context/constraint/available time. Learning Engine chọn **hình thức** review theo mức (SDD-002 §11): giảm nhẹ → 1 câu retrieval; thấp → 2–3 mixed problems; rất thấp → Worked Example → Guided → Independent. "Review" không đồng nghĩa học lại bài từ đầu.

## 8. Recommendation integration — New / Repair / Review (REQ-INT-26)

Recommendation Engine (SDD-002 §10) thêm loại candidate **Review** cạnh Learn New/Repair Weakness; tỷ lệ **không hard-code** — tính từ models (xa thi: nghiêng New; gần thi: nghiêng Review/retrieval — khớp mode switching SDD-011 §6). Context Model override được ("ốm, capacity −70%" → chỉ top-3 review đáng giá nhất, postpone phần còn lại); Constraint (50' review nhưng chỉ có 15') → chọn **highest expected value per minute**. Explainability: mỗi review recommendation lưu reason `{historical_mastery, estimated_retention, last_retrieval_days, exam_relevance, urgency}` + model_version (SDD-002 §15).

## 9. Review Queue động & implicit review (REQ-INT-26)

* **Review Queue = view tính lại mỗi ngày** từ Retention+Goal+Context+Constraint models — không phải fixed task list. 43 candidates → hôm nay chọn 5 highest-value; mai tính lại.
* **Avoid review debt**: learner nghỉ vài ngày **không** thấy "187 overdue reviews". Hệ re-optimize "*kiến thức đã rơi nào còn đáng phục hồi?*" — node có thể drop / deprioritize / sample-check / review gián tiếp. Không tạo backlog vô hạn bắt learner "trả nợ".
* **Implicit review**: bài mới dùng prerequisite cũ mà learner retrieval thành công → ghi nhận `implicit retrieval` cập nhật retention của prerequisite — không spam review session riêng. (Phase 1: evidence đúng độc lập trên chính node; prerequisite-traversal Phase 2 — Q-117.)

## 10. UX — learner & parent (REQ-INT-28)

* **Learner** (learn, luật tối giản DS-001 §5b): khối "Ôn nhanh" trong tab "Hôm nay" của school cockpit (hub — Q-118) — "*Tam giác đồng dạng — 8 phút. Con làm tốt phần này, nhưng 24 ngày chưa dùng. 2 câu để giữ thật chắc.*" **Không bao giờ** nói "bạn đã quên". Session ngắn, friction thấp, không punishment, retrieval trước explanation. Không đếm nợ.
* **Parent** (marlins): không thấy forgetting equations — chỉ nhóm nhãn `Đang chắc / Cần nhắc lại sớm / Có nguy cơ quên / Nên ôn lại` theo môn/area (vd "Algebra: Stable · Geometry: 3 areas need reinforcement"); phân biệt "từng vững nay có nguy cơ quên" với "chưa từng vững" (§5).
* Internal explanation đầy đủ (mastery/retention/urgency/days) có trong API cho debug + mentor.

## 11. Events & data flow (REQ-INT-24, REQ-INT-26; REQ-INT-18 mở rộng)

Event types: `LEARNING_COMPLETED · RETRIEVAL_ATTEMPTED · RETRIEVAL_SUCCEEDED · RETRIEVAL_FAILED · HINT_USED · TRANSFER_SUCCEEDED · REVIEW_COMPLETED · ASSESSMENT_COMPLETED · TIME_WINDOW_REACHED`. Flow:

```text
Learning Experience → Evidence Registry → Learner Engine → Learner Model
Time + Evidence → Retention Engine → Retention Model → Readiness Engine (Phase 2)
All models → Recommendation → New/Repair/Review → Learning Engine → New Evidence ↺
```

Model Update Policy (SDD-002 §14) thêm dòng: practice/review evidence → update Learner + **Retention** trước, Recommendation cuối. Readiness đọc retention (Phase 2 — Q-114): readiness giảm do decay phải ghi reason `estimated memory decay`, **không** phải `observed performance decline` — khác biệt về confidence.

## 12. Phasing (Q-111..Q-118)

| Phase | Nội dung |
| --- | --- |
| **MVP (Phase 1)** | `learner_retention` node-level; engine v1 (decay exp + evidence tiers seen/assisted/retrieved/retrieved-successfully + spacing growth); urgency/priority/window; review-queue API top-k; learn "Ôn nhanh" + review session; marlins nhóm nhãn; lazy recalculation |
| **Phase 2** | learner-specific + knowledge-type forgetting rate; prerequisite weighting đầy đủ + implicit review qua graph; adaptive spacing nâng cao; backlog optimization; Readiness integration; cron notification |
| **Phase 3** | predictive forgetting; counterfactual review scheduling; exam-aware memory optimization; cross-node transfer; interference modeling; long-term trajectory |

Model evolution: Level 1 rules (1d→7d→21d→60d) → Level 2 performance-adaptive (đang ở đây với v1) → Level 3 learner-specific decay → Level 4 node-specific predictive. **Không xây Level 4 từ MVP.**

## 13. Non-functional & success metrics

* **NFR** (QG-009): deterministic đủ để debug; `model_version` trên mọi state; explainable; không full-recalculation liên tục; lazy evaluation; nghìn states/learner; giữ source evidence; đổi algorithm không mất lịch sử (state cũ giữ model_version cũ, recompute từ Evidence Registry được).
* **Metrics** (không đo "số review đã làm"): **Retention Accuracy** (prediction vs retrieval performance thật); **Review Efficiency** (phút review / improvement); **Unnecessary Review Rate** (review thứ đã quá chắc); **Forgotten Critical Knowledge** (knowledge quan trọng tụt dưới threshold trước khi hệ can thiệp); **Long-term Retrieval Success** (30/90/180 ngày).

## 14. Implementation mapping (Phase 1)

* Migration `0021_learner_retention.sql`: bảng `learner_retention` (§2, PK learner_id+target_type+target_id).
* Module `workers/api/src/modules/retention/`: `engine.ts` (pure functions: decay/update/urgency/window — behavior tests vitest, QG-005), `routes.ts` (`GET /v1/learners/{id}/retention/summary` — nhóm nhãn theo môn; `GET /v1/learners/{id}/retention/review-queue?limit=` — top-k candidates kèm reason; recalculation lazy trong 2 route đọc).
* Hook: practice/exam answer flow (learning module) sau khi ghi evidence → `updateRetentionOnEvidence` (tier từ hint/correct/độc lập + reliability).
* learn: khối "Ôn nhanh" (tab "Hôm nay" của cockpit) + review action trong cockpit next-actions (`buildCockpit`) → review session dùng lại practice flow (SRC-110 pattern); marlins: `ChildReport` thêm nhóm nhãn retention.

## 15. Tính lại định kỳ — WF-17 Retention Refresh (REQ-INT-30, SRC-104)

Retention phai theo **thời gian**, không theo hành động: learner nghỉ 3 tuần thì model phải đổi dù không có một evidence nào. Lazy recalculation (Q-113) giải quyết phần *đọc*, nhưng ba thứ vẫn nằm chết trong DB và mọi consumer khác đọc phải giá trị cũ:

* `review_urgency` — chụp lúc ghi evidence, khi đó chưa có ngữ cảnh goal/exam.
* `next_review_earliest / ideal / latest` — mốc lịch ôn.
* `retention_confidence` — phai theo thời gian không quan sát (§5).

**Cron hằng ngày 21:00 UTC (04:00 giờ Việt Nam)** chạy WF-17: chọn learner có retention state, ưu tiên learner lâu nhất chưa có snapshot, mỗi learner một `engine_runs` row + một snapshot `learner_model_versions(model_kind='retention')`. Cap 200 learner/lần chạy; phần bị hoãn ghi rõ `deferred` trong output workflow (không cắt im lặng) và lên đầu hàng đợi hôm sau vì thứ tự theo độ cũ của snapshot. Admin bấm "Refresh retention now" chạy đúng workflow đó.

**Ranh giới bắt buộc — refresh KHÔNG được đụng anchor.** `current_retention` là R₀ *tại* `last_exposure_at`; ghi giá trị đã decay ngược vào đó mà không dời anchor sẽ decay hai lần và bào mòn trí nhớ learner một cách vô hình. Job chỉ ghi các trường phái sinh. Hai bất biến này có test riêng (`retention/periodic.test.ts`):

1. Decay mũ memoryless → chia bao nhiêu chặng cũng ra một kết quả; re-anchor lịch ôn tại `now` cho **đúng mốc tuyệt đối cũ**, refresh hằng ngày không làm trôi lịch.
2. Khi đã cắt ngưỡng thì lịch kẹp về "đến hạn ngay", không được đẩy ra tương lai.

Retention Engine cũng chạy trong chuỗi WF-04 sau mỗi lần có evidence — cron lo phần "thời gian trôi", WF-04 lo phần "vừa có bằng chứng mới".

## Trace

| REQ | Section |
| --- | --- |
| REQ-INT-23 (Retention ≠ Mastery, Retention Model) | §1, §2 |
| REQ-INT-24 (Engine: decay, tiers, retrieval strength, lazy) | §3, §4, §5, §11 |
| REQ-INT-25 (urgency, priority, window, Ladder) | §6, §7 |
| REQ-INT-26 (Recommendation, queue động, no debt, implicit) | §8, §9, §11 |
| REQ-INT-27 (confidence + probe, 3 phân biệt) | §5, §7 |
| REQ-INT-28 (UX không phán xét) | §10 |
| US-64/65/66 | §7–§10 |

Liên quan: SDD-002 (§2 mastery, §5 evidence, §7-8 update, §10 recommendation, §11 learning modes, §14 update policy, §15 explainability, §16 goal, §17 readiness, §18 reliability), SDD-007 §12 (recency/decay của confidence — độc lập với retention), SDD-011 §6 (mode switching), SDD-008 §4 (node state "Needs Review"), DS-001 §5b (luật tối giản cho khối Ôn nhanh).
