# Build Evals — Claude Code Skill

Skill für Claude Code. Speichere diese Datei unter `~/.claude/skills/build-evals.md`
und rufe sie mit `/build-evals` auf.

---

Führe den Nutzer Schritt für Schritt durch den Aufbau eines Eval-Systems für seinen
KI-Agenten. Folge dieser Reihenfolge strikt. Stelle pro Phase nur die nötigen Fragen,
dann handle sofort.

---

## Phase 1: Agenten verstehen

Stelle diese drei Fragen nacheinander:

1. "Was macht dein Agent? Ein Satz: was kommt rein, was kommt raus."
2. "Hast du ihn schon auf echten Eingaben laufen lassen? Was hat dich gestört?"
3. "Was ist das Schlimmste, was er tun könnte, ohne dass du es sofort merkst?"

Extrahiere aus den Antworten eine rohe Beobachtungsliste. Nicht schön formulieren,
einfach notieren was der Nutzer nennt.

---

## Phase 2: Grader-Typ entscheiden

Teile die Beobachtungsliste in zwei Spalten:

**Code-Prüfer** (zählbar, eindeutig, kein Urteil nötig):
- Hat die Ausgabe eine Zahl / ein Wort / ein Format?
- Ist die Länge unter / über X?
- Existiert eine Datei / ein Link / ein Abschnitt?
- Gibt es unerwünschte Zeichen (Emojis, Floskeln, bestimmte Phrasen)?

**LLM-Richter** (Qualitätsurteil, Interpretation nötig):
- Klingt es generisch oder spezifisch?
- Ist der Nutzen klar?
- Würde ein professioneller Empfänger das so akzeptieren?
- Deckt es das eigentliche Problem ab?

Zeige dem Nutzer die Aufteilung und frage kurz zur Bestätigung.

---

## Phase 3: Ordnerstruktur anlegen

Erstelle im Projektverzeichnis:

```
evals/
  kriterien.md        ← Beobachtungsliste aus Phase 1
  testfaelle/         ← echte Eingaben (noch leer)
  ergebnisse.md       ← Bewertungstabelle
  code_check.py       ← deterministische Checks
  richter_prompt.md   ← LLM-Richter-Auftrag
  qa_loop_prompt.md   ← adversarieller Prüfer
```

Schreibe die rohe Beobachtungsliste in `evals/kriterien.md`.

---

## Phase 4: Code-Prüfer schreiben

Schreibe für jede Frage aus der "Code-Prüfer"-Spalte einen Python-Check.

**Vorlage — passe Dateiname und Parsing an den Output-Typ an:**

```python
# Anpassen: txt, json, html, mdx, pdf, ...
output = open("output.txt", encoding="utf-8").read()

checks = [
    ("Beschreibung",  bedingung),   # True = bestanden
    # weitere Checks hier
]

bestanden = sum(1 for _, b in checks if b)
print(f"\nErgebnis: {bestanden}/{len(checks)} bestanden\n")
for name, ok in checks:
    print("  ✓" if ok else "  ✗", name)
```

**Häufige Checks:**

```python
# Text-Checks
("Wort vorhanden",          "Schlüsselwort" in output)
("Unter 600 Wörter",        len(output.split()) < 600)
("Keine generische Anrede", not output.startswith("Sehr geehrte"))
("Kein Emoji",              not any(ord(c) > 127000 for c in output))
("Preis vorhanden",         "€" in output)

# Struktur-Checks (für HTML/MDX)
("Hat FAQ-Abschnitt",       "FAQ" in output or "faq" in output.lower())
("Hat interne Links",       output.count('href="/') >= 3)
("Hat externe Links",       output.count('href="http') >= 3)

# Meta-Checks
("Titel unter 60 Zeichen",  len(titel) <= 60)
("Description unter 160",   len(description) <= 160)
```

Speichere als `evals/code_check.py`.

---

## Phase 5: LLM-Richter-Prompt schreiben

**Pflicht: Begründungen IMMER vor der Note. Nie danach.**
(Grund: LLMs rechtfertigen eine vorschnelle Note — statt ehrlich zu urteilen.)

Schreibe für die Qualitätsfragen diesen Richter-Auftrag:

```
Du bist ein kritischer Prüfer für [Output-Typ des Agenten].

Meine Qualitätskriterien:
[Kriterien aus evals/kriterien.md einfügen]

Eingabe:
[EINGABE]

Ausgabe des Agenten:
[AUSGABE]

Schritt 1: Nenne alle konkreten Hinweise, dass die Ausgabe die Kriterien erfüllt.
Schritt 2: Nenne alle konkreten Hinweise, dass sie sie verfehlt oder generisch ist.
Schritt 3: Vergib eine Note von 1 bis 5.
  5 = erfüllt alle Kriterien vollständig
  3 = gemischt, einiges gut, einiges schlecht
  1 = verfehlt die Kriterien komplett

[Optional — Ankerpunkte für konsistente Noten:]
Eine 5 klingt so: [gutes Beispiel einfügen]
Eine 1 klingt so: [schlechtes Beispiel einfügen]
```

Frage den Nutzer, ob er schon ein gutes und ein schlechtes Beispiel hat. Wenn ja,
baue sie als Ankerpunkte ein. Das macht die Noten deutlich stabiler.

Wenn Schwankungen auftreten: Multi-Richter-Konsens — drei unabhängige Claude-Sitzungen,
Mehrheitswert nehmen.

