diff --git a/backend/database.py b/backend/database.py index 459c5eb..9f5d99f 100644 --- a/backend/database.py +++ b/backend/database.py @@ -238,16 +238,6 @@ async def init_db(): "UPDATE guides SET status = 'error', progress = NULL, error_msg = 'Server-Neustart' " "WHERE status IN ('queued', 'generating')" ) - # Milestone-Migration auf Score-Skala 0–30: absolviert≥6, verstanden≥12, gemeistert≥18. - # Leitet die Meilensteine aus dem aktuellen Score ab (bestehende Timestamps bleiben), - # idempotent — nach einem Lauf stabil, im Normalbetrieb deckungsgleich mit der Prüf-Route. - await db.execute("UPDATE baustein_progress SET gute_antworten = 30 WHERE gute_antworten > 30") # Alt-Scores deckeln - for _spalte, _schwelle in (("absolviert", 6), ("verstanden", 12), ("gemeistert", 18)): - await db.execute( - f"UPDATE baustein_progress SET {_spalte} = COALESCE({_spalte}, datetime('now')) " - f"WHERE gute_antworten >= {_schwelle}" - ) - await db.execute(f"UPDATE baustein_progress SET {_spalte} = NULL WHERE gute_antworten < {_schwelle}") await db.commit() diff --git a/backend/lernen.py b/backend/lernen.py index 8762206..bac7a8b 100644 --- a/backend/lernen.py +++ b/backend/lernen.py @@ -72,6 +72,7 @@ FRAGETYPEN = { # Antwort-Niveau (wie sehr der Kern getroffen ist) → Punkt-Delta. NIVEAUS = { + "unbeantwortbar": 0, # Frage selbst kaputt (Randthema/Verweis auf Nichtgezeigtes) → kein Malus "kaum": -1, # < 25 % richtig "teilweise": 0, # 25–49 % "solide": 1, # 50–74 % diff --git a/templates/Prompt/Baustein-Bewertung-Kritik.md b/templates/Prompt/Baustein-Bewertung-Kritik.md index e5df238..d477e4b 100644 --- a/templates/Prompt/Baustein-Bewertung-Kritik.md +++ b/templates/Prompt/Baustein-Bewertung-Kritik.md @@ -16,9 +16,10 @@ ZU PRÜFENDE BEWERTUNG (enthält das vergebene Niveau): {bewertung_block} NIVEAU-SKALA (Anteil des getroffenen Kerns): -- kaum < 25 % · teilweise 25–49 % · solide 50–74 % · stark 75–99 % · komplett 100 %. +- unbeantwortbar (Frage selbst kaputt — kein Punktverlust) · kaum < 25 % · teilweise 25–49 % · solide 50–74 % · stark 75–99 % · komplett 100 %. PRÜFE GEGEN DIESE KRITERIEN: +- FAIRNESS DER FRAGE: Ist die GEPRÜFTE FRAGE aus dem BAUSTEIN nicht beantwortbar (Randthema/Stichwort, Verweis auf nicht Gezeigtes, falsche Prämisse), MUSS das Niveau "unbeantwortbar" sein — NIE "kaum". Wurde der Lerner für eine kaputte Frage abgewertet → Fehlurteil. - Passt das Niveau zum tatsächlichen Anteil des Kerns? Zu STRENG (richtige/vollständige Antwort zu niedrig) ODER zu MILDE (falsche/dünne Antwort zu hoch) → Fehlurteil. Beide Richtungen prüfen. - Kern sachlich FALSCH (Gegenteil) → muss "kaum" sein, egal wie selbstsicher. - Kein Fordern über das Material hinaus: „Nicht im Material" darf nie zu Lasten gehen. diff --git a/templates/Prompt/Baustein-Bewertung.md b/templates/Prompt/Baustein-Bewertung.md index 22b49b0..5f01a12 100644 --- a/templates/Prompt/Baustein-Bewertung.md +++ b/templates/Prompt/Baustein-Bewertung.md @@ -22,6 +22,12 @@ FINALER STAND ZÄHLT — nicht die erste Aussage: - Zuerst falsch, dann im Dialog selbst korrigiert = zählt (erlaubter Lernweg). - ABER: Hat der Tutor die Lösung vorgesagt und der Lerner sie nur nachgesprochen ("ja", "genau", bloße Wiederholung), zählt sie NICHT. Der tragende Schluss muss vom Lerner kommen. +FRAGE-CHECK ZUERST — ist die GEPRÜFTE FRAGE überhaupt fair? +- Prüfe gegen den BAUSTEIN: Lässt sie sich aus dem Material beantworten? +- NICHT fair, wenn die Frage ein nur am Rand erwähntes Stichwort abfragt, auf nicht gezeigte Dinge (Code-Ausschnitte, Beispiele, Werte) verweist oder eine falsche Prämisse hat. +- Dann niveau "unbeantwortbar": der Lerner wird NICHT bestraft (kein Punktverlust). Das gilt AUCH, wenn der Lerner korrekt sagt „das steht so nicht im Material / ist nicht beantwortbar". Feedback benennt knapp den Mangel der FRAGE — kein Vorwurf an den Lerner. +- Ist die Frage fair, bewerte normal mit den Niveaus unten. + NIVEAU — wie viel vom KERN der Frage ist richtig getroffen? Wähle GENAU EINS: - "kaum": unter 25 % — fast nichts richtig, oder klar falsch / das Gegenteil. - "teilweise": 25–49 % — ein Bruchstück stimmt, der Kern fehlt. @@ -46,4 +52,4 @@ HINWEISE DES PRÜFERS ZUR LETZTEN FASSUNG: {kritik_block} Gib NUR dieses JSON aus (kein weiterer Text): -{{"feedback": "ein Satz", "niveau": "kaum" | "teilweise" | "solide" | "stark" | "komplett"}} +{{"feedback": "ein Satz", "niveau": "unbeantwortbar" | "kaum" | "teilweise" | "solide" | "stark" | "komplett"}} diff --git a/templates/Prompt/Baustein-Frage-Variante.md b/templates/Prompt/Baustein-Frage-Variante.md index d7e4184..4beedd4 100644 --- a/templates/Prompt/Baustein-Frage-Variante.md +++ b/templates/Prompt/Baustein-Frage-Variante.md @@ -9,11 +9,17 @@ BAUSTEIN AUS DEM GUIDE (fachliche Referenz — die Frage darf ihr nie widersprec KOMPAKTE FASSUNG (Merksätze, falls vorhanden): {kompakt_block} +ERDUNG AM BAUSTEIN (zuerst prüfen): +- Das Muster wurde ohne den Guide-Text erstellt — es kann am Inhalt vorbeigehen. +- Prüfe das Muster gegen den BAUSTEIN oben: Lässt sich die Sache wirklich aus dem Material beantworten? +- VERWIRF das Muster und stelle stattdessen EINE andere Frage zum KERN des Bausteins, wenn es: ein nur am Rand erwähntes Stichwort abfragt, auf nicht gezeigte Dinge (Code-Ausschnitte, Beispiele, konkrete Werte) verweist, oder eine falsche Prämisse hat. +- Die Ersatzfrage muss klar aus dem BAUSTEIN beantwortbar sein. Im Zweifel das zentrale Konzept des Bausteins abfragen. + HARTE REGELN: - GENAU EINE Frage. Ein einziges Fragezeichen. Eine einzige Sache. - Maximal 1–2 Sätze, keine Vorrede, kein Szenario-Aufbau. - Verboten: zwei Fragen mit "und"/"sowie" verketten, "nenne drei …", Aufzähl-Forderungen. -- Gleiche Kernfrage wie das Muster, nur anders formuliert — KEINE neue Sache, KEINE wörtliche Kopie. +- Ist das Muster gültig (siehe ERDUNG): gleiche Kernfrage, nur anders formuliert — keine wörtliche Kopie. Sonst die geerdete Ersatzfrage. - Frag nur, was aus dem Material beantwortbar ist. Keine erfundenen Zusatzannahmen. - Sprich den Lerner direkt an, klares Deutsch, keine Floskeln. - `$…$` NUR für echte Mathematik. Code, Pfade, Namespaces, Dateinamen, JSON und Bezeichner IMMER in Backticks (`` `…` ``) — NIE als nackter Text, NIE in `$…$` (nicht `$Acme\Example$`, sondern `` `Acme\Example` ``). diff --git a/templates/Prompt/Frage-Muster-Recherche.md b/templates/Prompt/Frage-Muster-Recherche.md index da0498b..0c7d9a9 100644 --- a/templates/Prompt/Frage-Muster-Recherche.md +++ b/templates/Prompt/Frage-Muster-Recherche.md @@ -11,6 +11,7 @@ AUFGABE (für **jeden** der Bausteine oben): - Lasse eine Kombination **weg**, wenn der Typ klar nicht passt (z.B. Code-Vorhersage bei reiner Theorie ohne Code). Nichts erzwingen. - Jedes Muster ist EINE konkrete, knappe Frage (1–2 Sätze, genau ein Fragezeichen, eine Sache) — kein Mehrteiler, keine Aufzählung. - Die Frage muss aus dem Baustein-Wissen beantwortbar sein. Erfinde keine Zusatzannahmen. +- WICHTIG: Du siehst nur Titel, NICHT den späteren Guide-Text. Frag deshalb nur nach dem KERNKONZEPT des Subbausteins. Setze NICHTS voraus, was evtl. nicht im Guide steht: keine „gezeigten" Code-Ausschnitte/Beispiele/Diagramme, keine konkreten Werte/Listen/Zahlen, keine Randthemen. Frag das Konzept selbst, nicht ein bestimmtes Artefakt. - Innerhalb eines Subbausteins sollen die Muster verschiedener Typen **wirklich verschiedene** Aspekte treffen — keine Umformulierungen derselben Frage. - Der `typ` ist exakt einer der Schlüssel oben. `baustein` ist exakt einer der Baustein-Titel oben. `subbaustein` ist exakt einer der Subbaustein-Titel des jeweiligen Bausteins.