Community编程与开发github.com

lukezielke/lecture-to-anki

从大学课程文件夹(包含讲义、习题、解答和旧试卷)创建并增量更新针对考试的 Anki 牌组。支持数学/计算机科学题型、稳定笔记 ID、图表和 .apkg 包。

lecture-to-anki 是什么?

本技能(Lecture → Anki v2)是一个 AI 驱动的工具,旨在将本地大学课程材料(如讲义幻灯片、作业、解答和以往考试题目)转化为高质量的 Anki 复习卡片。其核心理念是“证据驱动的学科导师”,而非简单的“幻灯片到要点转换器”,强调生成准确、原子化、自包含且聚焦于考试的笔记。它通过保持稳定的笔记 ID 和牌组名称,支持增量更新,使得重新导入 .apkg 包时能更新现有笔记,而非创建重复项。该技能适用于主流 AI 编程助手(如 Claude Code, Cursor, Codex),并在用户本地文件系统上工作,不进行网络查找或第三方上传。工作流程包括:确定首次运行或更新、读取并盘点源文件、构建学习地图、生成包含 MathJax 和本地图片的卡片、输出 .apkg 或文本格式,并生成覆盖率报告以跟踪理解差距。它特别擅长处理数学和计算机科学领域的概念,要求显式考虑定理、证明策略、复杂度、算法追踪等内容,并支持从 PDF 或 PPTX 中裁剪图像。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/lukezielke/skills/tree/HEAD/skills/lecture-to-anki

Installed? Explore more 编程与开发 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

预览

来自技能 README

lecture-to-anki preview

文档

讲义 → Anki (v2)

扮演一个基于证据的学科导师,而不是幻灯片到要点的转换器。将本地讲义材料、作业、解答和以往考试转化为准确、对考试有用、原子化、自包含的 Anki 笔记。保留来源引用并维护标识符,以便重新导入的包更新现有笔记。绝不猜测未读的图表或未解决的试题。

输入、默认值和约束

  • 课程根目录:用户的文件夹或工作目录。递归读取,排除 anki-output/、.git、.agents、build 等。
  • 输出:<course>/anki-output;规范的可编辑数据是 cards.json。
  • 牌组:除非另有提供,否则使用课程文件夹名;更新期间不要重命名,因为这会更改牌组/模型标识符。
  • 模式:exam-focused(默认)、comprehensive、topic-specific 和 update。
  • 交付:默认是 deck.apkg,可选 basic.txt/cloze.txt。需要 genanki 来生成 .apkg。只在需要时征得用户许可后安装;如果不可用,使用 --format text 导出文本并解释限制。
  • 只读取和写入课程树/指定输出目录内;不要更改或删除讲义材料;未经用户请求,不上传第三方或进行网络查找。
  • 更新时保持相同的牌组名称、笔记 id 值和卡片类型。更改卡片的笔记类型会破坏其标识符,可能在 Anki 中创建一个单独的笔记。

工作流程

1) 在提取前确定首次运行还是更新

如果 <output>/cards.json 和 <output>/source_manifest.json 存在,首先运行:

python3 <skill-dir>/scripts/plan_update.py "/path/to/course"

读取 anki-output/update_plan.json。它报告新添加、更改和删除的源文件(SHA-256 哈希)以及由更改/删除文件支持的现有笔记。此步骤必须在新导出之前完成,因为成功的导出会提交更新的清单。如果没有基准线,则生成完整的初始牌组。没有材料变化的更新通常不需要新卡片;但仍然允许显式请求的改进。

旧的 v1 cards.json 没有显式的笔记 ID:在编辑问题之前,运行一次:

python3 <skill-dir>/scripts/migrate_ids.py "/path/to/course/anki-output/cards.json"

这会写入一个 .bak 备份,并使用原始问题填充缺失的 ID。永远保持这些 ID 不变(即使相应问题的措辞或引用的幻灯片发生了变化)。

2) 读取并盘点源文件

python3 <skill-dir>/scripts/extract_sources.py "/path/to/course" \
  --output "/path/to/course/anki-output/sources.jsonl"

