Skip to content

Optionaler KI-Tutor in Übungen: drei Hinweisstufen, Lösungsprüfung, Monatsdeckel (LRN-6) - #30

Open
hernstev97 wants to merge 2 commits into
mainfrom
feat/lrn-6-context-tutor-mvp
Open

hernstev97 wants to merge 2 commits into
mainfrom
feat/lrn-6-context-tutor-mvp

Conversation

@hernstev97

Copy link
Copy Markdown
Owner

Bisher hilft eine Übung nur mit festen Hinweisen und „Lösung zeigen“. LRN-6 wünscht einen Tutor, der Lektion und Übung kennt, auf Klick gestufte Hilfe gibt und die Lösung nicht verrät. Dieser PR baut Schritt 2 aus dem Issue: Hinweisstufen 1–3, Lösungsprüfung, Monatsdeckel, kein gespeicherter Verlauf.

Ohne ANTHROPIC_API_KEY im Convex-Deployment ändert sich nichts. Übungsseite und /daten sehen aus wie vorher, und es geht keine Anfrage raus. Offline und im Offline-Lesemodus ist der Tutor ebenfalls ausgeblendet. Es gibt noch keinen Schlüssel: Alles ist nur gegen einen Fake-Provider getestet, ein echter API-Aufruf hat nie stattgefunden.

Was der Tutor tut

  • Unter den Hinweisen einer Übung: „Tutor fragen“ mit Stufe 1 (Denkanstoß), Stufe 2 (Konzept, mit Link auf den Lektionsabschnitt) und Stufe 3 (Fehlerstelle). Die nächste Stufe wählst du selbst. Dazu kommt ein freiwilliges Feld „Was hakt?“.
  • Ist die Übung gelöst oder die Lösung angezeigt, beantwortet er freie Fragen zur Übung.
  • Bevor eine Antwort erscheint, prüft der Server deterministisch, ob sie eine akzeptierte Lösung enthält. Dafür nutzt er die Normalisierer aus src/engine/answers.ts und zählt nur den Teil, den du selbst schreiben musst. Bei einem Treffer fragt er einmal neu, beim zweiten zeigt die Seite den nächsten statischen Hinweis.
  • Ein Monatsbudget wird auf dem Server durchgesetzt. Ab 80 % erscheint ein Hinweis. Passt eine lange Anfrage nicht mehr ins Restbudget (mit Sonnet etwa 10 ct), pausiert der Tutor bis Monatsanfang. Den Verbrauch zeigt /daten.
  • Im Erzählkurs gilt deine KI-Regel aus LRN-29: Handwerk erklären ja, inhaltliche Vorschläge, Umschreiben und Bewertung der Wirkung nein. Im Combat-Kurs schlägt er keine Designentscheidungen vor. Eigene Texte (practice mit prose oder text) bekommen in beiden Kursen keinen Tutor, Übungen ohne Musterlösung nirgends.
  • An Anthropic gehen Lektion, Übung samt Lösung, dein Versuch, die letzte Rückmeldung und deine Frage. Übungs-ID, Clerk-ID und E-Mail gehen nicht mit. Dein Name, Benutzername und deine E-Mail aus der Clerk-Sitzung werden vorher im ganzen Request durch Platzhalter gleicher Länge ersetzt („Steven“ → „Jordan“). Gespeichert werden nur Token-Zähler und Kosten.

Screenshots mit dem Fake-Provider; die Antworten sind handgeschrieben, nicht von einem Modell:

Desktop: zwei Stufen, Abschnitts-Link Handy (390 px)
Tutor-Panel auf dem Desktop nach Stufe 1 und 2; „Die Operatoren ?. ?: und !!“ ist ein Link in die Lektion Dasselbe Panel auf 390 px Breite
80 % des Budgets Budget verbraucht Nach „Lösung zeigen“
Gelber Hinweis: 4,10 $ von 5,00 $ Monatsbudget verbraucht Pausiert bis zum 1. November, kein Eingabefeld mehr Freie Frage mit Antwort nach angezeigter Lösung

