艾宾浩斯复习工具 Recall写在前面你有没有过这种经历背了一上午的英语单词第二天醒来全忘了或者学了一个技术点过两周再看跟第一次见一样这不是你记忆力差是人脑的遗忘曲线决定的。德国心理学家艾宾浩斯早在 1885 年就通过实验发现人类对无意义音节的记忆保持率在学习后 20 分钟、1 小时、1 天、6 天分别约为 58%、44%、33%、25%。那有没有办法对抗遗忘有——间隔重复Spaced Repetition。简单说就是在你快要忘掉的时候刚好复习一下每次复习之后间隔可以拉长直到真正进入长期记忆。市面上已经有 Anki、Quizlet 这类产品但 Anki 配置太折腾、UI 不够友好Quizlet 在线使用体验好但离线要翻墙。我想要一个轻量、好看、纯本地、数据完全自己掌控的复习工具——所以就搞了个Recall。GitHub 项目地址 https://github.com/suger-cheng/memory-tool一、先看成品长什么样 今日概览打开应用第一眼就能看到今天要复习多少张、留存率、总卡片数、连续打卡天数、XP 和等级进度。 卡片管理三种卡片类型记忆卡片、知识点笔记、语录收藏。支持按卡组分类嵌套卡组也没问题。 卡组管理卡组树结构默认卡组 自建卡组每日新卡数和复习上限独立配置。⚙️ 设置页主题切换、每日限额、托盘提醒、JSON 导入导出、数据库备份、自定义数据目录改完自动迁移。二、核心算法9 阶段间隔 三级反馈 长期记忆毕业2.1 艾宾浩斯遗忘曲线艾宾浩斯的实验公式是R(t) e^(-t/S)其中 R 是记忆保持率t 是经过的时间S 是记忆强度和复习次数正相关。我们的目标是在 R 降到某个阈值之前恰好复习一次把 S 拉高下次间隔可以更长。2.2 九阶段间隔表我把复习间隔设计成 9 个递进阶段从第一次复习的 5 分钟到第 9 次的 30 天阶段123456789基础间隔5 分钟30 分钟12 小时1 天2 天4 天7 天15 天30 天但这不是死板的——每张卡还有一个ease难度因子1.3~3.0实际间隔 基础间隔 × (ease / 2.5)。容易的卡ease 大间隔自动拉长难的卡ease 小间隔自动压缩。2.3 三级反馈机制每次复习完一张卡用户只需要点三个按钮之一反馈quality阶段变化ease 变化熟练度变化获得 XP 记住了21最高到第 9 阶段0.08100/9 × (ease/2.5)10 模糊1-1最低到 0-0.05-54 忘了0重置为 0-0.3×0.41忘了惩罚最重阶段清零 ease 大减 0.3 熟练度砍到 40%——但还是能拿到 1 XP哪怕只是打开应用标记忘了也是好的鼓励用户保持习惯。2.4 熟练度与毕业系统熟练度范围 0~100达到 100 时卡片毕业从普通复习流程进入长期记忆池长期记忆卡片使用 60 天基础间隔按 ease 增长上限 180 天长期记忆卡片若再被标忘了退回普通流程熟练度降至当前值的 40%毕业就像通关——你不会再被一张已经记住的卡反复打扰。2.5 复习队列优先级一天到期的卡可能有几十上百张按什么顺序复习我的设计逾期普通卡 今日到期 即将到期 逾期长期卡同优先级内逾期天数降序 → ease 升序 → 熟练度升序简单说就是越该复习的卡越靠前让每张卡都在最佳遗忘临界点被复习。2.6 核心算法代码算法集中在review_engine.py核心就一个函数defapply_feedback(card:dict,feedback:str)-dict:根据用户反馈更新卡片的阶段、ease、熟练度。q{forgot:0,fuzzy:1,remembered:2}[feedback]# 三级反馈更新逻辑ifq2:# 记住了card[stage]min(card[stage]1,9)card[ease]min(card[ease]0.08,3.0)card[mastery]100/9*(card[ease]/2.5)elifq1:# 模糊card[stage]max(card[stage]-1,0)card[ease]max(card[ease]-0.05,1.3)card[mastery]max(card[mastery]-5,0)else:# 忘了card[stage]0card[ease]max(card[ease]-0.3,1.3)card[mastery]*0.4# 熟练度达标 → 毕业ifcard[mastery]100andnotcard[is_long_term]:card[is_long_term]1returncard三、技术栈 架构设计3.1 为什么选 PySide6框架优点缺点PySide6我选的Qt 官方 Python 绑定、文档全、跨平台、QSS 样式能力强、社区成熟打包体积大但 PyInstaller 可解决Tkinter自带、轻量样式丑、功能弱、图表支持差PyQt5/6功能和 PySide6 类似GPL/商业双授权商用要花钱Electron/CEFUI 最好看体积大动辄 100MB、内存占用高PySide6 是目前 Python 桌面 GUI 的性价比之王——免费LGPL 协议、跨平台、样式系统灵活、图表渲染可以接 pyqtgraph。3.2 整体架构┌──────────────────────────────────────────────┐ │ PySide6 界面层 │ │ dashboard_view / review_view / card_manager │ │ deck_manager / stats_view / settings_view │ └──────────────────┬───────────────────────────┘ │ 调用 ┌──────────────────▼───────────────────────────┐ │ 业务逻辑层 │ │ review_engine.py 复习调度算法 │ │ gamification.py XP/等级/成就 │ │ scheduler.py 定时提醒 │ └──────────────────┬───────────────────────────┘ │ 读写 ┌──────────────────▼───────────────────────────┐ │ SQLite 数据层 │ │ database.py 连接管理 路径解析 │ │ utils/import_export.py JSON 导入导出 │ └──────────────────────────────────────────────┘3.3 数据模型全部 7 张表职责清晰表职责cards卡片数据 复习调度状态stage/ease/mastery/is_long_termdecks卡组支持嵌套parent_id 自关联review_log每次复习的完整记录含前后状态快照 反应时间daily_stats按天聚合的统计settings键值对配置user_progressXP 与等级achievements成就定义与解锁状态用 SQLite WAL 模式 单连接复用性能和稳定性都够用。3.4 数据路径的坑这里有个我花了点心思的设计数据目录可配置 自动迁移。问题如果把路径硬编码成E:\data\xxx别人 Windows 机器上 E 盘不存在就崩了。但如果放在安装目录升级/卸载会丢数据。方案默认路径跨平台Windows 用%APPDATA%、macOS 用~/Library/Application Support、Linux 用$XDG_DATA_HOME引导配置独立在~/.recall_config.json存data_dir——放在用户 home 而不是 data_dir 里否则改了 data_dir 后下次启动找不到自己在哪一键迁移设置里选新目录 → 自动关闭连接 → 迁recall.db-wal-shm→ 写引导配置。还做了目标目录可写校验、已存在数据库拒绝覆盖、迁移中途失败自动回滚便携版支持设环境变量RECALL_BOOT_CONFIG./boot.json就能把引导配置也挪走整个 Recall 可以跟着 U 盘走# database.py —— 路径解析核心逻辑def_get_data_dir()-str:默认路径按系统选择。ifsys.platformwin32:baseos.environ.get(APPDATA)oros.path.expanduser(~)elifsys.platformdarwin:baseos.path.expanduser(~/Library/Application Support)else:baseos.environ.get(XDG_DATA_HOME)oros.path.expanduser(~/.local/share)returnos.path.join(base,Recall)def_resolve_data_dir()-str:优先级引导配置 系统默认。cfg_load_boot_config()# 读 ~/.recall_config.jsoncustom(cfg.get(data_dir)or).strip()ifcustomandos.path.isabs(custom):returncustomreturn_default_data_dir()四、游戏化让坚持下去变得容易纯工具很难坚持加了一点游戏化元素XP 与等级每次复习拿 XP记住 10、模糊 4、忘了 1升级公式100 × (n-1) × n / 28 种成就徽章初次复习、勤奋学习者10/100 张、连续打卡3/7 天、完美一轮、长期记忆、小有所成Lv.5连续打卡天数断一天就清零——但这也是动力XP 系统其实是个副产品算法本身已经很科学了但加了数字反馈之后用户会更愿意打开应用——这对坚持来说比算法精度更重要。五、快速上手方式一源码运行# 克隆仓库gitclone https://github.com/suger-cheng/memory-tool.gitcdmemory-tool# 安装依赖pipinstall-rrequirements.txt# 运行python main.py方式二打包 exe 分发pipinstallpyinstaller# 单目录模式推荐启动快pyinstaller--onedir--windowed--nameRecall main.py# 产物dist/Recall/Recall.exe分发时把dist/Recall/整个文件夹压缩给对方即可。对方双击就能用数据目录自动按系统选择无需配置。依赖清单PySide6 6.5.0 pyqtgraph 0.13.0Python 3.10 即可。也可以直接安装exe文件无需安装各种依赖直接运行。有任何问题或建议欢迎在 GitHub 提 Issue / PR也可以在评论区交流。项目地址https://github.com/suger-cheng/memory-tool⭐ 如果觉得有用记得给项目点个 Star