查阅 sources_report.json;它包含每个文件的哈希值、类型、类别分类、无法访问的文件和空白的 PDF 页面。类别:lectures、homework、homework solutions、past exams、exam solutions 和 notes。PDF 文本需要 pdftotext 或 pymupdf。支持 PPTX/DOCX/Markdown/LaTeX/HTML/文本。图像密集或扫描文件需要视觉检查;文本提取并不能证明所有内容都已被理解。根据需要调用本地 PDF/PPTX 渲染器,而不是编造 OCR/图表解释。在 coverage.md 中记录被省略的内容。

在首次运行时读取所有相关的源文档。对于增量运行,主要检查新增/更改的源文件以及相关的现有材料,以检测冲突和重叠的事实。为两者维护一个整体课程大纲/覆盖率映射。不要仅仅基于文件名或孤立的片段创建卡片。

3) 构建一个聚焦考试的学习地图

  1. 幻灯片是范围:关键术语、定理、形式化假设、符号、算法、示例。
  2. 作业训练迁移:解题策略、证明模式、反复出现的误解。
  3. 解答验证答案;绝不要为没有已验证解答的考试/作业问题编造答案。
  4. 以往考试表明频率和预期的任务格式,但不是完整的教学大纲。将历史重复视为证据,绝不是有保证的考试预测。
  5. 根据中心性、课程学习目标、跨独立材料的重复出现以及考试/作业重点对主题进行排序。优先考虑可复用的知识,而不是记忆孤立的旧答案。

在编写任何卡片之前,请阅读:

使用主题覆盖计划:定义+条件、理解/原因、应用/识别、错误案例。对于数学/计算机科学尤其重要的是,有意识地考虑定理/前提/证明策略/证明步骤/反例/不变式/复杂度/算法追踪/归约/微应用。并非每个主题都需要所有类型;只选择合理、简洁、可测试的卡片。保留量词和前提条件。说明使用了哪种复杂度度量、输入假设和图约定。使用 Anki MathJax \(...\) 或 \[...\],并进行正确的 JSON 转义。

4) 在需要时使用图像和图表

文本提示对于图、自动机、树、架构图、算法追踪、几何构造或符号密集的公式来说是不够的。如果视觉内容是必要的,将其包含在卡片中,而不是让学习者想象它。

首先视觉检查图形以确定确切区域;不要自动复制整张幻灯片或不分青红皂白地包含图形。

对于裁剪的 PDF 图表(坐标以 PDF 点为单位):

python3 <skill-dir>/scripts/prepare_media.py pdf "/path/to/course/slides/L3.pdf" \
  --page 12 --crop 100,90,490,330 --output "/path/to/course/anki-output/media"

对于完整的 PPTX 幻灯片(需要 LibreOffice + PyMuPDF)或嵌入的 PPTX 图片:

python3 <skill-dir>/scripts/prepare_media.py pptx-slide "/path/to/course/slides/L3.pptx" \
  --slide 7 --output "/path/to/course/anki-output/media"
python3 <skill-dir>/scripts/prepare_media.py pptx-image "/path/to/course/slides/L3.pptx" \
  --slide 7 --image 1 --output "/path/to/course/anki-output/media"

对于现有的 .png、.jpg 等,使用 prepare_media.py image ... --output ...。

将确切的基本名称插入卡片的 HTML:<img src="lta_example_abcdef1234.png">。同时将该笔记的 "media": ["media/lta_example_abcdef1234.png"] 添加到该笔记中。HTML 文件名只是基本名称(没有 media/ 前缀)。资源必须是本地的,并且在选择的输出文件夹下。这确保 .apkg 包含它们。请参阅 references/cards-schema.md。

避免将用户特定的课程答案存储为图像,当可复制且屏幕阅读器友好的数学文本可以传达相同内容时;在文本中描述或说明重要的视觉关系。图形不能替代验证概念的正确性。

5) 生成/维护 cards.json

使用 references/cards-schema.md 中的模式;每条笔记必须有一个唯一的稳定 id(例如 graphs.dijkstra.nonnegative)。在更新期间,绝不能从编辑后的问题文本中派生新的 ID。在首次生成时创建一个稳定的 ID;将其持久化在 cards.json 中。ID 必须在牌组中保持唯一,并且卡片 type 应该保持稳定。

