在间隔重复系统(Spaced Repetition System)领域,Anki 和 Mochi 等工具长期占据主导地位,但它们都存在各自的局限性。2025 年出现的 hashcards 项目提出了一个革命性的设计理念:将闪卡存储为纯文本 Markdown 文件,而非传统的数据库格式。这一设计决策不仅改变了用户与学习材料的交互方式,更在工程层面带来了全新的架构挑战与机遇。
纯文本优先的设计哲学
hashcards 的核心设计理念源于一个简单的观察:知识工作者最熟悉的工具是文本编辑器。项目创始人 Fernando Borretti 在博客文章中详细阐述了他的设计思路:" 当学习教科书或网站时,我会在 Markdown 文件中编写闪卡。通常,我使用类似[foo]的简写来表示填空删除。然后使用 Python 脚本将简写转换为 Mochi 使用的{{1::foo}}符号。"
这种工作流程的自然延伸催生了 hashcards 的诞生。系统采用极简的文本格式:
Q: What is the role of synaptic vesicles?
A: They store neurotransmitters for release at the synaptic terminal.
C: Speech is [produced] in [Broca's] area.
每个 Markdown 文件对应一个 "牌组"(deck),文件名(不含扩展名)即为牌组名称。这种设计的优势在于:
- 零学习成本:用户无需掌握新的编辑界面,直接使用熟悉的文本编辑器
- 版本控制友好:Git 可以完美追踪闪卡的变化历史
- 脚本自动化:可以使用标准 Unix 工具或编程语言批量处理闪卡
内容寻址与数据持久化架构
hashcards 采用内容寻址(content addressing)机制来标识卡片。每张卡片通过其文本内容的 SHA-256 哈希值唯一标识。这一设计带来了重要的工程影响:
技术实现细节:
- 卡片哈希:
card_hash = SHA256(card_text) - 编辑即重置:当卡片内容被修改时,哈希值改变,系统将其视为新卡片,学习进度重置
- 数据库关联:SQLite 数据库中的
cards表通过card_hash字段关联纯文本卡片
数据库架构设计体现了数据分离的原则:
-- cards表存储学习进度
CREATE TABLE cards (
card_hash TEXT PRIMARY KEY,
added_at TEXT NOT NULL,
last_reviewed_at TEXT,
stability REAL,
difficulty REAL,
interval_raw REAL,
interval_days REAL,
due_date TEXT,
review_count INTEGER NOT NULL
);
-- reviews表记录每次复习历史
CREATE TABLE reviews (
review_id INTEGER PRIMARY KEY,
session_id INTEGER NOT NULL,
card_hash TEXT NOT NULL,
reviewed_at TEXT NOT NULL,
grade TEXT NOT NULL, -- 'forgot', 'hard', 'good', 'easy'
stability REAL NOT NULL,
difficulty REAL NOT NULL,
interval_raw REAL,
interval_days REAL,
due_date TEXT NOT NULL
);
这种架构实现了内容与进度的分离:纯文本文件存储 "是什么",SQLite 数据库存储 "学得怎么样"。这种分离使得:
- 备份简单:只需备份文本文件和数据库文件
- 迁移灵活:可以在不同设备间复制整个目录
- 恢复可靠:即使数据库损坏,卡片内容仍然完整
FSRS 算法在 hashcards 中的工程实现
hashcards 采用 FSRS(Free Spaced Repetition Scheduler)算法,这是目前最先进的间隔重复算法。与传统的 SM-2 算法相比,FSRS 基于深度学习模型,能够更准确地预测记忆保留率。
算法参数调优:
- 稳定性(stability):卡片在记忆中保持的时间长度
- 难度(difficulty):卡片的学习难度系数
- 间隔(interval):下次复习的时间间隔
FSRS 算法的核心公式基于记忆的三因素模型:
下次复习间隔 = f(稳定性, 难度, 评分等级)
在 hashcards 中,FSRS 的实现考虑了以下工程细节:
- 实时计算:每次复习后立即更新卡片参数
- 边界处理:确保间隔在合理范围内(通常 1 天到数年)
- 进度持久化:所有参数都存储在 SQLite 中,支持会话恢复
性能优化策略:
- 批量更新:在一次复习会话中批量更新数据库
- 延迟写入:非关键操作使用异步写入
- 索引优化:对
card_hash和due_date建立索引
跨平台同步的工程挑战与解决方案
纯文本存储的最大挑战在于多设备同步。与传统数据库应用不同,hashcards 没有内置的云同步机制,这既是设计选择,也是工程挑战。
同步冲突的三种类型
- 内容冲突:同一张卡片在不同设备上被不同修改
- 进度冲突:同一张卡片在不同设备上有不同的复习记录
- 结构冲突:牌组结构(文件组织)在不同设备上不一致
Git-based 同步策略
最直接的同步方案是使用 Git。hashcards 的纯文本特性使其天然适合 Git 工作流:
# 基本同步流程
git add .
git commit -m "Update flashcards"
git push origin main
# 在另一台设备
git pull origin main
hashcards drill ./Cards
Git 同步的最佳实践:
- 分支策略:为每台设备创建独立分支,定期合并到主分支
- 冲突解决:使用 Git 的合并工具解决文本冲突
- 自动化脚本:编写 pre-commit 钩子验证闪卡格式
增量同步算法设计
对于不想使用 Git 的用户,可以设计自定义的增量同步算法:
def sync_cards(local_dir, remote_dir):
# 1. 扫描本地和远程的卡片哈希
local_hashes = scan_hashes(local_dir)
remote_hashes = scan_hashes(remote_dir)
# 2. 识别新增、修改、删除的卡片
new_cards = remote_hashes - local_hashes
modified_cards = find_modified(local_hashes, remote_hashes)
deleted_cards = local_hashes - remote_hashes
# 3. 合并数据库记录
merge_databases(local_dir, remote_dir)
# 4. 解决冲突
resolve_conflicts(local_dir, remote_dir)
数据库同步策略
SQLite 数据库的同步需要特殊处理,因为直接复制数据库文件可能导致数据损坏:
安全的数据同步方案:
- 导出 / 导入模式:使用
hashcards export命令导出 JSON,在目标设备导入 - 增量合并:只同步新增的复习记录,忽略时间戳冲突
- 最后写入胜出:对于冲突的进度记录,采用时间戳最新的版本
可落地的部署参数与监控指标
部署配置清单
对于生产环境部署,建议以下配置:
-
存储参数:
- 最大牌组数量:无限制(受文件系统限制)
- 单张卡片最大大小:10MB(考虑图片和音频嵌入)
- 数据库文件大小预警阈值:1GB
-
性能参数:
- 并发用户数:单实例支持 50 个并发会话
- 响应时间:卡片加载 < 100ms,复习提交 < 50ms
- 内存使用:基础内存占用 < 50MB,每 1000 张卡片增加~10MB
-
同步参数:
- 自动同步间隔:15 分钟(移动设备),1 小时(桌面设备)
- 冲突检测阈值:5 分钟内同一卡片的修改视为冲突
- 备份频率:每日自动备份到云存储
监控指标体系
建立完整的监控体系确保系统稳定性:
-
性能指标:
hashcards_response_time_avg:平均响应时间hashcards_active_sessions:活跃会话数hashcards_cards_reviewed_per_minute:每分钟复习卡片数
-
业务指标:
hashcards_new_cards_per_day:每日新增卡片数hashcards_review_completion_rate:复习完成率hashcards_retention_rate_7d:7 天记忆保留率
-
系统健康指标:
hashcards_database_size:数据库文件大小hashcards_file_system_usage:文件系统使用率hashcards_sync_success_rate:同步成功率
工程实践中的注意事项
安全性考虑
- 本地存储安全:数据库文件应加密存储,特别是包含学习历史时
- 网络传输安全:如果实现自定义同步,必须使用 TLS 加密
- 输入验证:严格验证用户输入的卡片内容,防止注入攻击
可扩展性设计
- 插件架构:支持第三方插件扩展功能
- API 设计:提供 REST API 供其他应用集成
- 格式兼容:支持导入 Anki、Mochi 等格式的卡片
故障恢复机制
- 自动备份:定期自动备份卡片和数据库
- 完整性检查:
hashcards check命令验证集合完整性 - 孤儿卡片管理:
hashcards orphans命令管理已删除卡片的残留记录
未来发展方向
hashcards 的纯文本架构为未来扩展提供了坚实基础:
- 协作学习:基于 Git 的协作闪卡编辑和复习
- AI 增强:集成 LLM 自动生成卡片或优化卡片内容
- 离线优先:完善的离线功能与智能同步
- 跨平台一致性:确保在所有平台上的体验一致
正如 Borretti 在博客中所说:"'Git 仓库中的 Markdown 文件 ' 给了我其他方法所缺乏的所有权感。" 这种所有权感正是 hashcards 设计的核心 —— 将学习材料的控制权完全交还给用户。
通过将复杂的间隔重复算法与简单的纯文本存储相结合,hashcards 在工程优雅性与用户友好性之间找到了平衡点。对于重视数据所有权、喜欢使用文本工具的知识工作者来说,它提供了一个既强大又透明的学习系统。
资料来源:
- hashcards GitHub 仓库 - 项目架构与实现细节
- Hashcards: A Plain-Text Spaced Repetition System - 设计理念与比较分析