llamacppctl/docs/EVAL_RUBRIC.md
dschlueter bee6a71de0 docs: add model profiles, evaluation rubric, and CLAUDE.md
KI_TOOLS_PROFILES.md records what each local GGUF is actually for, based on
the model cards: ornith is a purpose-built agentic coding model, Carnice targets
agent runtimes, Qwopus is reasoning plus vision, and the two HauhauCS models are
abliterated — an axis about refusals, not literary quality. It also maps which
models the local mmproj.gguf fits (the Qwen3.6-35B-A3B based ones, not ornith).
Capability and benchmark claims are attributed to their authors, not asserted.

EVAL_RUBRIC.md separates what a script can measure from what needs reading, and
warns that a passing test suite only proves the code satisfies its own tests.

CHANGELOG covers the mmproj feature, the --print-effective-config fix, and the
new tooling.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 16:25:26 +02:00

108 lines
5.2 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.

# Bewertungsrubrik für Modell-Prompt-Tests
Zweck: Modellwechsel (anderes Modell, andere Quantisierung, `Balanced` statt
`Aggressive`, MTP, KV-Cache-Einstellungen) sollen an **Zahlen** entschieden
werden, nicht an Bauchgefühl. Ohne Vorher-Nachher-Messung ist nicht feststellbar,
ob eine Änderung verbessert oder verschlechtert hat.
Grundlage sind die Läufe unter `~/llamacppctl_prompt_tests/` gegen die Prompts in
`example_user_prompts/`. Modelleignung siehe [`KI_TOOLS_PROFILES.md`](KI_TOOLS_PROFILES.md).
## Zwei Ebenen
**Objektiv** — von `scripts/eval_prompt_tests.py` automatisch gemessen, keine
Meinung nötig:
| Metrik | Domäne | Bedeutung |
|---|---|---|
| Wortzahl, Abweichung vom Ziel | prosa, reden | Der Prompt nennt ein Ziel („etwa 1200 Wörtern"). |
| Trunkierungsverdacht | alle | Text endet ohne Satzzeichen → Budget zu klein. |
| Tests laufen durch | coding | Der generierte Code wird **wirklich ausgeführt**. |
| Anteil bestandener Tests | coding | `passed / (passed + failed)`. |
**Subjektiv** — von Hand oder per LLM-Judge, Skala 15. Die Anker unten sind
bewusst so formuliert, dass 3 „brauchbar, aber mit Mängeln" bedeutet; ein
durchschnittlich guter Text landet nicht automatisch bei 4.
## Skala
| Punkte | Bedeutung |
|---|---|
| 5 | Kriterium durchgängig erfüllt; kein Eingriff nötig. |
| 4 | Erfüllt, mit einzelnen Schwächen, die den Gesamteindruck nicht tragen. |
| 3 | Brauchbar, aber erkennbare Mängel; Überarbeitung nötig. |
| 2 | Kriterium überwiegend verfehlt; Grundgerüst vorhanden. |
| 1 | Verfehlt. |
## Prosa
1. **Show, don't tell** — Innenleben ausschließlich über Handlung, Gegenstand,
Wahrnehmung. *1 = benannte Gefühle („sie war traurig"); 5 = kein einziges
benanntes Gefühl, Zustand trotzdem eindeutig.*
2. **Schlussbild** — konkretes, bedeutungstragendes Bild statt Moral oder
Zusammenfassung. *1 = explizite Lehre; 5 = Bild, das die Geschichte trägt.*
3. **Ton- und Registertreue** — hält die geforderte Tonlage (z. B. „nüchtern,
ohne Pathos") über den gesamten Text.
4. **Sprachliche Präzision** — konkrete Substantive, keine Füllattribute, keine
Klischees.
5. **Komposition** — Aufbau trägt; kein Leerlauf, kein abrupter Abbruch.
6. **Sprachrichtigkeit (Deutsch)** — Grammatik, Kasus, Idiomatik. *Eigener
Punkt, weil abliterierte, primär englisch trainierte Modelle hier auffällig
sind.*
## Reden
1. **Argumentative Substanz** — trägt der Gedankengang, oder reiht er Behauptungen?
2. **Vorweggenommene Einwände** — wird der stärkste Gegeneinwand benannt und
beantwortet, nicht der schwächste?
3. **Benannte Zielkonflikte** — werden echte Interessengegensätze offen
ausgesprochen statt harmonisiert?
4. **Rhetorische Mittel** — bewusst und sparsam eingesetzt (Trikolon, Anapher,
Antithese), nicht dekorativ.
5. **Adressatenbezug** — Sprache, Beispiele und Anrede passen zum Publikum.
6. **Sprachrichtigkeit (Deutsch)** — siehe oben.
## Coding
1. **Korrektheit***primär aus dem automatischen Testlauf.* Ein Modul, dessen
eigene Tests durchfallen, kann in diesem Kriterium nicht über 2 kommen.
2. **Anforderungsabdeckung** — sind alle Punkte des Prompts umgesetzt?
3. **Fehlerbehandlung** — die im Prompt geforderten Fehlerfälle, sauber getrennt.
4. **Testqualität** — decken die Tests die genannten Fälle ab, und sind sie
konsistent zum eigenen Code (richtiger Exception-Typ, Fixtures erfüllen das
Schema)?
5. **Keine Halluzinationen** — keine erfundenen APIs, Signaturen,
Framework-Aussagen oder Benchmark-Messwerte. *Automatisch nicht prüfbar;
erfundene Messwerte sind in den bisherigen Läufen wiederholt aufgetreten.*
6. **Lesbarkeit** — Benennung, Struktur, Kommentardichte.
## Durchführung
- **Blind bewerten.** Die Modellzuordnung steckt im Dateinamen; beim Scoren
ausblenden (`scripts/eval_prompt_tests.py --anonymize` schreibt anonymisierte
Kopien mit Zufalls-IDs und eine Auflösungstabelle).
- **Ein Kriterium über alle Texte**, nicht ein Text über alle Kriterien. Das
hält den Maßstab konstant.
- **LLM-Judge:** möglich gegen den lokalen Server, aber der Judge darf **nicht**
das bewertete Modell sein. Ein Modell bewertet seine eigenen Texte zu gut.
Der Judge ersetzt die menschliche Stichprobe nicht — mindestens 20 % der Texte
gegenlesen und die Übereinstimmung prüfen.
- **Mindestens zwei Läufe pro Zelle**, weil bei `temp > 0` ein Einzellauf wenig
aussagt. Für Coding-Vergleiche `--seed` fixieren.
## Was die Zahlen nicht sagen
Ein bestandener Testlauf beweist, dass der Code *seine eigenen* Tests besteht —
nicht, dass er korrekt ist. Wenn Modell und Test aus derselben Halluzination
stammen, sind beide konsistent falsch. Kriterium 4 (Testqualität) ist deshalb
nicht redundant zu Kriterium 1, sondern dessen Korrektiv.
## Sicherheitshinweis
`scripts/eval_prompt_tests.py` führt **modellgenerierten Code aus**. Das ist der
Sinn der Übung, aber es ist Codeausführung aus einer nicht vertrauenswürdigen
Quelle. Der Runner arbeitet in einem temporären Verzeichnis, erzwingt ein
Zeitlimit und verweigert den Start als `root`. Er bietet **keine** Netz- oder
Dateisystem-Isolation. Wer die Läufe auf einem Rechner mit Produktionsdaten
auswertet, sollte `--no-exec` verwenden oder das Skript in einem Container
starten.