SmartRecall 中的 SM-2 算法详解

SM-2 间隔重复算法的完整实现:初始间隔、ease factor 更新、lapse 规则,以及 SmartRecall 的实操调整,附完整算例。
2026/04/29

SmartRecall 中的 SM-2 算法详解

SM-2 是 Piotr Wozniak 在 1987 年的 SuperMemo 论文 里发表的间隔重复算法,也是 Anki 和 Mnemosyne 背后的算法。本页面把 SmartRecall 的实现讲透 —— 每一个常数、每一个状态转移,附完整算例。

一句话原理

每复习一次,给本次回忆打分:

  • Again(0) —— 失败,没回忆起来
  • Hard(3) —— 想起来了,但很费劲
  • Good(4) —— 正常想起来
  • Easy(5) —— 一秒回忆

SM-2 用这个评分更新两个数:

  1. 间隔(I —— 距离下一次复习的天数
  2. 难度系数(EF,Ease Factor) —— 控制间隔增长速度的乘数

评分越高 → EF 越大 → 间隔增长越快;评分越低 → EF 越小 → 间隔越紧。失败会把间隔重置,但 EF 只是被略微下调。

SmartRecall 使用的精确规则

新卡片初始值:
  I  = 0       (首次复习时设置)
  EF = 2.5
  reps = 0     (连续成功复习次数)

每次复习,质量分 q (0–5):

  if q < 3:                  // 失败 lapse
    reps = 0
    I    = 1                 // 间隔回到 1 天
    // EF 下面继续更新

  else:                      // 成功
    if reps == 0: I = 1
    elif reps == 1: I = 6
    else:          I = round(I_prev * EF)
    reps = reps + 1

  EF = max(1.3, EF + (0.1 - (5 - q) * (0.08 + (5 - q) * 0.02)))

EF 公式在每个评分点折成易记的数:

评分qEF 变化
Again0−0.80
Hard3−0.14
Good40.00
Easy5+0.10

EF 下限被夹在 1.3 —— 不论失败多少次,间隔都不会比这更慢地增长。

完整算例

一张新卡:"什么是间隔效应?"

第几次复习评分q复习后 reps复习后 EF复习后 I下次复习
1Good412.501 天明天
2Good422.506 天+6 天
3Easy532.6016 天+16 天
4Hard342.4639 天+39 天
5Again001.661 天明天(lapse)
6Good411.661 天+1 天
7Good421.666 天+6 天

需要注意的几点:

  • 前两次的间隔(1 天 → 6 天)是写死的,不走乘法。SM-2 之所以这么设计,是为了避免新卡因为高 EF 一下子飞到 30 天后才复习。
  • 第 4 次后的间隔是 round(16 * EF) = round(16 * 2.46) = 39
  • 第 5 次是 lapse —— reps 归零,I 归 1,但 EF 只下调 0.80(没回到 2.5)。卡片是"受伤",不是"清零"。
  • lapse 之后,调度不会重复 1 → 6 的递增;第 6 次成功之后 reps 升到 1,第 7 次直接走 6 天间隔。

SmartRecall 在 SM-2 之上做的三个调整

SM-2 是底线,不是天花板。我们做了三处务实改动:

  1. Hard 三连软 lapse。 如果你连续三次给同一张卡评 Hard,下一次的间隔会被夹在 I_prev,不再继续乘 EF。纯 SM-2 会继续放大间隔,让你跟它越打越远。
  2. Leech(钉子卡)识别。 一张卡一共 lapse 8 次后,会被打上 leech 标签并出现在你的 Dashboard 上,提示你重写这张卡。一张烂卡是工作流问题,不是算法问题。
  3. 生成时间种子化的初始扩散。 AI 一次生成 200 张卡时,我们不会全部放在第一天复习 —— 用卡片 ID 的确定性哈希把首次 I = 1 的复习铺到接下来 5 天里,让你的每日复习量保持平稳。

其余部分 —— EF 公式、1/6 天阶梯、1.3 下限、lapse 语义 —— 都和 1987 年的论文完全一致。

为什么暂时不用 FSRS?

FSRS 是一个更新的调度器,会从用户的复习历史里学习个性化遗忘曲线。在累计 ~1000 次复习之后,它的表现可测量地优于 SM-2。我们正在把 FSRS 作为可选调度器开发中 —— 进展看 更新日志

延伸阅读