Files
creator2/DESIGN.md
2026-07-13 12:31:25 +02:00

102 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Design creator2
Beschlossen am 2026-07-09 (Diskussion Nutzer + Claude). Ersetzt `../creator`.
## Warum Neubau
Der Vorgänger gruppierte nach Entitäts-Ähnlichkeit (Clustering → Naming → Umbrella → Dedup
→ Degradier-Pass). Der Guide las sich als Aneinanderreihung von Bausteinen. Viele Fixes
waren Symptomreparatur an dieser Kerneinheit. creator2 wechselt das Kriterium: gruppiert
wird nach „lernt sich gut zusammen" (Backward Design), nicht nach „ist dieselbe Entität".
## Pipeline
```
E0 Korpus Themen: N Recherche-Sweeps (Curricula/Lehrbuch/Syllabus/Übungen) → Snapshots
Uni: Dateien aus topics/<name>/ (txt/md/pdf) → Snapshots
Soll-Extraktion je Quelle → Konsens (Themen: Punkt braucht ≥2 unabhängige
Quellen; uni: 1 Beleg genügt — Korpus ist vertrauenswürdig, Zitat-Gate
fängt Halluzinationen)
Themen: Runden bis Sättigung (Runde ohne neuen Soll-Punkt) → Auto-Freeze
E1 Inventar Abschnitte (~12k Zeichen) → 2 Reader je Abschnitt → Atome mit Verbatim-Anker
Dedup: Anker-Overlap (auto) → Embedding-Kandidaten → 2er-Panel (einstimmig)
Soll-Zuordnung je Atom; Soll-Punkt ohne Atom → gezielte Nachextraktion
E2 Artefakte je Soll-Punkt-Gruppe: Flashcards + 1 typisiertes Beispiel pro Atom
(Form: text|mathe|code|tabelle, beste Passung) → Form-Gate
(Syntax/Struktur parse-only, kein Ausführen) → Verify-Panel gegen Anker → Fix
E3 Struktur Lernziele+Zuordnung aus Atomen (je Soll-Punkt) → Ziel-Check
→ Bausteine = Ziel-Gruppen im Band (split/merge)
→ Ordnung per Judge je Level (Quellpositions-Median als Prior,
Permutations-Gate, Fallback = Quellreihenfolge mit Befund)
E4 Guide je Baustein: Writer (Facts inline, Atom-Marker; Ausgabe DELIMITED, nicht JSON
— LaTeX-Backslashes) → det. Checks → Prüfer → Fix (Fix-Cap gegen Churn).
Beispiel-Marker setzt der Code DETERMINISTISCH (nicht der Writer);
Assembly tauscht Marker gegen ```-Fence/Tabelle.
```
Jede Ebene endet mit `qa.messen(ebene)`; `auto_loop` fährt QA→Repair bis Note 10,0,
Stillstand oder 10 Iterationen. Erst dann startet die nächste Ebene.
## Datenmodell (SQLite, backend/db.py)
- `topics(name, titel, art thema|uni, status, provider)`
- `runs(id, topic, status running|paused|done|failed|budget, gestartet, beendet, git_hash, git_dirty, budget_tokens, grund)`
- `events(run_id, ts, ebene, stage, item, template, template_hash, provider, model, role, status, dur_ms, wait_ms, tok_in, tok_out, tok_cache_read, tok_cache_write, meta)` — Ledger, append-only
- `quellen(id, topic, art web|datei, titel, url, snapshot, hash, runde, status)`
- `soll(id, topic, punkt, status kandidat|bestaetigt, belege JSON [{quelle,zitat}])`
- `atome(id, topic, titel, typ, definition, level, status, soll_id, ziel_id, baustein_id, ord, merged_into)`
- `anker(atom_id, quelle_id, start, ende, zitat)`
- `kanten(topic, von_atom, zu_atom, art verwandt, status)` — Dedup-Gedächtnis
- `artefakte(id, atom_id, typ flashcard|beispiel, inhalt JSON, status kandidat|verifiziert|verworfen)`
— beispiel-`inhalt` trägt `form` + formspezifische Felder (text|code+sprache|tabelle);
code/tabelle kommen verbatim via `<!-- beispiel: id -->` in den Guide (Assembly-Swap)
- `lernziele(id, topic, text, soll_id, status)`
- `bausteine(id, topic, ziel_id, titel, ord, status)`
- `sections(baustein_id, stage, text_kompakt, text_lang, befunde JSON)`
- `leitner(artefakt_id, box, faellig, historie)`
- `befunde(run_id, ebene, art, item, detail, status offen|repariert|freigesprochen)`
Alles status-basiert → Resume = Lauf neu starten, fertige Items werden übersprungen.
## QA (backend/qa.py)
**Invarianten (deterministisch, gated):**
- E0: jeder bestätigte Soll-Punkt hat ≥2 Belege aus verschiedenen Quellen; Korpus nicht leer
- E1: jedes Atom hat Anker (Zitat verbatim in Quelle gefunden), Definition, Typ, genau einen
Soll-Punkt; jeder Soll-Punkt ≥1 Atom
- E2: jedes Atom ≥1 verifizierte Flashcard; Beispiel-Status entschieden
- E3: Partition (jedes Atom genau ein Baustein via Ziel), Bandgröße, DAG azyklisch,
keine Kante von spätem zu frühem Baustein
- E4: jeder Atom-Marker vorhanden, Ziel-Anker im Text, Längenband, keine Vorwärtsverweise
(Titel eines späteren Atoms fällt nicht früher)
**LLM-Stichproben (nur wo nötig, immer 2 unabhängige Bestätiger):** fachlich-falsch im Guide.
Note = 10 · (1 gewichtete Befundquote); 10,0 nur bei null offenen Befunden.
## Nebenläufigkeit
Einfache Wellen (`asyncio.gather` + Semaphoren in agents.py), keine Streaming-Engine.
Innerhalb einer Ebene laufen unabhängige KETTEN (gen→verify je Chunk/Baustein) parallel;
Stage-Barrieren nur, wo ein Schritt global rechnet (Dedup, Level, Ordnung, Konsens).
Panels = n parallele Calls + Konsensregel. Hedge: Slot ohne Ergebnis nach
max(90 s, timeout/2) bekommt einen Zwilling, erstes valides Ergebnis gewinnt.
Live-Board trotzdem: jeder Statuswechsel → WebSocket-Broadcast.
## Provider
Wie Vorgänger: `claude`-CLI, `opencode` (MiniMax), MiniMax-Text-API direkt (tool-lose Calls).
Rollen quick|judge|guide|fast je Provider-Stack, Routing via env (`ROLE_JUDGE=claude`).
`CREATOR_FAKE_AGENTS=1` → fake_agents.py.
## Frontend (Vue 3 + Vite)
Tabs: **Board** (Spalten = Ebenen, ALLE Karten, scrollbar, live via WS) · **Guide**
(marked+KaTeX+highlight, Level-Filter) · **Üben** (Leitner-Boxen) · **Kennzahlen**
(Tokens/Zeit je Ebene/Stage/Template aus dem Ledger).
## Bewusst gestrichen
Delta-Läufe (Material vollständig), Abnahme-Benchmark, Projekt-/Link-Quellen,
Chat/Prüfungs-Features, ELO/Stufen-Ansichten (Level-Feld existiert, Ansichten später).