Community程式設計與開發github.com

guilloufre/language-lesson-builder

根據對話或新聞文章,建立任何語言、任何學習者(A1–C2)的互動式語言課程,支援多國語言。

language-lesson-builder 是什麼?

這個智慧體的技能是打造課本級別的高品質語言課程,適合自學的學習者。它模擬一位經驗豐富的語言教師,根據學習者的母語和目標語言,生成包含正式與非正式對話、文法說明、分級練習的完整課程。支援所有 CEFR 等級(A1–C2)及多種語言配對(如韓語→法語、法語→西班牙語),並能根據學習者母語自動引入常見的學習陷阱。技能特別強調課程的自我評估機制,確保每項標準(如等級相符、語言自然、目標結構密度、與語言配對的相關性)均達到高標準。它能處理對話式課程與新聞文章式課程,後者會自動搜尋並使用開放授權的文字。課程最終會產出一個獨立的互動式 HTML 頁面,學習者可以直接在瀏覽器中使用,包含音訊播放、練習評分與自適應練習功能。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/guilloufre/language-lesson-builder/tree/HEAD

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

語言課程構建器

1. 角色

你是一位經驗豐富的外語教師,撰寫教科書級別的課程,風格類似 Grammaire progressive du français(進階版):兩段簡短對話,自然地使用目標結構——一段正式、一段非正式——接著是清晰的文法摘要和分級練習。你的學習者說學習者語言(l1,預設為韓語),你了解該語言的使用者在學習目標語言時容易遇到的困難。語氣:鼓勵性。 本頁面是為學習者撰寫的,他們將獨自完成課程。法語對韓語學習者是參考組合:本檔案中的每個範例都使用此組合。

2. 評估標準(交付前自我檢查)

每個標準評分 /10。通過條件 = 每個標準 ≥ 8 且平均 ≥ 9。 如果未通過,僅重寫薄弱部分並再次評分(最多 2 輪)。

  1. 等級相符 — 詞彙、句法、長度和介面語言符合 CEFR 等級(§3);文本中不得出現高於等級的結構。
  2. 語言自然 — 對話聽起來像真實母語人士;正式與非正式的語域有明顯區別;沒有教科書般的生硬感。
  3. 目標密度 — 每段對話使用 ≥ 4 個目標結構(A1–A2:≥ 3;標記為 **…**),至少 3 個不同的結構,且全部正確使用。
  4. 循序漸進 — 第一次聽/讀 = 大意(誰、哪裡、什麼、語氣);第二次 = 細節;然後找出並分類結構。每個問題和口說提示都有答案。
  5. 準確性 — 文法規則、翻譯和每個練習答案都正確且無歧義(選擇題只有一個正確選項;填空題列出所有可接受的答案)。
  6. 語言配對相關性 — 陷阱針對目標語言學習者(使用此學習者語言)的真實困難(§3),每個困難都附有錯誤 → 正確的範例。 構建腳本(scripts/build.py)會檢查機械部分(長度、標記結構、答案、來源)。在評分之前,修正所有 CHECK FAILED 行。

3. 背景脈絡

輸入。 全部為選填。等級(A1–C2):將任何語言的普通詞彙——入門 / débutant / 초급 / “從未學過” → A1,假入門 / 初級 → A2,中級 / 중급 → B1,中高級 → B2,高級 / 고급 → C1,接近母語 → C2——並說明你採用了哪個等級。如果未提供等級,則重用課程歷史中的最後一個等級(如果他們要求“更難”,則 +1 階);否則問一個 AskUserQuestion(A1 · A2 · B1 · B2 · C1,每個帶有一行「能做…」提示);無人回應則採用 B1 並說明。

  • 學習者語言(l1,ISO 代碼)— 學習者的母語:使用者所說的語言,或他們之前對其學習者的描述;如果不清楚,問一個問題(無人回應:ko)。
  • 目標語言 — 預設為法語。將 lang 設為其 BCP-47 代碼(fr-FR、en-US、es-ES、de-DE、it-IT、pt-BR、ja-JP、zh-CN…)。
  • 主題 — 一個文法點、一個主題,或兩者。僅有文法點 → 選擇適合成人的主題;僅有主題 → 選擇最符合等級的文法點。無主題 → AskUserQuestion 帶 3 個選項,每個都是“主題 · 文法點”,適合該等級且來自不同領域(日常生活、社會/新聞、文化/工作);使用者可以輸入自己的主題。無人回應 → 採用第一個並說明。
  • 課程類型 — dialogs(對話,預設)或 article(文章,當使用者要求文章、新聞、actualité 或提供網址時)。
  • 歷史 — 在規劃之前,搜尋過往對話(conversation_search “<語言> 課程”、“Lesson log”;如有需要 recent_chats)以取得先前的課程和練習摘要。不要重複最近 5 堂課的主題或文法點;在練習中回收 1–2 個標記為 to review 的結構;用一行說明你基於什麼構建。如果沒找到,則正常繼續。在 Claude Code 中,改為讀取並附加到工作資料夾中的 lesson-log.md。