Abschnitt KI-Tutor auf /daten mit Monatsverbrauch, Anfragen und Modell

Was du entscheiden musst

  1. Modell (TUTOR_MODEL, Standard claude-sonnet-5-5; TUTOR_EFFORT, Standard medium): Das ist der Vorschlag aus LRN-6, bestätigt ist er nicht. Neu seit 07.10.2026 gibt es Claude Haiku 5.5 für 0,10 / 0,01 / 0,50 $ pro Million Tokens (Input / Cache-Read / Output). Das ist der Preis, den das Issue für GPT-6 Luna high nennt. Hält Haiku im Eval mit, entfällt Lunas einziger Vorteil. Haiku 5.5 ist als haiku-medium im Eval, Luna nicht (dafür bräuchte es einen OpenAI-Schlüssel und einen zweiten Provider).
  2. Budget (TUTOR_MONTHLY_BUDGET_USD, Standard 5): Bei angenommenen 500 Output-Tokens kostet die erste Frage zu einer Übung mit Sonnet etwa 2 ct, jede weitere zur selben Übung dank Cache etwa 0,6 ct. 5 $ reichen damit für etwa 200–400 Antworten. Wie viel das Denken dazugibt, zeigt erst der Eval. Mit dem API-Guthaben aus Claude Max (siehe Kommentar in LRN-6) könntest du höher gehen, ohne zu zahlen.
  3. Schlüssel: Max-Guthaben einlösen, in der Console einen eigenen Workspace mit Ausgabenlimit und einen API-Schlüssel anlegen, dann pnpm exec convex env set ANTHROPIC_API_KEY …, erst in Entwicklung. Produktion habe ich nicht angefasst.
  4. Eval laufen lassen, sobald ein Schlüssel da ist: TUTOR_PRIVATE_NAMES="Vorname,Nachname,E-Mail" pnpm tutor:eval --live --max-usd 2. Die Schätzung liegt bei etwa 1,40 $ für Sonnet low, Sonnet medium und Haiku medium. Bevor die nächste Anfrage das Limit überschreiten könnte, bricht er ab. Danach füllst du den Bewertungsbogen tutor-eval/…/grading.md aus.

