Skip to content

Latest commit

 

History

History
55 lines (40 loc) · 2.56 KB

File metadata and controls

55 lines (40 loc) · 2.56 KB

ADR-018: 间隔重复调度器引入 fsrs crate(FSRS-6)

状态

已接受

日期

2026-08-22

背景

v0.11.2(学习循环统一)需要间隔重复调度器。2026-08-22 用户裁决选型 FSRS (记忆决策:《间隔重复引擎选型 FSRS 取代 SM-2(v0.11.2)》):FSRS-6 是 Anki 23.10+ 默认调度器,DSR 三变量模型(难度/稳定性/可提取性)基于遗忘曲线 实证研究,按目标留存率反解间隔,大规模真实数据验证优于 SM-2。

备选降级路径为手写 SM-2 纯函数兜底——触发条件是「依赖引入受限」(本机存在 TLS 拦截,部分 CDN 下载会失败)。

决策

  1. 引入 fsrs = "6"(crates.io v6.6.1)作为调度器实现:
    • 实测 crates.io 拉取与编译成功(含 6 个轻量传递依赖),降级条件未触发;
    • 仅消费推理 API(FSRS::new(&[]) 默认参数 + next_states),不启用 训练/优化器路径(--no-default-features 关闭 experimental_cost_adr);
    • 纯算法零网络依赖,契合本地优先;默认参数开箱即用。
  2. 目标留存率取 0.9(FSRS 推荐默认);个性化参数优化是复习数据积累后的 远期扩展(数据不出本机)。
  3. 调度接口(scheduler.rs:schedule(state, rating, now) -> ScheduleOutcome) 与算法实现解耦——将来若需换算法(或受限环境补 SM-2),接口不变。
  4. 不保留双实现(YAGNI):依赖引入成功后 SM-2 兜底失去存在理由;接口预留 使后补成本极低。

备选方案

方案 A:手写 SM-2 纯函数(未采用)

  • 优点:零依赖、完全可控。
  • 缺点:启发式 EF 系数易漂移失真,调度质量系统性弱于 FSRS;用户已裁决弃用。

方案 B:引入 rs-fsrs 轻量调度 crate(未采用)

  • 优点:依赖更少。
  • 缺点:非 Anki 官方算法主线,维护活跃度与算法版本(FSRS-6)跟进不确定。

方案 C:fsrs 官方 crate(采用)

  • 优点:算法主线权威(Anki 同款)、FSRS-6 默认参数、纯 Rust 编译通过。
  • 缺点:crate 含训练域代码(未启用),传递依赖 6 个。

后果

  • flashcards.state_json 采用 FSRS MemoryState(stability/difficulty)+ reps/lapses 扩展字段的序列化格式;旧格式损坏回退新卡状态(诚实降级)。
  • 复习日志无 streak 字段(弹性承诺纪律:不追债不清零,N10 归零暴政防御)。
  • 指标埋点(card_reviewed/fragment_upgraded)随复习链路同批落库——北极星与 Phase 4 门控判据从第一天记录。