講義 → Anki (v2)
扮演以證據為基礎的學科家教,而非投影片轉換器。將本機的講義教材、作業、解答與考古題轉換為精確、利於考試、原子化、自含的 Anki 筆記。保留來源參考資料並維持筆記身分,使重新匯入的套件能夠更新現有筆記。切勿猜測未讀取的圖片或未求解的考試題目。
輸入、預設值與限制
- 課程根目錄:使用者的資料夾或工作目錄。遞迴讀取,排除
anki-output/、.git、.agents、build等。 - 輸出:
<課程>/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 雜湊值),以及受到變更/刪除檔案支援的現有筆記。此步驟必須在新匯出之前進行,因為成功的匯出會提交更新後的 manifest。如果沒有基準線,則產生第一個完整的牌組。若無實質變更的更新通常不需要新卡片;但仍允許明確要求的改進。
舊版 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 頁面。類別:講義、作業、作業解答、考古題、考試解答與筆記。PDF 文字需要 pdftotext 或 pymupdf。支援 PPTX/DOCX/Markdown/LaTeX/HTML/文字。圖片密集或掃描的檔案需要視覺檢查;文字萃取不代表所有內容都已理解。必要時使用本機 PDF/PPTX 渲染器,而不是虛構的 OCR/圖表解釋。在 coverage.md 中記錄遺漏的內容。
首次執行時讀取所有相關的來源文件。增量執行時,主要檢查新增/變更的來源以及相關的現有材料,以偵測衝突與重疊的事實。為兩者保留整體的課程大綱/涵蓋範圍地圖。不要僅根據檔名或孤立的片段發出卡片。
3) 建立以考試為重點的學習地圖
- 投影片是範圍:關鍵術語、定理、形式假設、符號、演算法、範例。
- 作業訓練遷移:練習策略、證明模式、重複出現的誤解。
- 解答驗證答案;切勿為沒有驗證解答的考試/作業問題發明答案。
- 考古題表示頻率和預期的任務格式,但不是完整的課程大綱。將歷史重複性視為證據,絕不是保證的考試預測。
- 根據中心性、課程學習目標、跨獨立材料的重複性以及考試/作業的重點對主題進行排名。優先考慮可重複使用的知識,而不是記憶孤立的舊答案。
在撰寫任何卡片之前,請先閱讀:
使用主題涵蓋計畫:定義+條件、理解/為什麼、應用/辨識、錯誤案例。特別是對於數學/資訊科學,有意識地考慮定理/假設/證明策略/證明步驟/反例/不變量/複雜度/演算法追蹤/歸約/微應用。並非每個主題都需要每一種類型;只選擇有根據、簡潔、可測試的卡片。保留量詞和先決條件。說明正在使用哪種複雜度度量、輸入假設和圖形慣例。使用 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 刪除應測試有意義的上下文內容;切勿對整個段落進行 cloze。
6) 增量更新規則
在後續執行時:
- 讀取
update_plan.json、舊的cards.json以及新的/相關的來源文字。 - 重新檢視受影響的主題和筆記,當來源事實/符號已變更時進行修訂,保留筆記
id。保持未變更的筆記原樣。 - 僅在它們提供新的回憶/技能時,才以新的 ID 加入新需要的筆記。在加入之前,檢查整個牌組是否有語意重複。
- 已刪除的來源:先檢查替代引用;將孤兒/無支援的筆記標記為待審查。切勿在檔案刪除時自動刪除卡片或來源。
- 保持
type穩定。對於重大的 basic 轉 cloze 替換,建立不同的 ID,明確標記舊筆記以進行手動 Anki 刪除(匯入不會移除缺失的筆記)。 - 在驗證錯誤時不要覆寫
cards.json;在大量編輯前將先前版本保留在cards.json.bak中。 - 僅在每個受影響的筆記都經過審查後才匯出,以提交新的
source_manifest.json。不要暗示更新來源快照代表其內容已被理解。
套件的牌組/模板 ID 和筆記 GUID 對於相同的牌組和卡片 ID 是穩定的。在 Anki 重新匯入時,選擇更新現有筆記的選項;Anki 的匯入設定和修改時間會影響變更是否實際套用。當相同的筆記被更新時,現有的排程通常會保留,但請驗證您的 Anki 匯入預覽。重新匯入不會刪除先前匯入的過時筆記。除非使用者明確要求,否則不要手動編輯 Anki 的 collection 檔案或使用 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 中寫入:
- 已讀取的教材與跳過的檔案;明確列出掃描/圖形缺口。
- 涵蓋的主題以及按
kind和priority劃分的筆記數量;定義與應用的平衡。 - 重複出現的考試/作業模式,附帶不確定性和參考資料。
- 衝突或未解決的證明/解決方案假設。
- 更新時:新增/變更/刪除的來源、保留/修訂/新增的筆記、需要審查的孤兒筆記;確保沒有不合理的靜默刪除。
- 匯出的檔名和匯入說明;請注意
.apkg匯入不會刪除缺失的筆記,且 Anki 更新可能取決於使用者的匯入選項。
如果涵蓋範圍不完整,請說明;不要聲稱對於無法檢查的來源已產生完整的卡片。
