diff --git a/docs/blog/STYLE.md b/docs/blog/STYLE.md index f7aecf1..6cf5d5e 100644 --- a/docs/blog/STYLE.md +++ b/docs/blog/STYLE.md @@ -4,6 +4,10 @@ Formatting rules for every article under `docs/blog/`. They apply from the first draft on, not as an afterthought. (They extend the repository-wide no-em-dash rule from the coding standards to prose.) +This is the single place the blog formatting guidelines live (elsewhere +referred to as the "formatierungsrichtlinien-blog-engine-cc" rules). Read +it before drafting or reviewing an article. + ## 1. No em-dashes Never use `—` (U+2014), and never fake one with a spaced hyphen used as a @@ -24,21 +28,47 @@ formatting. German text and examples use real umlauts (ä, ö, ü, Ä, Ö, Ü, never ae/oe/ue/ss substitutions. ASCII-art diagrams in code fences use plain ASCII (`+`, `-`, `|`, `>`), not box-drawing characters. -## 3. Tables are real Markdown tables +## 3. No emojis unless the context explicitly requires them + +By default no emojis in body text or headings. (Artifact tab icons are +tooling metadata, not article text, and are exempt.) + +## 4. Rhetorical questions only when they carry the argument + +A question in the prose is allowed when it does real work: framing the +piece's central problem, bridging into the next section, or posing a test +the reader is meant to answer (for example the core-or-extension decision +questions in the schema-first article). It is not allowed as a +conversational filler that a plain statement would say better. "Don't +like the mix? Regenerate." is filler; "To change the mix, regenerate." +is the sentence. Question marks inside quoted examples or code +(`"Was ist Berlin?"`) are content, not prose, and are exempt. + +## 5. Tables are real Markdown tables Never flatten a table into running text with column gaps. Always a regular -Markdown table with `|` separators and a header row. +Markdown table with `|` separators and a header row. Conversely, a bullet +list whose items are prose explanations is a list, not a disguised table: +only convert to a table when the items are genuinely tabular (short, +parallel, two or more aligned columns). -## 4. No emojis unless the context explicitly requires them +## 6. Close with a summary where it helps -By default no emojis in body text or headings. (Artifact tab icons are -tooling metadata, not article text, and are exempt.) +An article that makes an argument or walks a process ends with a short +recap: the italic one-liner these pieces use ("Core owns the contract. +Consumers own the rules.") or a tight bulleted takeaway. It is a default, +not a mandate: a purely referential note needs none. ## Checking A quick audit before committing an article: ```shell -grep -c $'—' docs/blog/
.md # em-dashes, expect 0 +grep -c $'—' docs/blog/
.md # real em-dashes (U+2014), expect 0 +grep -nP '\S - \S' docs/blog/
.md # faked em-dashes (spaced hyphen as a pause), expect none in prose grep -oP '[^\x00-\x7F]' docs/blog/
.md | sort -u # review every non-ASCII char ``` + +The second grep matters: a spaced hyphen used as a pause is rule 1's other +half and a plain U+2014 count misses it entirely. Ignore hits inside code +fences (ASCII diagrams) and table rows. diff --git a/docs/blog/assets/create-lesson/e1-extensions-entry.png b/docs/blog/assets/create-lesson/e1-extensions-entry.png index 11a572f..9a39f06 100644 Binary files a/docs/blog/assets/create-lesson/e1-extensions-entry.png and b/docs/blog/assets/create-lesson/e1-extensions-entry.png differ diff --git a/docs/blog/assets/create-lesson/e2-type-picker.png b/docs/blog/assets/create-lesson/e2-type-picker.png index cf5c87b..2ca6629 100644 Binary files a/docs/blog/assets/create-lesson/e2-type-picker.png and b/docs/blog/assets/create-lesson/e2-type-picker.png differ diff --git a/docs/blog/assets/create-lesson/e3-dictation-fields.png b/docs/blog/assets/create-lesson/e3-dictation-fields.png index 3c2a87b..bfabd76 100644 Binary files a/docs/blog/assets/create-lesson/e3-dictation-fields.png and b/docs/blog/assets/create-lesson/e3-dictation-fields.png differ diff --git a/docs/blog/assets/create-lesson/s1-metadata.png b/docs/blog/assets/create-lesson/s1-metadata.png index e9ce580..840bff2 100644 Binary files a/docs/blog/assets/create-lesson/s1-metadata.png and b/docs/blog/assets/create-lesson/s1-metadata.png differ diff --git a/docs/blog/assets/create-lesson/s2-cards.png b/docs/blog/assets/create-lesson/s2-cards.png index 3b85a6e..395b972 100644 Binary files a/docs/blog/assets/create-lesson/s2-cards.png and b/docs/blog/assets/create-lesson/s2-cards.png differ diff --git a/docs/blog/assets/create-lesson/s3-exercises-config.png b/docs/blog/assets/create-lesson/s3-exercises-config.png index 62e12bf..c21fa10 100644 Binary files a/docs/blog/assets/create-lesson/s3-exercises-config.png and b/docs/blog/assets/create-lesson/s3-exercises-config.png differ diff --git a/docs/blog/assets/create-lesson/s3-exercises.png b/docs/blog/assets/create-lesson/s3-exercises.png index 8a8466e..7c5e383 100644 Binary files a/docs/blog/assets/create-lesson/s3-exercises.png and b/docs/blog/assets/create-lesson/s3-exercises.png differ diff --git a/docs/blog/assets/create-lesson/s4-review.png b/docs/blog/assets/create-lesson/s4-review.png index 41b14a9..5e4e930 100644 Binary files a/docs/blog/assets/create-lesson/s4-review.png and b/docs/blog/assets/create-lesson/s4-review.png differ diff --git a/docs/blog/assets/create-lesson/s5-template-book.png b/docs/blog/assets/create-lesson/s5-template-book.png index 68682fa..d6bfa40 100644 Binary files a/docs/blog/assets/create-lesson/s5-template-book.png and b/docs/blog/assets/create-lesson/s5-template-book.png differ diff --git a/docs/blog/assets/create-lesson/s6-book-text.png b/docs/blog/assets/create-lesson/s6-book-text.png index f2b0926..7ea2c7e 100644 Binary files a/docs/blog/assets/create-lesson/s6-book-text.png and b/docs/blog/assets/create-lesson/s6-book-text.png differ diff --git a/docs/blog/assets/create-lesson/s7-edit-review.png b/docs/blog/assets/create-lesson/s7-edit-review.png index c6daf7f..f0c93e7 100644 Binary files a/docs/blog/assets/create-lesson/s7-edit-review.png and b/docs/blog/assets/create-lesson/s7-edit-review.png differ diff --git a/docs/blog/create-a-lesson-in-the-app.md b/docs/blog/create-a-lesson-in-the-app.md index 58da514..17f83c9 100644 --- a/docs/blog/create-a-lesson-in-the-app.md +++ b/docs/blog/create-a-lesson-in-the-app.md @@ -1,6 +1,6 @@ --- title: "Create a Lesson in the App, Step by Step" -description: "A hands-on walkthrough of the adaptive-learner lesson creator: the four wizard steps, the book-text path that turns a pasted textbook chapter into a knowledge lesson, the extension path for the five advanced exercise types, and the edit mode - with real screenshots from the running app." +description: "A hands-on walkthrough of the adaptive-learner lesson creator: the four wizard steps, the book-text path that turns a pasted textbook chapter into a knowledge lesson, the extension path for the five advanced exercise types, and the edit mode, with real screenshots from the running app." date: 2026-07-17 tags: [tutorial, authoring, adaptive-learner, walkthrough] --- @@ -64,11 +64,11 @@ The type list now holds all six core exercise types: matching, free text, cloze, ![Step 3 after generating: ten exercises, plus a notice naming the one selected type that could not be built](assets/create-lesson/s3-exercises.png) -For our four cards the generator produced ten exercises, starting with a matching exercise over all four pairs. It also reports what it could *not* do: "Some selected types produced no exercises: picture_choice", because none of our cards carries an image. That notice is the point of the optional fields in step 2. Cloze and word tiles need example sentences, picture choice needs images, and the step names the missing precondition instead of quietly handing back a shorter list. +For our four cards the generator produced ten exercises, starting with a matching exercise over all four pairs. It also reports what it could *not* do, and does it as an instruction rather than a complaint: "Some selected types produced no exercises: Picture choice: add an image to at least two cards." That notice is the point of the optional fields in step 2. Cloze and word tiles need example sentences, picture choice needs images, and the step names both the missing precondition and its fix instead of quietly handing back a shorter list. Four more details matter here: -- **The generation is deterministic and local.** It derives exercises from your cards by rule, not by a language model, so it needs no API key and produces the same kind of result every time. Don't like the mix? **Regenerate**, adjust the type checkboxes, or delete individual exercises from the list. +- **The generation is deterministic and local.** It derives exercises from your cards by rule, not by a language model, so it needs no API key and produces the same kind of result every time. To change the mix, **Regenerate**, adjust the type checkboxes, or delete individual exercises from the list. - **The exercises are real schema exercises.** What the generator emits are the same `matching` and `free_text` structures a hand-written lesson JSON would contain. The wizard is writing the canonical format for you, one form at a time. - **Every exercise is editable in place.** Generated output is a starting point, not a verdict: open any entry and adjust the prompt, the accepted answers, the options. You are editing the exercise, not regenerating around it. - **You do not have to generate at all.** **Add exercise** creates one by hand, picking the type yourself. That closes the gap for the exercise the generator cannot derive from your cards, and it means the generator is a convenience rather than the only way in. @@ -80,7 +80,6 @@ The last step shows the lesson summary and, more importantly, a checklist: ![Step 4: the review screen with the quality checklist, all green](assets/create-lesson/s4-review.png) - Has a title -- Language pair is valid - At least 4 cards - At least 5 exercises - At least 2 exercise types @@ -99,15 +98,15 @@ The four steps above assume vocabulary cards. Since then the wizard has grown a ![Step 1 with the template row, including the new "Knowledge lesson from text" card](assets/create-lesson/s5-template-book.png) -Choosing it switches the wizard to a shorter three-step flow: metadata, book text, review. The middle step is where the work happens - you paste **one section of a textbook** (a chapter is the right size), optionally add the book reference, and press **Generate theory + exercises**: +Choosing it switches the wizard to a shorter three-step flow: metadata, book text, review. The middle step is where the work happens: you paste **one section of a textbook** (a chapter is the right size), optionally add the book reference, and press **Generate theory + exercises**: ![The book-text step: pasted chapter, the rights hint, book reference fields, and the generate button](assets/create-lesson/s6-book-text.png) What happens on generate is deliberately NOT a copy-paste job: -- **The AI rewrites the text in its own words.** The rephrase prompt carries an explicit guardrail - reformulate, never reproduce the wording verbatim - both for copyright reasons and because a rephrasing that has to survive in its own words is a better theory text than a quote. It is a design guardrail, not a user option, and a unit test pins that the prompt carries it. The UI reminds you of your side of the deal too: paste only text you have the rights to, or that is intended for personal use. +- **The AI rewrites the text in its own words.** The rephrase prompt carries an explicit guardrail (reformulate, never reproduce the wording verbatim), both for copyright reasons and because a rephrasing that has to survive in its own words is a better theory text than a quote. It is a design guardrail, not a user option, and a unit test pins that the prompt carries it. The UI reminds you of your side of the deal too: paste only text you have the rights to, or that is intended for personal use. - **The exercises point back at the theory.** Each generated exercise is linked to its theory step via the schema's `theory_ref` field, using the same resolver the app uses at play time, so the write side and the read side cannot diverge. -- **The book reference travels with the set.** Title, author, URL and ISBN/ASIN land in the set's `book` block - the same field the official content sets use for their companion books. +- **The book reference travels with the set.** Title, author, URL and ISBN/ASIN land in the set's `book` block, the same field the official content sets use for their companion books. This path calls a language model, so it is the one part of the creator that needs an API key (bring your own; Anthropic, OpenAI or Gemini). Without a key configured, the step tells you so in plain words instead of failing. @@ -135,24 +134,24 @@ The picker shows the technical type ids, which is honest about what you are auth Dictation is the newest of the five, and its editor shows what a self-contained extension payload looks like: -![The dictation editor: instruction, audio file path with its hint, and two accepted transcriptions](assets/create-lesson/e3-dictation-fields.png) +![The dictation editor: instruction, the audio field with upload and path, and two accepted transcriptions](assets/create-lesson/e3-dictation-fields.png) -Three fields, no more: the instruction the learner sees, the **audio file path**, and the list of **accepted transcriptions**. The accepted list is why dictation is forgiving in the right way: you decide up front that *"a coffee please"* counts as well as *"A coffee, please."*, so the grader does not have to guess how strict to be about capitals and punctuation. +Three fields, no more: the instruction the learner sees, the **audio**, and the list of **accepted transcriptions**. The accepted list is why dictation is forgiving in the right way: you decide up front that *"a coffee please"* counts as well as *"A coffee, please."*, so the grader does not have to guess how strict to be about capitals and punctuation. -Note what the audio field is: a path, typed. The wizard does not upload the clip for you in this version; you put the file into the set's `assets` folder and name it here. That is a real limit, and it is the honest one to state rather than implying an upload button that is not there. +The audio field takes the clip two ways. **Upload audio** stores it self-contained with the lesson, inlined as a data URI, which is the quick path for a lesson you keep locally. Or you type a relative path to a file in the set's `assets` folder, which is what a published repo set wants, because an inlined clip travels inside the lesson JSON and grows it. Saving works exactly as everywhere else in the creator. The lesson that comes out is a normal lesson in the canonical schema, with one addition: it declares the extension it uses, so the portability contract holds. ## The wizard is now also the editor -The second door: every lesson you created (or imported) can be reopened. In the Content area, own lessons carry an **Edit** action - lessons from foreign repositories stay read-only - and it opens the same wizard, pre-filled with the lesson's title, languages, cards and exercises. Walk the steps, change what you want, and the review screen offers a choice the create flow does not have: +The second door: every lesson you created (or imported) can be reopened. In the Content area, own lessons carry an **Edit** action (lessons from foreign repositories stay read-only), and it opens the same wizard, pre-filled with the lesson's title, languages, cards and exercises. Walk the steps, change what you want, and the review screen offers a choice the create flow does not have: ![The review step in edit mode: the overwrite note, Save changes, and Save as a copy](assets/create-lesson/s7-edit-review.png) - **Save changes** overwrites the lesson in place, keeping the same set id and lesson filename. That detail matters: spaced-repetition progress is keyed on the filename and the card content, so unchanged cards keep their learning history, edited or removed cards fall away cleanly, and new cards start fresh. Editing a typo does not reset your streak. - **Save as a copy** leaves the original untouched and writes a new lesson next to it. -Alongside editing, the same area lets you **combine several of your own lessons into one set** - select them, group them into a new set (or append to an existing one), and the result is a normal own set that exports and shares like any other. Both features route through the same save path as everything else in this article, so nothing about the output format changes. +Alongside editing, the same area lets you **combine several of your own lessons into one set**: select them, group them into a new set (or append to an existing one), and the result is a normal own set that exports and shares like any other. Both features route through the same save path as everything else in this article, so nothing about the output format changes. ## What you just made @@ -163,8 +162,8 @@ The output of these steps is not a proprietary in-app object. It is a lesson in The creator is deliberately the *simple* path, and it has edges: - Extension exercises are authorable now, but one at a time and by hand. There is no generator for them: the wizard gives you a form per type, not a rule that derives a graded quiz from your cards. That is a deliberate order of work (make it authorable first, automate later), not an oversight. -- Dictation takes an audio path, not an upload. You place the clip in the set's `assets` folder yourself and type the path. Recording or uploading from the browser is not built in this version. -- The card-path generator is rule-based on purpose. It produces solid drill exercises from your cards and needs no API key; it does not invent prose. Theory-rich lessons are now the book-text path's job - that one does write theory, and in exchange it is the only part that needs a model key. +- Dictation takes an existing audio file, either uploaded (inlined with the lesson) or referenced by asset path. Recording a clip in the browser is not built. +- The card-path generator is rule-based on purpose. It produces solid drill exercises from your cards and needs no API key; it does not invent prose. Theory-rich lessons are now the book-text path's job: that one does write theory, and in exchange it is the only part that needs a model key. - The book-text path takes pasted text only. PDF or Word upload and automatic chapter detection are not built; splitting a book into chapters is still your call. For the everyday case (a teacher or learner who wants a small, clean vocabulary lesson that plays immediately and can be shared properly) the four steps above are the whole job. For turning a textbook chapter into a playable knowledge lesson, the book-text path is; and when either result needs a second pass, the wizard doubles as the editor. diff --git a/docs/blog/de/assets/create-lesson/e1-extensions-entry.png b/docs/blog/de/assets/create-lesson/e1-extensions-entry.png new file mode 100644 index 0000000..c224a13 Binary files /dev/null and b/docs/blog/de/assets/create-lesson/e1-extensions-entry.png differ diff --git a/docs/blog/de/assets/create-lesson/e2-type-picker.png b/docs/blog/de/assets/create-lesson/e2-type-picker.png new file mode 100644 index 0000000..a7a74c2 Binary files /dev/null and b/docs/blog/de/assets/create-lesson/e2-type-picker.png differ diff --git a/docs/blog/de/assets/create-lesson/e3-dictation-fields.png b/docs/blog/de/assets/create-lesson/e3-dictation-fields.png new file mode 100644 index 0000000..e0b049d Binary files /dev/null and b/docs/blog/de/assets/create-lesson/e3-dictation-fields.png differ diff --git a/docs/blog/de/assets/create-lesson/s1-metadata.png b/docs/blog/de/assets/create-lesson/s1-metadata.png new file mode 100644 index 0000000..fd47539 Binary files /dev/null and b/docs/blog/de/assets/create-lesson/s1-metadata.png differ diff --git a/docs/blog/de/assets/create-lesson/s2-cards.png b/docs/blog/de/assets/create-lesson/s2-cards.png new file mode 100644 index 0000000..ef7b7b2 Binary files /dev/null and b/docs/blog/de/assets/create-lesson/s2-cards.png differ diff --git a/docs/blog/de/assets/create-lesson/s3-exercises-config.png b/docs/blog/de/assets/create-lesson/s3-exercises-config.png new file mode 100644 index 0000000..d672a99 Binary files /dev/null and b/docs/blog/de/assets/create-lesson/s3-exercises-config.png differ diff --git a/docs/blog/de/assets/create-lesson/s3-exercises.png b/docs/blog/de/assets/create-lesson/s3-exercises.png new file mode 100644 index 0000000..3d4647f Binary files /dev/null and b/docs/blog/de/assets/create-lesson/s3-exercises.png differ diff --git a/docs/blog/de/assets/create-lesson/s4-review.png b/docs/blog/de/assets/create-lesson/s4-review.png new file mode 100644 index 0000000..4f1dd98 Binary files /dev/null and b/docs/blog/de/assets/create-lesson/s4-review.png differ diff --git a/docs/blog/de/assets/create-lesson/s5-template-book.png b/docs/blog/de/assets/create-lesson/s5-template-book.png new file mode 100644 index 0000000..357bc52 Binary files /dev/null and b/docs/blog/de/assets/create-lesson/s5-template-book.png differ diff --git a/docs/blog/de/assets/create-lesson/s6-book-text.png b/docs/blog/de/assets/create-lesson/s6-book-text.png new file mode 100644 index 0000000..e3e6586 Binary files /dev/null and b/docs/blog/de/assets/create-lesson/s6-book-text.png differ diff --git a/docs/blog/de/assets/create-lesson/s7-edit-review.png b/docs/blog/de/assets/create-lesson/s7-edit-review.png new file mode 100644 index 0000000..75e384b Binary files /dev/null and b/docs/blog/de/assets/create-lesson/s7-edit-review.png differ diff --git a/docs/blog/de/create-a-lesson-in-the-app.md b/docs/blog/de/create-a-lesson-in-the-app.md new file mode 100644 index 0000000..016fff9 --- /dev/null +++ b/docs/blog/de/create-a-lesson-in-the-app.md @@ -0,0 +1,173 @@ +--- +title: "Eine Lektion in der App erstellen, Schritt für Schritt" +description: "Eine praktische Tour durch den Lektions-Editor von adaptive-learner: die vier Assistenten-Schritte, der Buch-Text-Pfad, der aus einem eingefügten Lehrbuchkapitel eine Wissens-Lektion macht, der Erweiterungs-Pfad für die fünf fortgeschrittenen Übungstypen und der Bearbeitungsmodus, mit echten Screenshots aus der laufenden App." +date: 2026-07-17 +tags: [tutorial, authoring, adaptive-learner, walkthrough] +--- + +# Eine Lektion in der App erstellen, Schritt für Schritt + +*Eine praktische Tour durch den Lektions-Editor in adaptive-learner: die klassischen vier Assistenten-Schritte vom leeren Formular bis zur gespeicherten, schema-gültigen Lektion, der Buch-Text-Pfad, der aus einem eingefügten Lehrbuchkapitel eine Wissens-Lektion macht, der Erweiterungs-Pfad, der die fünf fortgeschrittenen Übungstypen ohne JSON autorierbar macht, und der Bearbeitungsmodus des Assistenten. Jeder Screenshot in dieser Anleitung stammt aus der laufenden App, aufgenommen während des exakt beschriebenen Ablaufs.* + +`adaptive-learner` · für Lehrende und Content-Autoren · Teil 3 der Serie + +Der [vorige Artikel](../one-source-many-outputs.md) machte ein Versprechen: Sie müssen Lektions-JSON nicht von Hand schreiben. Dieser Artikel löst es ein. Wir bauen eine kleine echte Lektion ("Ordering coffee", Englisch für Deutschsprachige) im Lektions-Editor der App und enden mit einer Lektion, die dieselben Qualitätsprüfungen besteht wie jede andere Lektion im Ökosystem. Kein Editor, kein Terminal, kein JSON. + +## Wo der Editor lebt + +Der Editor ist eine Seite in der App: Öffnen Sie `/create-lesson` (oder folgen Sie der Erstellen-Aktion im Inhalte-Bereich). Auf dem klassischen Pfad ist es ein vierstufiger Assistent, und die Schritte spiegeln genau wider, was eine Lektion im kanonischen Schema *ist*: Metadaten, Karten, Übungen und eine abschließende Überprüfung. Sie können in jedem Schritt zurückgehen; nichts wird gespeichert, bevor Sie es sagen. Drei weitere Türen führen in denselben Assistenten, und wir gehen jede nach dem klassischen Pfad durch: einen **Buch-Text-Pfad**, der aus einem eingefügten Lehrbuchkapitel eine Wissens-Lektion baut, einen **Erweiterungs-Pfad** für die fortgeschrittenen Übungstypen und einen **Bearbeitungsmodus**, der jede eigene Lektion wieder öffnet. + +## Schritt 1: Lektionsdetails + +Der erste Schritt sammelt die Metadaten, die jede Lektion trägt: einen Titel, einen optionalen Titel in der Zielsprache, das Sprachpaar, ein Niveau sowie ein optionales Thema und einen Autorennamen. + +![Schritt 1: das Lektionsdetails-Formular mit Titel, Sprachen, Niveau, Thema und Autor](assets/create-lesson/s1-metadata.png) + +Für unser Beispiel: + +| Feld | Wert | +|---|---| +| Titel | Ordering coffee | +| Titel in der Zielsprache | Kaffee bestellen | +| Gelernte Sprache | Englisch | +| Deine Sprache | Deutsch | +| Niveau | A1 | + +Zwei Dinge sind hier bemerkenswert. Erstens ist das Sprachpaar dasselbe `target_language` / `source_language`-Paar, das auch das Schema festhält; der Assistent gibt ihm nur freundlichere Namen ("Gelernte Sprache" und "Deine Sprache"). Zweitens beginnen in der Vorlagen-Reihe auch die alternativen Pfade des Assistenten: neben den vier Start-Vorlagen (leer, Vokabeln, Grammatik, Konversation) stehen "Wissens-Lektion aus Text" und "Erweiterte Übungstypen", beide weiter unten behandelt. Die angewandte Vorlage zeigt einen gedrückten Zustand, sodass Sie sehen, welche aktiv ist. Für diese Tour füllen wir einfach die Felder aus und drücken **Weiter**. + +## Schritt 2: Vokabelkarten hinzufügen + +Karten sind das Rohmaterial einer Lektion: die Wörter und Wendungen, die die Übungen einüben. Jede Karte hat eine Vorderseite (in der gelernten Sprache) und eine Rückseite (in Ihrer Sprache), dazu optionale Notizen, einen Beispielsatz, alternative akzeptierte Antworten und ein Bild. + +![Schritt 2: der Karten-Editor mit dem Beispielsatz-Feld, alternativen Antworten und vier hinzugefügten Karten in der Liste](assets/create-lesson/s2-cards.png) + +Wir fügen vier hinzu: + +| Vorderseite (gelernt) | Rückseite (deine Sprache) | +|---|---| +| coffee | der Kaffee | +| please | bitte | +| the bill | die Rechnung | +| milk | die Milch | + +Vorderseite und Rückseite eintippen, **Karte hinzufügen** drücken, wiederholen. Die Liste unter dem Formular wächst mit, und jeder Eintrag lässt sich bearbeiten, löschen oder umsortieren. Wenn Sie Vokabeln bereits in einer Tabelle haben, übernimmt **CSV importieren** sie in einem Schritt statt in vier. + +Ein Feld verdient einen genaueren Blick, weil es still entscheidet, was der nächste Schritt für Sie bauen kann: der **Beispielsatz**. Sein Hinweis sagt es direkt: Er ermöglicht Lückentext- und Wort-Kachel-Übungen, und beim Lückentext muss der Satz den Vorderseiten-Begriff enthalten, damit dieser ausgeblendet werden kann. Das macht aus einem früheren Ratespiel etwas, das im Moment des Autorierens sichtbar ist. Dasselbe gilt für das **Bild**, das die Bildauswahl braucht. Lassen Sie beide weg, hat der Generator schlicht weniger Material; Schritt 3 sagt es Ihnen, statt stillschweigend weniger Übungen zu erzeugen. + +## Schritt 3: Übungen erstellen + +Das ist der Schritt, der von Hand mühsam wäre, und der Assistent erledigt ihn für Sie. Wählen Sie, wie viele Übungen Sie möchten, welche Typen erlaubt sind und eine Richtungspräferenz. Dann drücken Sie **Übungen automatisch erstellen**. + +![Schritt 3: der Übungs-Generator mit den sechs Kern-Typ-Kontrollkästchen und der Schaltfläche Übung hinzufügen](assets/create-lesson/s3-exercises-config.png) + +Die Typenliste hält jetzt alle sechs Kern-Übungstypen: Zuordnung, Freitext, Lückentext, Wort-Kacheln, Bildauswahl und Multiple Choice. Multiple Choice ist erwähnenswert, weil es ein *Kern*-Typ ist, keine Erweiterung: Es ging in den eigentlichen Übungstyp-Enum des Schemas ein, sodass jeder Konsument des Formats es versteht, ohne sich für irgendetwas zu entscheiden. + +![Schritt 3 nach dem Erstellen: zehn Übungen, dazu ein Hinweis, der den einen gewählten Typ nennt, der nicht gebaut werden konnte](assets/create-lesson/s3-exercises.png) + +Für unsere vier Karten erzeugte der Generator zehn Übungen, beginnend mit einer Zuordnungsübung über alle vier Paare. Er meldet auch, was er *nicht* tun konnte, und zwar als Handlungsanweisung statt als Beschwerde: "Einige ausgewählte Typen haben keine Übungen ergeben: Bildauswahl: Füge mindestens zwei Karten ein Bild hinzu." Dieser Hinweis ist der Sinn der optionalen Felder aus Schritt 2. Lückentext und Wort-Kacheln brauchen Beispielsätze, Bildauswahl braucht Bilder, und der Schritt benennt sowohl die fehlende Voraussetzung als auch ihre Behebung, statt stillschweigend eine kürzere Liste zurückzugeben. + +Vier weitere Details sind hier wichtig: + +- **Die Erstellung ist deterministisch und lokal.** Sie leitet Übungen regelbasiert aus Ihren Karten ab, nicht über ein Sprachmodell, braucht also keinen API-Schlüssel und liefert jedes Mal dasselbe Ergebnis. Um die Mischung zu ändern, drücken Sie **Neu generieren**, passen die Typ-Kontrollkästchen an oder löschen einzelne Übungen aus der Liste. +- **Die Übungen sind echte Schema-Übungen.** Was der Generator ausgibt, sind dieselben `matching`- und `free_text`-Strukturen, die auch ein von Hand geschriebenes Lektions-JSON enthielte. Der Assistent schreibt das kanonische Format für Sie, ein Formular nach dem anderen. +- **Jede Übung ist direkt bearbeitbar.** Die erzeugte Ausgabe ist ein Ausgangspunkt, kein Urteil: Öffnen Sie einen Eintrag und passen Sie die Aufgabenstellung, die akzeptierten Antworten, die Optionen an. Sie bearbeiten die Übung, statt drumherum neu zu generieren. +- **Sie müssen gar nicht generieren.** **Übung hinzufügen** erstellt eine von Hand, wobei Sie den Typ selbst wählen. Das schließt die Lücke für die Übung, die der Generator nicht aus Ihren Karten ableiten kann, und macht den Generator zu einer Bequemlichkeit statt zum einzigen Weg hinein. + +## Schritt 4: Überprüfen und speichern + +Der letzte Schritt zeigt die Lektionsübersicht und, wichtiger, eine Checkliste: + +![Schritt 4: der Überprüfungs-Bildschirm mit der Qualitäts-Checkliste, alles grün](assets/create-lesson/s4-review.png) + +- Hat einen Titel +- Mindestens 4 Karten +- Mindestens 5 Übungen +- Mindestens 2 Übungstypen +- Gültige Lektionsstruktur + +Falls diese Liste bekannt aussieht, sollte sie das: Es sind dieselben Qualitäts-Mindestwerte, die die Content-Repositories in der CI durchsetzen (der Qualitäts-Boden aus dem vorigen Artikel). Der Assistent führt sie *vor* dem Speichern aus, sodass eine Lektion, die diesen Bildschirm grün verlässt, bereits die Art Lektion ist, die der Rest der Pipeline akzeptiert. Ein roter Punkt blockiert nichts stillschweigend; er sagt Ihnen genau, was fehlt. + +Dann zwei Wege hinaus: + +- **Lokal speichern** legt die Lektion in der App selbst ab. Sie erscheint neben Ihren anderen Inhalten und kann sofort gespielt werden, wobei die verteilte Wiederholung sie wie jede andere Lektion verfolgt. +- **Speichern und teilen** geht weiter: Es führt Sie durch das Beitragen der Lektion zu einem Content-Repository auf GitHub. Mit konfiguriertem Token forkt die App das Repository, erstellt einen Branch, committet die Lektion und öffnet den Pull Request für Sie; ohne Token bereitet sie eine vorausgefüllte URL vor, die Sie von Hand vervollständigen. So oder so ist das Ziel dasselbe überprüfbare, versionierte Zuhause, in dem der übrige Content lebt. + +## Der Buch-Text-Pfad: eine Wissens-Lektion aus einem Kapitel + +Die vier Schritte oben setzen Vokabelkarten voraus. Seitdem hat der Assistent einen zweiten Weg hinein bekommen, gebaut für **Wissens-Lektionen**: Material, das in derselben Sprache geschrieben ist, die es lehrt, wie die Psychologie- und Technologie-Sets im Content-Ökosystem. Der Einstieg ist die letzte Start-Vorlage in Schritt 1: + +![Schritt 1 mit der Vorlagen-Reihe, einschließlich der neuen Karte "Wissens-Lektion aus Text"](assets/create-lesson/s5-template-book.png) + +Sie zu wählen schaltet den Assistenten auf einen kürzeren dreistufigen Ablauf um: Metadaten, Buchtext, Überprüfung. Der mittlere Schritt ist, wo die Arbeit passiert: Sie fügen **einen Abschnitt eines Lehrbuchs** ein (ein Kapitel ist die richtige Größe), fügen optional die Buchangabe hinzu und drücken **Theorie + Übungen generieren**: + +![Der Buch-Text-Schritt: eingefügtes Kapitel, der Rechte-Hinweis, die Buchangabe-Felder und die Generieren-Schaltfläche](assets/create-lesson/s6-book-text.png) + +Was beim Generieren passiert, ist bewusst KEINE Kopieraktion: + +- **Die KI schreibt den Text in eigenen Worten um.** Die Umformulierungs-Anweisung trägt eine ausdrückliche Leitplanke (umformulieren, den Wortlaut nie wörtlich wiedergeben), sowohl aus Urheberrechtsgründen als auch, weil eine Umformulierung, die in eigenen Worten bestehen muss, ein besserer Theorietext ist als ein Zitat. Es ist eine Design-Leitplanke, keine Nutzeroption, und ein Unit-Test hält fest, dass die Anweisung sie trägt. Die Oberfläche erinnert Sie auch an Ihren Teil der Abmachung: Fügen Sie nur Text ein, an dem Sie die Rechte haben oder der für den persönlichen Gebrauch bestimmt ist. +- **Die Übungen verweisen zurück auf die Theorie.** Jede erzeugte Übung ist über das Schema-Feld `theory_ref` mit ihrem Theorie-Schritt verknüpft, mit demselben Resolver, den die App zur Spielzeit nutzt, sodass Schreibseite und Leseseite nicht auseinanderlaufen können. +- **Die Buchangabe reist mit dem Set.** Titel, Autor, URL und ISBN/ASIN landen im `book`-Block des Sets, demselben Feld, das die offiziellen Content-Sets für ihre Begleitbücher nutzen. + +Dieser Pfad ruft ein Sprachmodell auf, ist also der eine Teil des Editors, der einen API-Schlüssel braucht (bringen Sie Ihren eigenen mit; Anthropic, OpenAI oder Gemini). Ohne konfigurierten Schlüssel sagt der Schritt es Ihnen in klaren Worten, statt zu scheitern. + +Ein Durchlauf des Assistenten erzeugt eine Lektion in einem Set. Für ein Buch mit vielen Kapiteln durchlaufen Sie den Assistenten einmal pro Kapitel; jedes Set trägt denselben Buch-Block, sodass die Lektionen sichtbar verwandt bleiben. + +## Der Erweiterungs-Pfad: fortgeschrittene Übungstypen + +Die sechs Kern-Typen decken das alltägliche Einüben ab. Manche Übungsformen passen in keinen davon, und die leben in der Erweiterungs-Schicht: einer getrennten, freiwilligen Ebene, die Übungstypen hinzufügt, ohne das Kern-Schema zu verbreitern (der zweite Artikel erklärt, warum diese Grenze existiert). Bis vor Kurzem waren sie nur als JSON verfügbar. Das sind sie nicht mehr. Der dritte Eintrag in der Vorlagen-Reihe öffnet ihren eigenen Assistenten-Zweig: + +![Schritt 1 mit der Vorlagen-Reihe: die vier Start-Vorlagen plus die Einträge Buch-Text und Erweiterte Übungstypen](assets/create-lesson/e1-extensions-entry.png) + +Ihn zu wählen schaltet auf einen kürzeren dreistufigen Ablauf um: Metadaten, Übungen, Überprüfung. Kein Karten-Schritt, weil Erweiterungsübungen ihren eigenen Inhalt tragen, statt auf Karten zurückzugreifen. **Erweiterungsübung hinzufügen** öffnet die Typ-Auswahl, und alle fünf adoptierten Typen sind da: + +![Die Erweiterungstyp-Auswahl mit allen fünf adoptierten Typen](assets/create-lesson/e2-type-picker.png) + +Die Auswahl zeigt die Typen unter ihren deutschen Namen. Darunter liegt jeweils ein namensraum-gebundener `ext:`-Typ, den die Lektion in `requires_extensions` deklariert, sodass ein Konsument ohne diese Erweiterung die Lektion laut ablehnt, statt sie falsch darzustellen. Wofür jeder da ist, mit seiner technischen Id und einem kleinen Beispiel aus einem Französisch-Kurs für Deutschsprachige: + +| Typ in der App | Technische Id | Was die lernende Person tut | Beispiel | +|---|---|---|---| +| Kategorisierung | `ext:al-categorization` | Sortiert Elemente in benannte Behälter | *pomme, carotte, banane, poireau* nach **Obst** und **Gemüse** einordnen | +| Fehlerkorrektur | `ext:al-error-correction` | Findet und behebt einen eingebauten Fehler | *"Elle a mangé des pomme."* Der Fehler: *pomme* muss *pommes* heißen | +| Leseverständnis | `ext:al-reading-comprehension` | Liest einen Text, beantwortet mehrere Fragen dazu | *"Marie habite à Paris. Elle travaille dans un café le matin et étudie le français le soir."* Frage: Wo arbeitet Marie? | +| Benotetes Quiz | `ext:al-graded-quiz` | Bearbeitet ein bewertetes Fragenset mit Bestehensgrenze | Drei Fragen zu Begrüßungen, je ein Punkt, bestanden bei 2 von 3 | +| Diktat | `ext:al-dictation` | Hört einen Clip und tippt, was gesagt wurde | *"Comment ça va?"* hören, mit oder ohne Akzent akzeptiert | + +Diktat ist der jüngste der fünf, und sein Editor zeigt, wie ein in sich geschlossenes Erweiterungs-Payload aussieht: + +![Der Diktat-Editor: Anweisung, das Audio-Feld mit Hochladen und Pfad, und zwei akzeptierte Transkriptionen](assets/create-lesson/e3-dictation-fields.png) + +Drei Felder, nicht mehr: die Anweisung, die die lernende Person sieht, das **Audio** und die Liste der **akzeptierten Transkriptionen**. Die Akzeptanzliste ist der Grund, warum Diktat auf die richtige Weise nachsichtig ist: Sie legen im Voraus fest, dass *"a coffee please"* genauso zählt wie *"A coffee, please."*, sodass der Bewerter nicht raten muss, wie streng er mit Groß-/Kleinschreibung und Zeichensetzung sein soll. + +Das Audio-Feld nimmt den Clip auf zwei Wegen. **Audio hochladen** legt ihn selbstständig bei der Lektion ab, eingebettet als Data-URI, was der schnelle Weg für eine lokal gehaltene Lektion ist. Oder Sie tippen einen relativen Pfad zu einer Datei im `assets`-Ordner des Sets, was ein veröffentlichtes Repo-Set möchte, weil ein eingebetteter Clip im Lektions-JSON mitreist und es aufbläht. + +Das Speichern funktioniert genau wie überall sonst im Editor. Die Lektion, die herauskommt, ist eine normale Lektion im kanonischen Schema, mit einer Ergänzung: Sie deklariert die Erweiterung, die sie nutzt, sodass der Portabilitäts-Vertrag hält. + +## Der Assistent ist jetzt auch der Editor + +Die zweite Tür: Jede Lektion, die Sie erstellt (oder importiert) haben, lässt sich wieder öffnen. Im Inhalte-Bereich tragen eigene Lektionen eine **Bearbeiten**-Aktion (Lektionen aus fremden Repositories bleiben schreibgeschützt), und sie öffnet denselben Assistenten, vorausgefüllt mit Titel, Sprachen, Karten und Übungen der Lektion. Gehen Sie die Schritte durch, ändern Sie, was Sie möchten, und der Überprüfungs-Bildschirm bietet eine Wahl, die der Erstellen-Ablauf nicht hat: + +![Der Überprüfungs-Schritt im Bearbeitungsmodus: der Überschreiben-Hinweis, Änderungen speichern und Als Kopie speichern](assets/create-lesson/s7-edit-review.png) + +- **Änderungen speichern** überschreibt die Lektion an Ort und Stelle und behält dieselbe Set-Id und denselben Lektions-Dateinamen. Dieses Detail zählt: Der Fortschritt der verteilten Wiederholung ist an den Dateinamen und den Karteninhalt gebunden, sodass unveränderte Karten ihre Lernhistorie behalten, bearbeitete oder entfernte Karten sauber wegfallen und neue Karten frisch beginnen. Einen Tippfehler zu korrigieren setzt Ihre Serie nicht zurück. +- **Als Kopie speichern** lässt das Original unberührt und schreibt eine neue Lektion daneben. + +Neben dem Bearbeiten können Sie im selben Bereich **mehrere Ihrer eigenen Lektionen zu einem Set zusammenfassen**: auswählen, zu einem neuen Set gruppieren (oder an ein bestehendes anhängen), und das Ergebnis ist ein normales eigenes Set, das wie jedes andere exportiert und geteilt wird. Beide Funktionen laufen über denselben Speicher-Pfad wie alles andere in diesem Artikel, sodass sich am Ausgabeformat nichts ändert. + +## Was Sie gerade gebaut haben + +Die Ausgabe dieser Schritte ist kein proprietäres App-internes Objekt. Es ist eine Lektion im selben kanonischen Schema, um das es in dieser ganzen Serie geht: Karten, Schritte, Übungen, Metadaten, alle validiert. Das heißt, alles aus dem vorigen Artikel gilt für sie. Sie wird als interaktive Übung mit verteilter Wiederholung dargestellt. Sie kann per Pull Request zu einem Content-Repository reisen, wo derselbe Validator sie in der CI absichert. Eine Quelle, und Sie haben nie einen Texteditor geöffnet. + +## Ehrliche Grenzen + +Der Editor ist bewusst der *einfache* Pfad, und er hat Kanten: + +- Erweiterungsübungen sind jetzt autorierbar, aber einzeln und von Hand. Es gibt keinen Generator für sie: Der Assistent gibt Ihnen ein Formular pro Typ, keine Regel, die ein benotetes Quiz aus Ihren Karten ableitet. Das ist eine bewusste Reihenfolge der Arbeit (erst autorierbar machen, später automatisieren), kein Versäumnis. +- Diktat nimmt eine vorhandene Audiodatei, entweder hochgeladen (mit der Lektion eingebettet) oder über einen Asset-Pfad referenziert. Einen Clip im Browser aufzunehmen ist nicht gebaut. +- Der Karten-Pfad-Generator ist bewusst regelbasiert. Er erzeugt solide Einübungs-Übungen aus Ihren Karten und braucht keinen API-Schlüssel; er erfindet keine Prosa. Theorie-reiche Lektionen sind jetzt die Aufgabe des Buch-Text-Pfads: Dieser schreibt tatsächlich Theorie und ist im Gegenzug der einzige Teil, der einen Modell-Schlüssel braucht. +- Der Buch-Text-Pfad nimmt nur eingefügten Text. PDF- oder Word-Upload und automatische Kapitelerkennung sind nicht gebaut; ein Buch in Kapitel zu teilen bleibt Ihre Aufgabe. + +Für den Alltagsfall (eine Lehrkraft oder lernende Person, die eine kleine, saubere Vokabel-Lektion will, die sofort spielbar und ordentlich teilbar ist) sind die vier Schritte oben die ganze Arbeit. Um ein Lehrbuchkapitel in eine spielbare Wissens-Lektion zu verwandeln, ist es der Buch-Text-Pfad; und wenn eines der Ergebnisse einen zweiten Durchgang braucht, dient der Assistent zugleich als Editor. + +--- + +*Vier Schritte, kein JSON: Metadaten, Karten, generierte Übungen und eine Überprüfung, die denselben Qualitäts-Boden wie die CI ausführt. Und drei Türen mehr: ein Lehrbuchkapitel hinein, eine Wissens-Lektion hinaus; die fünf fortgeschrittenen Übungstypen autorierbar in ihrem eigenen Zweig, Diktat inklusive; und jede eigene Lektion bearbeitbar, ohne ihren Fortschritt zu verlieren.* diff --git a/docs/blog/schema-first-content-engineering.md b/docs/blog/schema-first-content-engineering.md index 133a575..0ce7fec 100644 --- a/docs/blog/schema-first-content-engineering.md +++ b/docs/blog/schema-first-content-engineering.md @@ -40,7 +40,7 @@ Trace what a single core type touches: - **Schema.** `lesson.schema.json` gains an enum value and a payload definition (an additive minor bump, 1.7 to 1.8). - **Types.** `generate-lesson-types.mjs` regenerates the interfaces; every consumer picks up the new shape. -- **Mirrors.** Ten content repositories mirror the schema - the official repo, the test/starter repo, the template, and seven `alc-*` domain repos (plus the app's own generated copy) - and byte-parity gates keep them honest. +- **Mirrors.** Ten content repositories mirror the schema (the official repo, the test/starter repo, the template, and seven `alc-*` domain repos, plus the app's own generated copy), and byte-parity gates keep them honest. - **Dispatcher & renderer.** The app's exercise dispatcher needs a new branch and a new renderer component. - **i18n.** Eleven language catalogs need instruction keys, feedback, and error strings. - **Validation.** `validate.ts` needs rules for the new shape: well-formedness, cross-field integrity.