101 lines
5.6 KiB
Markdown
101 lines
5.6 KiB
Markdown
# 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 → Kanten auflösen
|
||
→ Zyklen brechen (Judge) → Bausteine = Ziel-Gruppen im Band (split/merge)
|
||
→ topologische Ordnung (Bausteine + Atome darin)
|
||
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 braucht|verwandt, status)`
|
||
- `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).
|