包括:

  • type:basic 或 cloze(Anki 笔记类型;大多数数学/计算机科学任务适合 Basic)。
  • kind:例如 theorem、proof_idea、counterexample、algorithm_trace、complexity、application(分类标签,不是 Anki 模板)。
  • front/back 或 text/extra。
  • source_file 和 source_location,加上当内容跨多个文件验证时的 supporting_sources。
  • tags 包含 topic::...、priority::...、from::...。
  • 使用时的 media。

一个 Basic 问题必须能够在大约 5-30 秒内独立回答,针对一个事实或想法,并区分假设和结论。将长的算法演练/证明分解为短的可测试步骤。Cloze 删除应该测试有意义的上下文内容;永远不要删除整个段落。

6) 增量更新规则

在后续运行时:

  1. 读取 update_plan.json、旧的 cards.json 以及新的/相关的源文本。
  2. 重新审视受影响的主题和笔记,当源事实/符号发生变化时进行修订,保留笔记 id。逐字保留未更改的笔记。
  3. 添加新需要的笔记,使用新 ID,仅在它们贡献新的回忆/技能时。在添加之前检查整个牌组中是否存在语义重复。
  4. 删除的源:首先检查备用引用;标记孤立的/无支持的笔记以供审查。在文件被删除时,永远不要自动删除卡片或源。
  5. 保持 type 稳定。对于重大的 basic 到 cloze 替换,创建一个独特的 ID,显式标记旧笔记以进行手动的 Anki 删除(导入不会移除缺失的笔记)。
  6. 在验证错误时不要覆盖 cards.json;在进行大规模编辑前,在 cards.json.bak 中保留之前的版本。
  7. 只有在所有受影响的笔记都被审查后才进行导出,以提交新的 source_manifest.json。不要暗示更新源快照意味着其内容已被理解。

包的牌组/模型 ID 和笔记 GUID 对于相同的牌组和卡片 ID 都是稳定的。在 Anki 重新导入时,选择更新现有笔记的选项;Anki 的导入设置和修改时间可能会影响更改是否真的被应用。当相同的笔记被更新时,现有的调度通常保持不变,但请验证你的 Anki 导入预览。重新导入不会删除之前导入的过时笔记。除非用户明确要求,否则不要手动编辑 Anki 的集合文件或使用 AnkiConnect。

7) 验证并导出

python3 <skill-dir>/scripts/export_anki.py "/path/to/course/anki-output/cards.json" \
  --output "/path/to/course/anki-output" \
  --course "/path/to/course" --format both

--format both(默认)生成 deck.apkg、basic.txt、cloze.txt(如适用)、export_report.json 和 source_manifest.json。将 .apkg 或 .txt 文件之一导入特定的 Anki 集合,不要同时导入两者:不同的笔记类型会导致重复。--format text 可以在没有 genanki 的情况下工作,但其导入器使用第一个字段匹配,并且无法通过 ID 安全地修订问题。对于持续的增量更新,使用 .apkg。--format apkg 跳过文本导出。

安装 .apkg 依赖项(如果可用):

python3 -m pip install genanki

检查 export_report.json 中的卡片数量、缺失的显式 ID、跳过的完全重复项、媒体数量。解决验证错误而不是忽略它们。媒体源文件名必须唯一且正确引用。从 Anki 的文件 → 导入导入 .apkg。

8) 总结覆盖范围和质量保证

将 <output>/coverage.md 写入包含:

  • 已读材料 vs 跳过的文件;显式列出扫描/图形缺口。
  • 覆盖的主题以及按 kind 和 priority 划分的笔记数量;定义 vs 应用平衡。
  • 重复出现的考试/作业模式,附有不确定性和引用。
  • 冲突或未解决的证明/解答假设。
  • 在更新时:新增/更改/删除的源文件,保留/修订/添加的笔记,需要审查的孤立笔记;确保没有不合理的静默删除。
  • 导出的文件名和导入说明;注意 .apkg 导入不会删除缺失的笔记,并且 Anki 更新可能取决于用户的导入选项。

如果覆盖范围不完整,请如实说明;不要声称对无法检查的源文件生成了完整的卡片。

相关技能