刚刚,Anki 用户吵翻了:新一代间隔重复算法 FSRS 到底开不开?
【免费下载链接】ankiAnki is a smart spaced repetition flashcard program项目地址: https://gitcode.com/GitHub_Trending/an/anki
Anki 的牌组选项页里,有一个开关能让老用户犹豫很久:是否启用 FSRS。一边是以"复习量更少、遗忘更可控"为论据的拥趸,另一边是"我复习了五年,凭什么现在改算法"的保守派。争论的焦点从来不是"FSRS 好不好",而是三件很实际的事:它和 SM-2 到底差在哪、切换之后我积累的复习历史会不会被浪费、我该怎么根据自己的数据做决定。
这篇文章把这三件事拆开讲。所有结论都基于 Anki 仓库中的真实源码(核心调度逻辑全部用 Rust 实现于rslib/src/scheduler/)和官方手册(docs-site/manual/),不引用任何无法验证的"听说"。
FSRS 是什么:DSR 三状态模型对易度因子的取代
先说清楚老算法在做什么。Anki 至今保留着基于 SuperMemo 2(SM-2)的完整实现,其核心逻辑在 rslib/src/scheduler/states/review.rs 里一目了然:卡片毕业进入复习阶段后,拿到一个初始易度因子(INITIAL_EASE_FACTOR: f32 = 2.5),按按钮线性增减——
pub const INITIAL_EASE_FACTOR: f32 = 2.5; pub const MINIMUM_EASE_FACTOR: f32 = 1.3; pub const EASE_FACTOR_AGAIN_DELTA: f32 = -0.2; pub const EASE_FACTOR_HARD_DELTA: f32 = -0.15; pub const EASE_FACTOR_EASY_DELTA: f32 = 0.15;"Good" 的下次间隔就是当前间隔 × 易度因子(见同文件passing_nonearly_review_intervals)。整个模型只有一个自由度:ease。它无法回答"这张卡到底什么时候会忘",只能靠一个缓慢漂移的系数去近似。
FSRS 则建立在官方文档 docs-site/faqs/what-spaced-repetition-algorithm.mdx 所述"Three Component Model of Memory"之上,每张卡片维护一组DSR 记忆状态:
- S(Stability,稳定性):可提取性从 100% 衰减到 90% 所需的天数;
- D(Difficulty,难度):这张卡本身有多难,决定了复习后稳定性增长的快慢;
- R(Retrievability,可提取性):此刻能回忆起来的概率,由 S 和距上次复习的时间推得,每天变化,而 D、S 只在每次作答后更新。
在源码里,这组状态直接挂在卡片对象上:rslib/src/scheduler/answering/review.rs 中,每次作答后self.card.memory_state = next.memory_state;把新的 S、D 写回卡片。作答按钮的效果也完全改变——不再是加减 ease,而是按 what-spaced-repetition-algorithm.mdx 的描述:Again 使稳定性骤降、难度骤升;Easy 使稳定性大幅上升、难度下降。
工程上有两个细节值得注意,它们直接解释了"迁移成本":
- 参数是"优化"出来的,不是设计出来的。Anki 通过 workspace 依赖引入社区维护的
fsrscrate(见根目录 Cargo.toml:[workspace.dependencies.fsrs] version = "6.6.2"),并内置优化器:rslib/src/scheduler/fsrs/params.rs 会训练后做健康检查(health_check_passed),当训练集超过 300 条记录时才返回评估结果。也就是说,FSRS 的"准"来自对你个人 revlog 的机器学习拟合——没有足够复习数据的人,FSRS 只有默认参数,没有个性化优势。 - 历史记忆状态是"算"出来的,不是"搬"过来的。开启 FSRS 时,rslib/src/scheduler/fsrs/memory_state.rs 的
set_memory_state会优先回放完整 revlog 推导初始 S、D;如果 revlog 被截断(常见于导入的旧卡组或清理过历史的集合),则退而用fsrs.memory_state_from_sm2(ease_factor, interval, historical_retention)从 SM-2 的 ease 和间隔反推一个近似起点。这段代码意味着:你的五年复习历史没有被扔掉,而是被"翻译"进了 DSR 模型——这也是官方敢于在 23.10 把 FSRS 集成为内置算法的底气(见 docs-site/releases/changes/changes/23.10.mdx,当时还要求清掉自定义调度里的旧 FSRS 代码)。
为什么现在吵:三个真实的迁移顾虑
社区里对 FSRS 的分歧,本质上是这三个问题,每一个都能在仓库里找到对应的"证据":
顾虑一:复习量会不会突然爆炸?官方手册 docs-site/manual/deck-options.mdx 明确说:开启 FSRS 时"Reschedule Cards on Change"默认是关闭的——"future reviews will use the new scheduling, but there will be no immediate change to your workload",并特意警告从 SM-2 首次切换时不建议打开重排期,因为它会让大量卡片立刻到期,且给每张卡都追加一条 revlog、撑大集合体积。但注意:不重排期也意味着你短期内看不到 FSRS 的任何"效果"——旧间隔还要按旧日期到期。所以"开了没感觉"和"开了爆炸"是同一枚硬币的两面,这正是论坛里各执一词的根源。
顾虑二:我的使用习惯会不会被算法"惩罚"?手册写得很直白:FSRS 无法适应一种习惯——忘答时按 Hard 而不是 Again。因为 Hard 是及格分,按 Hard 会让所有间隔变得"unreasonably high"。此外官方 FAQ docs-site/faqs/frequently-asked-questions-about-fsrs.mdx 的健康检查一节列举了 FSRS 失效的典型原因:复习量太少(少于几百条)、Hard 误用、忘答不按 Again。也就是说,FSRS 对"作答纪律"的依赖比 SM-2 更强,数据不干净的人开 FSRS 反而更糟。
顾虑三:生态兼容性与客户端版本。手册"Before Enabling"清单要求:Anki 23.10+、AnkiMobile 23.10+、AnkiWeb、AnkiDroid 2.17+ 全端支持,且曾使用自定义调度版 FSRS 的必须先清空自定义调度;同时提醒"任何会修改间隔和调度的插件都不建议与 FSRS 同用"。对重度插件用户来说,这是实打实的迁移摩擦。另外 docs-site/manual/deck-options.mdx 还要求把学习/重学习步骤全部设到 1 天以内,否则可能出现 Hard 按钮显示的间隔比 Good 更长这类反直觉现象。
还有一个常被忽略但源码里写死的约束:FSRS 是全局开关。rslib/src/deckconfig/update.rs 中self.get_config_bool(BoolKey::Fsrs) != req.fsrs判断后写入的是集合级配置(BoolKey::Fsrs),而非预设级——你无法"日语预设用 FSRS、地理预设用 SM-2"。这直接排除了"先小范围试点"的路线,要么全有要么全无。
到底开不开:按你的复习数据给判断框架
把上面的约束收敛成决策树,其实只需要回答四个问题。
第一问:你的复习历史有多长、多干净?
FSRS 优化器以 revlog 为训练数据。历史短(几百条以内)、或作答混乱(忘答按 Hard)的用户,得到的只能是一套与默认值差异不大的参数,个性化红利为零,迁移成本却照付。这类情况建议:先保持 SM-2,把作答纪律修正一两个月再切。反过来,revlog 完整且作答规范的用户,memory_state_from_sm2的回退路径都不会触发,S、D 全部由真实历史回放得出,是收益最大的一批人。
第二问:你想用哪个旋钮控制复习强度?
这是两个算法最根本的体验差异。SM-2 里你调的是"起始易度、易度增益、间隔乘数"这类间接参数;FSRS 里只有一个核心旋钮——期望保留率(desired retention),源码里的默认值就是desired_retention: 0.9(见 rslib/src/deckconfig/mod.rs)。官方给的压力曲线非常直观:
手册的措辞是"超过 90% 后工作量迅速攀升,超过 97% 会压垮人"。如果你希望把"记住多少"变成一个可以直接设定和验证的目标(配合"Ascending retrievability"排序和 rslib/src/stats/graphs/retrievability.rs 中的可提取性统计来验证),FSRS 的模型明显更贴合这种诉求。
第三问:你能接受"首次间隔变长"吗?
官方 FAQ 第一条就承认:FSRS 的 Good 首次间隔普遍比 SM-2 长(SM-2 毕业固定 1 天→6 天的节奏不再成立),但"对成熟卡片恰恰相反——FSRS 更保守"。对新卡占比较高的卡组(语言学习常见),切换后前两周的体感往往是"怎么都不回来";对以成熟卡为主的卡组,则更可能是"复习量下降"。两种体验都正常,提前知道预期就不会误判。
第四问:你的多端环境和插件生态允许吗?
任何一端旧客户端不支持,FSRS 数据同步就会出问题;依赖改间隔类插件(官方点名"if an add-on affects intervals and scheduling in some way, it shouldn't be used with FSRS")的,需要先做减法。
综合建议:复习量 ≥ 数千条、作答习惯干净、以成熟卡为主、全端已是新版——开,且不勾"Reschedule Cards on Change",按"一个月重新优化一次参数"的节奏走;刚起步或习惯混乱——先不急着开,把数据攒干净,FSRS 的优势本质上是"用数据换精度",没有数据就没有优势。SM-2 不会从 Anki 里消失(两条路径至今并存于 rslib/src/scheduler/states/review.rs 的ctx.fsrs_next_states分支判断中),这个开关的意义不是"新取代旧",而是让你自己决定:愿意用多少迁移成本,换多少调度精度。
【免费下载链接】ankiAnki is a smart spaced repetition flashcard program项目地址: https://gitcode.com/GitHub_Trending/an/anki
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考