Was ich selbst entschieden habe

  • Kein Streaming im MVP. Die Antwort kommt komplett, solange steht „Tutor denkt nach …“. Laut Issue braucht Sonnet medium dafür etwa 7 s.
  • Budget mit Reservierung. Vor jedem Aufruf wird der schlimmstmögliche Preis gebucht: jedes Zeichen als Cache-Write-Token plus 3.000 Output-Tokens. Nach der Antwort ersetzt der echte usage-Wert diese Buchung. So hält der Deckel auch, wenn zwei Tabs gleichzeitig fragen. Das SDK wiederholt nichts selbst (maxRetries: 0), weil ein zweiter Versuch doppelt kosten könnte. Eine Zeitüberschreitung (90 s) bleibt mit der Reservierung gebucht, liegengebliebene Reservierungen verfallen nach 15 Minuten. Als Monat zählt der UTC-Kalendermonat, wie bei den Console-Limits.
  • Bei vollem Budget bleibt ein Hinweis „Pausiert bis …“ sichtbar. Das Issue sagt „ausgeblendet“. Ich zeige den Hinweis, damit nicht unklar ist, wohin der Tutor verschwunden ist.
  • max_tokens steht auf 3.000 statt etwa 1.000, weil das Denken mitzählt. stop_reason: max_tokens gilt als Fehler, wie im Issue verlangt.
  • Die Lektion darf bis 60.000 Zeichen lang sein statt 40.000. python/nebenlaeufigkeit hat als Text 40.852 Zeichen. Alle 2.273 Übungen des Inhalts passen in die Grenzen (Test in tooling/tutor-eval.test.ts).
  • Freie Fragen nach dem Lösen sind mit drin, wie es der Didaktik-Abschnitt des Issues beschreibt. Schritt 2 nennt sie nicht ausdrücklich.
  • Keine Ausweichmodelle bei refusal. Die Kosten eines anderen Modells ließen sich nicht sauber verbuchen. Eine Ablehnung zeigt eine Meldung, und die statischen Hinweise bleiben.
  • Nur Modelle mit hinterlegtem Preis (claude-sonnet-5-5, claude-haiku-5-5; Preise von der Preisseite am 24.10.2026). Bei jedem anderen Wert bleibt der Tutor aus, und /daten nennt den Grund. Issue (Stand 29.09.) und Review nennen 0,20 $ für Sonnets Cache-Read; die Preisseite nennt heute 0,10 $, das steht im Code.
  • SDK fest auf @anthropic-ai/sdk 1.1.0. Das ist drei Tage alt. Für das neuere 1.3.0 hätte die Mindest-Release-Alter-Sperre von pnpm eine Ausnahme gebraucht.
  • Combat bekommt eine eigene Regel nach content/combat/area.yaml („Jede Designentscheidung triffst du selbst“). Das Issue verlangte sie nicht.
  • Namen werden auch im Kurstext ersetzt. 21 Inhaltsdateien nennen deinen Vornamen, etwa val name = "Steven" im Kotlin-Kurs oder Pfade wie /home/steven in Automation. Der Tutor sieht dort „Jordan“ und /home/jordan. Das ist harmlos, kann aber so in einer Antwort auftauchen. Die Lösungsprüfung arbeitet auf demselben ersetzten Text und bleibt damit stimmig.
  • Die Lösungsprüfung lässt Lösungen unter drei Zeichen nur als eigenen Codeschnipsel durchfallen (etwa `?.`), weil sie sich sonst nicht von normalem Text unterscheiden. Bei Fehlersuche, Reihenfolge und Auswahl erkennt sie auch Zeilennummern, Nachbarpaare und „Option 2“. Umschreibungen fängt sie nicht. Sie ist ein Schutz vor versehentlichem Verraten, so wie das Issue sie beschreibt.

Was noch einen echten Schlüssel braucht

  • Der Eval mit echten Antworten: Diagnose, Zurückhaltung, Deutsch, Wartezeit. Bisher sind nur die 30 Fälle und ihre Prompts geprüft.
  • Ein Cache-Treffer am echten cache_read_input_tokens. Der Test simuliert den Cache, indem er prüft, dass der Prefix byte-gleich ist.
  • Echte Fehlerfälle wie ein leeres Guthaben oder Rate Limits. Getestet ist nur ein nachgestellter 400-Fehler.
  • Lauf des SDK in der Convex-Cloud. Lokal bündelt und lädt es das wegwerfbare Convex-Backend, siehe unten.

Überschneidungen