**Kalibrierungs-Warnung:** Wenn alle Noten hoch ausfallen (z.B. durchgehend 4–5 bei Outputs,
die offensichtlich Probleme haben), ist das kein gutes Zeichen — das ist eine Fehljustierung.
Ankerpunkte schärfen, Kriterien präzisieren oder zu paarweisem Vergleich wechseln.

**Wichtig:** LLM-Richter können halluzinieren — besonders bei nuancierten Kriterien.
Deshalb niemals nur auf eine Richter-Session verlassen. Multi-Konsens oder manuelles
Stichproben-Checking einplanen.

Speichere als `evals/richter_prompt.md`.

---

## Phase 6: QA-Loop-Prompt schreiben

Ein zweiter, adversarieller Prüfer verbessert die Ausgabequalität in fast jedem
Anwendungsfall. Entscheidend ist die Formulierung: nicht "überprüfe ob alles ok ist",
sondern "gehe davon aus, dass es Probleme gibt".

```
Du bist ein kritischer Prüfer. Du bekommst eine Aufgabe und eine Antwort gezeigt.

Gehe davon aus, dass es Probleme gibt. Deine Aufgabe ist, sie zu finden:
- Was fehlt oder ist unvollständig?
- Was ist unklar oder mehrdeutig formuliert?
- Was wirkt generisch statt spezifisch auf die Situation?
- Was würde ein professioneller Empfänger stören?
- Was würde der Absender bereuen, wenn er es am nächsten Morgen liest?

Liste konkrete Probleme auf. Keine Bestätigungen, keine Lobeshymnen.
Wenn du nichts findest, such nochmal.

WICHTIG: Höre nicht auf, bis du mindestens einen Fehler gefunden, einen Fix
vorgeschlagen und das Ergebnis erneut geprüft hast. Ein Durchlauf ohne mindestens
einen Fix-und-Verify-Zyklus gilt nicht als abgeschlossen.
```

Passe die Fragen an den spezifischen Use Case an. Ein Code-Prüfer fragt anders
als ein E-Mail-Prüfer.

**Variante für hochriskante Outputs** (Rechtstexte, medizinische Inhalte, o.ä.):
Zwei-Agenten-Debatte — Agent A sucht Probleme, Agent B versucht sie zu widerlegen.
Nur was beide bestätigen, gilt als echtes Problem. Aufwendiger, aber deutlich robuster.

Speichere als `evals/qa_loop_prompt.md`.

Hinweis für Claude Code Nutzer: `/goal` implementiert diesen Loop nativ —
setze das Ziel als Qualitätskriterien, Claude arbeitet und prüft bis es erfüllt ist.

---

## Phase 7: Testfälle anlegen

Fordere den Nutzer auf, 3–5 echte Eingaben in `evals/testfaelle/` zu speichern.

Format: `anfrage-01.md`, `anfrage-02.md`, usw.

Regel: Testfälle müssen aus echtem Betrieb stammen, nicht erfunden sein.
Erfundene Testfälle messen nicht das, was im Alltag schiefläuft.

Ideal: Ein Testfall, der in der Vergangenheit schiefgelaufen ist. Einer, der typisch ist.
Einer, der besonders schwierig ist. Einer, der einfach ist.

---

## Phase 8: Bewertungstabelle initialisieren

Erstelle `evals/ergebnisse.md`:

```markdown
# Eval-Ergebnisse

## Baseline — [Datum]
Agent-Version: [System-Prompt-Version / Commit]

| Testfall | Code-Checks | Richter-Note | QA-Probleme | Notizen |
|----------|-------------|--------------|-------------|---------|
| anfrage-01 | /  | /5 | — | |
| anfrage-02 | /  | /5 | — | |
| anfrage-03 | /  | /5 | — | |

**Gesamtquote Code-Checks:** X/Y bestanden
**Durchschnitt Richter:** X.X/5

---

## Änderung 1 — [Datum]
Geändert: [Was genau geändert wurde — nur eine Sache]

| Testfall | Code-Checks | Richter-Note | QA-Probleme | Delta |
|----------|-------------|--------------|-------------|-------|
```

---

## Abschluss

Fasse zusammen was jetzt existiert und erkläre den Workflow:

1. **Testfall wählen** — eine echte Eingabe aus `evals/testfaelle/`
2. **Agent laufen lassen** — Output erzeugen
3. **Code-Check** — `python evals/code_check.py` mit der Output-Datei
4. **Richter befragen** — Output + Eingabe in `evals/richter_prompt.md` einfügen, Claude fragen
5. **QA-Loop** — Output durch `evals/qa_loop_prompt.md` schicken
6. **Ergebnis eintragen** — in `evals/ergebnisse.md`
7. **Eine Sache ändern** — System-Prompt, Werkzeug oder Richter-Kriterium
8. **Wiederholen** — bis die Quote steigt

Erinnere den Nutzer an vier Regeln aus dem Anthropic-Workshop:

1. **Jede Eval muss actionable sein.** Wenn du nicht weißt, wie du auf ein schlechtes
   Ergebnis reagieren würdest, lass den Check weg.

2. **Immer nur eine Sache auf einmal ändern.** Sonst weißt du nicht, was geholfen hat.

3. **Evals sind lebende Artefakte.** Wenn dein Agent alle Testfälle zu leicht besteht
   (Saturation), braucht es härtere Szenarien. Das ist ein gutes Zeichen, kein Problem.

4. **Evals gelten für Modelle, nicht nur für Prompts.** Wenn du überlegst, ob du von
   Sonnet auf Opus upgraden sollst, lasse dieselbe Eval-Suite auf beiden Modellen durch.
   Die Ergebnisse zeigen dir, ob der Mehrpreis sich für deinen konkreten Use Case lohnt.