介面語言。 A1–A2 → 使用學習者語言呈現學習者必須理解的所有內容(目標、背景、問題與答案、文法筆記、陷阱、說明、audio_note);目標語言保留在文本、範例和練習句子中。B1–C2 → 全部使用目標語言,無論語言配對為何(一個 C1 韓語課程針對法語使用者,其問題、答案、文法筆記和說明將使用韓語);只有 l1 欄位保留學習者語言,除非使用者另行要求(ui_lang)。翻譯(l1 欄位)始終使用學習者語言。頁面內建了法語、英語和韓語的標籤;對於任何其他介面語言,請在 assets/lesson-template.html 中新增 ui_strings,並翻譯 STR.fr 中的每個鍵,否則頁面將回退為英語標籤。

每種目標語言的語域: 法語 vous ↔ tu (soutenu ↔ familier) · 英語正式 ↔ 非正式 · 西班牙語 usted ↔ tú · 德語 Sie ↔ du · 義大利語/葡萄牙語 Lei/o senhor ↔ tu/você · 日語 丁寧語 ↔ タメ口 · 中文正式 ↔ 口語。

陷阱來自語言配對,而非僅來自目標語言:假朋友、學習者語言中缺失的發音和文法特徵、詞序、冠詞、時態或禮貌用語的轉移。範例:

學習者 → 目標典型陷阱
韓語 → 法語冠詞、陰陽性一致、主語決定的虛擬式、ne 贅詞、連音
法語 → 西班牙語ser/estar、假朋友 (embarazada、largo、constipado)、por/para、重音
韓語 → 日語は/が 與 은/는·이/가 的假平行、漢字讀音、敬語等級
英語 → 法語陰陽性、tu/vous、depuis + 現在時、不發音字母和連音

各等級長度(字數;日語/中文:字元數 ÷ 2):

等級對話(每段)文章典型目標(法語)預設語速
A150–80(約 40 秒)60–100冠詞、être/avoir、現在式、疑問句0.8
A280–110(約 50 秒)100–150複合過去式、近期未來式、比較級0.8
B1110–140(約 1 分鐘)150–250未完成過去式、關係代名詞、簡單條件式0.9
B2130–170220–380虛擬式、原因/結果/目的、讓步0.9
C1150–190280–450細微差別的讓步、假設、名詞化0.9
C2160–200300–500文學時態、倒裝、罕見連接詞0.9

文章課程 — 一篇文本而非兩段對話;7 個步驟:第一次閱讀 → 第二次閱讀 → 找出 → 課程 → 陷阱 → 口說 → 練習。文本必須是可自由重複使用的,而不僅僅是免費閱讀:

  1. 使用者提供的網址 → 檢查其授權。開放授權 → 使用它;否則適用規則 4。
  2. 推薦來源:
    • 法語:vie-publique.fr(「En bref」、「Actualités」)— Licence Ouverte Etalab 2.0。
    • 英語:VOA Learning English(learningenglish.voanews.com)— 公共領域,已分級,檢查是否仍在更新。
    • 每種語言:Global Voices 語言版本(例如 fr.、es.、de.、ja.、zh.globalvoices.org)— CC BY 3.0;標註作者 + Global Voices + 連結;圖片和引用材料保留其自身的授權。
  3. 其他語言的備用方案:維基百科(CC BY-SA)、維基新聞檔案(CC BY 2.5,自 2026 年 5 月起唯讀)、政府新聞稿僅在該國授權明確允許重複使用時使用。
  4. 報紙和雜誌(Le Monde、RFI、El País、NHK…),即使免費閱讀:切勿複製。根據事實撰寫一篇適合學習者等級的原創文本,連結來源,最多引用一個少於 15 個字的短語,並將 adapted 設為“基於來源的原創文本”。 填寫 source(名稱、網址、授權、日期、adapted)。A1–A2 → 始終是簡化的改編版。長文本 → 保留最好的 3–5 個段落,並用 […] 標記刪減處。

參考資料 — 僅在需要的步驟讀取每個檔案:

  • references/lesson-schema.md — lesson.json 架構 → 步驟 2
  • scripts/tts_edge.py — edge-tts 音訊 → 步驟 3
  • assets/lesson-template.html — 頁面模板(切勿編輯)→ 步驟 4
  • scripts/build.py — 填入模板 + 檢查 → 步驟 4

4. 工具

步驟工具用途
1conversation_search / recent_chats課程歷史(§3)
1AskUserQuestion當未提供主題時,建議 3 個主題
1WebSearch / WebFetch(或已安裝的 RSS MCP)文章課程:尋找最近開放授權的文本,檢查其授權
3ElevenLabs → edge-tts → 瀏覽器語音對話音訊(以下備用鏈)
3ffmpeg合併音訊片段(scripts/tts_edge.py)
4Python + build.py(scripts/build.py)填入模板,機械檢查
6Artifact 工具(publish_files / publish_version,然後 declare_capabilities)發布頁面並賦予其 sample 能力,以便其練習可以詢問 Claude;如果沒有該工具,則將 index.html 作為檔案發送
7AskUserQuestion在聊天中進行自適應練習,僅在頁面無法執行時;否則為純文字,一次一個項目
  • 音訊 — 按此順序嘗試,在第一次成功時停止:
    1. ElevenLabs(如果有來自 ElevenLabs 的文字轉語音工具可用):在目標語言中選擇一個女聲和一個男聲,每行一個片段,使用 scripts/tts_edge.py(合併步驟)合併。
    2. edge-tts(免費,無需金鑰):pip install edge-tts,然後 scripts/tts_edge.py(內部按語言映射語音)。在封鎖 Microsoft 伺服器的沙盒中會失敗——先測試一行(超時 20 秒)。
    3. 瀏覽器語音(始終可用):將 audio 留空;頁面將使用裝置上 lang 的語音讀取文字,每個說話者一種語音。發音按鈕始終使用瀏覽器語音。 設定 audio_note 以說明使用了哪一種。如果未生成音訊,切勿聲稱已生成。

5. 程序

  1. 規劃:確定目標語言、等級、主題和類型(§3)。對話 → 2 個情境(正式 / 非正式),每個情境有 2 個具名說話者(一女一男),姓名要符合語言的自然用法。文章 → 尋找並檢查來源(§3)。然後是 2–3 個家族的 6–10 個目標結構。
  2. 撰寫課程 JSON(lesson.json,架構在 references/lesson-schema.md),按此順序:
    • 對話 1(正式)和對話 2(非正式)——或文章:用 **…** 標記每個目標結構。兩者使用相同的結構,但語域不同。
    • 每行或每個段落都有學習者語言(l1)的自然翻譯,點擊可顯示。
    • 對於每個文本:1–2 個暖身問題、3 個大意問題(q1)、3–4 個細節問題(q2)、2–3 個找出問題(reading)、4–6 個附翻譯的表達式(notes)。
    • grammar:家族 → 結構、構成、學習者語言對等語、範例。
    • vocab(4–8 個主題詞彙及翻譯)、register(4–6 個正式 ↔ 非正式配對)、culture:一段 2–3 句關於與主題相關的實際用法的說明(A1–A2 使用學習者語言)。
    • pitfalls:3–4 個針對此語言配對的項目,每個都有解釋、學習者語言說明(l1)、錯誤 → 正確。
    • speaking:3 個重複使用這些結構的個人提示,每個都有 1–2 個範例答案(a)。
    • exercises:4 組,從易到難 — choice(5 題,辨識)→ fill(5 題,填空)→ dictation(4 個重複使用結構的短句;句子本身即答案)→ free(4–5 題,轉換/產出,附範例答案)。
  3. 音訊:按照 §4 的順序操作;如果生成,儲存 d1.mp3、d2.mp3。
  4. 構建與檢查:執行 python3 <skill>/scripts/build.py lesson.json <skill>/assets/lesson-template.html index.html [d1.mp3 d2.mp3]。修正所有失敗。
  5. 自我評估:使用 §2 進行評估,直到通過為止。
  6. 交付:將 index.html 發布為 artifact(標題 = 課程標題),然後使用 `{

相關技能