Prüfungen

  • pnpm lint, pnpm typecheck, pnpm content:check, pnpm bear:check, pnpm build: grün. Das SDK landet nicht im Frontend-Bundle. Der Tutor-Code ist ein eigenes Chunk von 13 KB.
  • pnpm test: 382 Tests grün. Neu sind 17 Convex-Tests mit Fake-Provider (Zugriff, ohne Schlüssel, Kosten, Cache, kein personenbezogenes Datum im Request, Lösungsprüfung mit zweitem Versuch, Budget auch parallel, Monatswechsel, Zeitüberschreitung, liegengebliebene Reservierung, Ablehnung, Abbruch, Provider-Fehler), 29 Engine-Tests und 7 Eval-Tests, darunter einer über alle Übungen des Inhalts.
  • pnpm test:e2e: 67/67 grün, darunter 8 neue Tutor-Tests (ohne Schlüssel unsichtbar, drei Stufen, Rückfall auf statischen Hinweis, Budget 80 % und 100 %, offline, nach „Lösung zeigen“, eigene Texte, /daten). Der Viewport-Test „real content fits phone, tablet and desktop viewports“ lief lokal grün; in CI scheitert er auch auf main (LRN-31), den habe ich nicht angefasst.
  • pnpm test:pwa:e2e: 5/5 grün.
  • tooling/ci/convex-e2e.sh gegen ein wegwerfbares lokales Convex-Backend: 15/15 grün, darunter der neue Test „ohne Schlüssel meldet sich der Tutor als abwesend“. Die Funktionen samt SDK ließen sich dort deployen.
  • pnpm tutor:eval (Trockenlauf): 30 Fälle gültig, alle Versuche laut Plattform-Prüfung falsch, Schätzung 1,39 $.
  • Im Browser durchgeklickt, auch mobil: Playwright mit dem Fake-Provider auf 1280 px und 390 px Breite, hell und dunkel. Ein Klick mit echtem Modell steht aus, weil es keinen Schlüssel gibt.
  • Unabhängiges Review vor dem PR (ein Agent ohne meine Begründungen): Die Befunde stehen behoben im zweiten Commit, bis auf den Preisbefund (siehe oben). Der wichtigste: Die Ausfallerkennung hätte das Panel während eines langen Aufrufs ausgeblendet. Dazu kamen Lücken in der Lösungsprüfung (Optionsnummern, Zeilennummern, Löschungen, Shell-Satzzeichen), fehlendes Ersetzen von Namen, Kanten beim Budget, max_tokens zu knapp und Kampf-Texte, die einen Tutor bekamen. Den Preisbefund habe ich nicht übernommen (siehe oben).

Teil von LRN-6. Das Issue bleibt nach dem Merge offen: Eval mit echtem Modell, Bewertung von explain und practice (Schritt 3), Streaming und Fragen in der Lektion (Schritt 4).

🤖 Generated with Claude Code

hernstev97 and others added 2 commits October 24, 2026 08:26
…N-6)

Optionaler Tutor unter den Hinweisen einer Übung. Ohne ANTHROPIC_API_KEY im
Convex-Deployment, offline und im Offline-Lesemodus bleibt er unsichtbar.

- convex/tutor.ts: Action mit requireOwner und offiziellem SDK, Budget-
  Reservierung des schlimmsten Falls vor jedem Aufruf, Verbuchung aus usage
  in tutorUsage (Mikro-Dollar je UTC-Monat), Status-Query für Panel und /daten
- src/engine/tutor.ts: byte-stabile Prompt-Reihenfolge mit zwei Cache-
  Breakpoints, Lösungsprüfung mit den Normalisierern aus answers.ts,
  Preise und Konfiguration (TUTOR_MODEL, TUTOR_EFFORT, TUTOR_MONTHLY_BUDGET_USD)
- KI-Regel für narrative (LRN-29) und combat; kein Tutor bei eigenen Texten
- Tests nur gegen Fake-Provider: convex-test mit ersetztem fetch, Browser-
  Tests mit window.__tutorFake; kein echter API-Aufruf
- Eval-Harness mit 30 Fällen (pnpm tutor:eval), Trockenlauf ohne Netz

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Panel bleibt während langer Tutor-Aufrufe sichtbar (Ausfallerkennung ignoriert sie)
- Namen aus der Clerk-Sitzung werden vor dem Senden ersetzt
- Lösungsprüfung: Optionsnummern, Zeilennummern bei Fehlersuche, Löschungen,
  Abdeckung über Codeblöcke, Aufgabentext und eigener Versuch gelten als bekannt
- Budget: Monat vom Client, offene Reservierungen getrennt, alte Reservierungen
  verfallen nach 15 min, Zeitüberschreitung bucht die Reservierung, keine Retries
- max_tokens 3000, SQL-Ergebnis als Rückmeldung, eigene Texte in Combat ohne Tutor

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 24, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 22fbae5b-950f-4b7f-9d0b-f44c4a77505d
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant