Konzept: Sampling-Strategien bei unterschiedlich großen Säulen (Legacy)¶
Legacy-Konzept (Stand 2025)
Dieses Dokument beschreibt Sampling-Strategien aus der Judge-UI-Phase. In LLARS (Stand 2026-02-05) werden LLM-Evaluatoren primär als Konfiguration im Scenario Manager genutzt. Die Inhalte dienen als Hintergrund und Design-Historie.
Datum: 25. November 2025 Status: Legacy (teilweise historisch implementiert) Autor: Claude / Philipp Steigerwald
1. Problemstellung¶
Die KIA-Datensäulen haben unterschiedlich viele E-Mail-Threads:
| Säule | Beschreibung | Erwartete Größe |
|---|---|---|
| 1 | Rollenspiele | Mittel (~50-100) |
| 2 | Feature aus Säule 1 | Variabel |
| 3 | Anonymisierte Daten | Groß (~200+) |
| 4 | Synthetisch generiert | Variabel |
| 5 | Live-Testungen | Klein (~20-50) |
Problem: Wie vergleichen wir fair, wenn z.B. Säule 3 über 200 Threads hat, aber Säule 5 nur 30?
2. Sampling-Strategien¶
2.1 Strategie A: Fixed Samples per Pillar (historisch implementiert)¶
Prinzip: Pro Säule wird eine feste Anzahl Threads gezogen (samples_per_pillar).
Vorteile: - Einfach zu implementieren - Gleiche Anzahl Vergleiche pro Säulenpaar - Keine Verzerrung durch Überrepräsentation
Nachteile: - Viele Daten aus größeren Säulen werden ignoriert - Möglicherweise nicht repräsentativ für die Gesamtpopulation
Verwendung: Standardmodus in pillar_sample (N wird explizit gesetzt).
2.2 Strategie B: Bootstrap Sampling mit Replacement¶
Prinzip: Bei kleineren Säulen werden Threads mehrfach verwendet (mit Ersetzung).
Säule 1: 80 Threads → Sample: 50 (einmalig)
Säule 5: 30 Threads → Sample: 50 (mit ~20 Wiederholungen)
Vorteile: - Alle Threads werden genutzt - Größere Sample-Größen möglich - Statistische Methode zur Varianzschätzung
Nachteile: - Wiederholte Threads können Ergebnisse verzerren - Kein echter "neuer" Vergleich bei Wiederholung
Empfehlung: Nur verwenden, wenn statistische Konfidenzintervalle berechnet werden sollen.
2.3 Strategie C: Gewichtetes Sampling¶
Prinzip: Größere Säulen werden mit höherem Gewicht bewertet.
# Beispiel-Berechnung
weight_pillar_1 = len(threads_1) / total_threads # z.B. 0.25
weight_pillar_3 = len(threads_3) / total_threads # z.B. 0.65
weight_pillar_5 = len(threads_5) / total_threads # z.B. 0.10
# Gewichtete Win-Rate
weighted_win_rate = wins * weight
Vorteile: - Berücksichtigt die "Wichtigkeit" jeder Säule - Fair bei unterschiedlichen Datenmengen
Nachteile: - Komplexere Berechnung - Schwerer zu interpretieren
Empfehlung: Für finale Auswertungen, nicht für Live-Vergleiche.
2.4 Strategie D: Round-Robin mit Wiederholungen (Empfohlen, historisch)¶
Prinzip: Mehrere Durchläufe (repetitions_per_pair), bei jedem Durchlauf zufällige Threads.
Durchlauf 1: Thread 1 vs Thread A, Thread 2 vs Thread B, ...
Durchlauf 2: Thread 3 vs Thread C, Thread 4 vs Thread D, ...
Durchlauf 3: Thread 5 vs Thread E, Thread 1 vs Thread F, ... (Wiederholung beginnt)
Ablauf: 1. Für jedes Säulenpaar (z.B. 1 vs 3): 2. Pro Durchlauf: Zufällige Auswahl von N Threads aus jeder Säule 3. 1:1 Paarung der Threads 4. Bei kleiner Säule: Threads werden in späteren Durchläufen wiederverwendet
Vorteile:
- Alle Threads haben Chance, verglichen zu werden
- Mehrfache Wiederholungen erhöhen statistische Sicherheit
- Position-Swap pro Vergleich reduziert Position-Bias
- Bereits implementiert (repetitions_per_pair Parameter)
Nachteile: - Höhere Anzahl Vergleiche = mehr API-Kosten - Längere Laufzeit
Konfiguration:
// JudgeConfig.vue
{
samplesPerPillar: 10, // Pro Durchlauf
repetitionsPerPair: 3, // Anzahl Durchläufe
positionSwap: true // A/B und B/A
}
// → Gesamt: 10 × 3 × 2 = 60 Vergleiche pro Säulenpaar
3. Empfohlene Konfiguration¶
Szenario: Explorative Analyse (schnell)¶
{
selectedPillars: [1, 3, 5],
samplesPerPillar: 5,
repetitionsPerPair: 1,
positionSwap: true
}
// Paare: 3 (1-3, 1-5, 3-5)
// Vergleiche: 3 × 5 × 2 = 30 Vergleiche
// Dauer: ~5 Minuten
Szenario: Robuste Evaluation (empfohlen)¶
{
selectedPillars: [1, 3, 5],
samplesPerPillar: 10,
repetitionsPerPair: 3,
positionSwap: true
}
// Paare: 3 (1-3, 1-5, 3-5)
// Vergleiche: 3 × 10 × 3 × 2 = 180 Vergleiche
// Dauer: ~30 Minuten
Szenario: Vollständige Evaluation (wissenschaftlich)¶
{
selectedPillars: [1, 3, 5],
samplesPerPillar: 20,
repetitionsPerPair: 5,
positionSwap: true
}
// Paare: 3 (1-3, 1-5, 3-5)
// Vergleiche: 3 × 20 × 5 × 2 = 600 Vergleiche
// Dauer: ~100 Minuten
4. Metriken zur Validierung¶
4.1 Sample Coverage¶
Misst, wie viel Prozent der Threads einer Säule tatsächlich verglichen wurden.
Ziel: > 50% bei kleinen Säulen, > 20% bei großen Säulen
4.2 Repetition Overlap¶
Misst, wie oft dieselben Threads in verschiedenen Durchläufen verwendet wurden.
Ziel: < 30% (niedrig = mehr Vielfalt)
4.3 Win-Rate Varianz über Repetitions¶
Misst die Stabilität der Ergebnisse.
# Win-Rates pro Durchlauf berechnen
win_rates = [win_rate_rep1, win_rate_rep2, win_rate_rep3]
variance = np.var(win_rates)
Ziel: Varianz < 0.05 (stabile Ergebnisse)
5. Thread-Performance-Tracking (NEU)¶
5.1 Warum Thread-Performance tracken?¶
Durch das Tracking einzelner Threads können wir:
- Qualitäts-Validierung: Threads die gegen viele verschiedene Gegner verlieren sind wahrscheinlich qualitativ schwächer
- Likert-Konsistenz prüfen: Bekommt ein Thread ähnliche Bewertungen egal gegen wen er antritt?
- Sampling-Bias erkennen: Wurde ein Thread zu oft/zu selten verwendet?
5.2 Per-Thread Metriken¶
# Für jeden Thread der in Vergleichen verwendet wurde:
{
'thread_id': 123,
'pillar': 1,
'usage_count': 5, # Wie oft wurde der Thread verwendet?
'unique_opponents': 4, # Gegen wie viele verschiedene Threads?
'wins': 3,
'losses': 1,
'ties': 1,
'win_rate': 0.6,
'performance_score': 0.4, # win_rate - loss_rate (-1 bis +1)
'is_consistent_winner': True,
'is_consistent_loser': False,
# Likert-Konsistenz (NEU)
'likert_scores': {
'quality': {'mean': 4.2, 'std_dev': 0.3, 'is_consistent': True},
'empathy': {'mean': 3.8, 'std_dev': 0.8, 'is_consistent': False},
...
},
'likert_consistency_score': 0.75 # 0-1, höher = konsistenter
}
5.3 Likert-Konsistenz-Analyse¶
Frage: Wenn Thread A mehrfach bewertet wird, bekommt er immer ähnliche Likert-Scores?
Beispiel:
Thread A vs Thread X: quality_a = 4
Thread A vs Thread Y: quality_a = 4
Thread A vs Thread Z: quality_a = 5
→ std_dev = 0.47, is_consistent = True ✓
Thread B vs Thread X: quality_b = 2
Thread B vs Thread Y: quality_b = 5
Thread B vs Thread Z: quality_b = 3
→ std_dev = 1.25, is_consistent = False ✗
Interpretation: - Konsistent (std_dev < 0.5): Das LLM bewertet diesen Thread zuverlässig - Inkonsistent (std_dev > 0.5): Die Bewertung variiert stark - mögliche Gründe: - Thread hat gemischte Qualität - LLM ist unsicher - Opponent-abhängige Bewertung
5.4 Consistent Winners/Losers¶
Consistent Winner: Thread mit >= 70% Win-Rate über mindestens 3 Vergleiche - Diese Threads repräsentieren hohe Qualität der Säule - Nützlich für Benchmark-Erstellung
Consistent Loser: Thread mit >= 70% Loss-Rate über mindestens 3 Vergleiche - Diese Threads repräsentieren niedrige Qualität - Kandidaten für manuelle Überprüfung
5.5 API Endpoint¶
GET /api/judge/sessions/{id}/thread-performance
Response:
{
"total_threads": 45,
"total_comparisons": 120,
"avg_usage_per_thread": 5.3,
"coverage_stats": {
"over_sampled_count": 3,
"under_sampled_count": 8,
"evenly_sampled_count": 34
},
"threads": [...],
"pillar_summary": {...},
"consistent_winners": [...],
"consistent_losers": [...],
"likert_consistency": {
"global": {
"quality": {"mean": 3.8, "std_dev": 0.9},
"empathy": {"mean": 4.1, "std_dev": 0.7}
},
"inconsistent_threads": [...]
}
}
6. Implementierungs-Roadmap¶
Phase 1: Basis (Bereits implementiert)¶
-
repetitions_per_pairParameter in JudgeConfig - Round-Robin Sampling in Backend
- Position-Swap Konsistenz-Analyse
- Thread-Performance Endpoint mit Usage-Tracking
- Likert-Konsistenz-Analyse per Thread
Phase 2: Erweiterungen (Nächste Schritte)¶
- Thread-Performance Sektion in JudgeResults.vue
- Sample Coverage Visualisierung
- Warnung wenn kleine Säule < samples_per_pillar hat
- Export der Thread-Performance Daten
Phase 3: Erweiterte Strategien¶
- Gewichtetes Sampling als Option
- Bootstrap Confidence Intervals
- Automatische Strategie-Empfehlung basierend auf Säulengrößen
- Thread-Qualitäts-Clustering basierend auf Likert-Scores
7. Frontend-Erweiterungen¶
7.1 Säulen-Info in JudgeConfig¶
Zeige die verfügbare Thread-Anzahl pro Säule an:
<v-chip v-for="pillar in availablePillars" ...>
{{ pillar.name }}
<v-badge :content="pillar.threadCount" color="info" />
</v-chip>
7.2 Warnung bei ungleichen Säulen¶
<v-alert v-if="hasUnequalPillars" type="warning">
Die ausgewählten Säulen haben unterschiedliche Größen.
Empfehlung: Erhöhen Sie die Wiederholungen auf {{ recommendedRepetitions }}.
</v-alert>
7.3 Coverage-Anzeige in Results¶
<v-card title="Sample Coverage">
<v-list>
<v-list-item v-for="pillar in coverage">
Säule {{ pillar.id }}: {{ pillar.coverage }}%
({{ pillar.used }}/{{ pillar.total }})
</v-list-item>
</v-list>
</v-card>
8. Zusammenfassung¶
| Strategie | Fairness | Aufwand | Empfehlung |
|---|---|---|---|
| Proportional | Hoch | Niedrig | Standard |
| Bootstrap | Mittel | Mittel | Konfidenzintervalle |
| Gewichtet | Hoch | Hoch | Finale Reports |
| Round-Robin | Hoch | Mittel | Empfohlen |
Empfehlung: Round-Robin mit repetitions_per_pair >= 3 für robuste Ergebnisse bei unterschiedlich großen Säulen. Die aktuelle Implementierung unterstützt dies bereits.
9. Position-Swap Konsistenz-Analyse (NEU)¶
9.1 Hintergrund¶
Position-Swap Konsistenz ist ein kritisches Qualitätsmaß für LLM Evaluator Evaluationen. Basierend auf: - Zheng et al. (2023): "Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena" - arXiv:2406.07791: "Judging the Judges: Position Bias in Pairwise Assessments"
9.2 Metriken¶
| Metrik | Beschreibung | Zielwert |
|---|---|---|
| Consistency Rate | % der Swap-Paare wo gleicher Thread gewinnt | ≥ 80% (excellent) |
| Primacy Bias | Tendenz, Position A (ersten) zu bevorzugen | < 20% |
| Recency Bias | Tendenz, Position B (letzten) zu bevorzugen | < 20% |
| Likert Stability | Wie stark ändern sich Scores bei Positionswechsel? | Δ ≤ 1 |
9.3 Interpretation¶
Consistency Rate ≥ 80% → "excellent" - Ergebnisse sind zuverlässig
Consistency Rate ≥ 60% → "good" - Akzeptabel, leichte Position Bias
Consistency Rate ≥ 40% → "fair" - Signifikanter Bias, Vorsicht
Consistency Rate < 40% → "poor" - Ergebnisse nicht vertrauenswürdig
9.4 Position Bias Typen¶
Primacy Bias (Position A bevorzugt):
Original: A=Thread1, B=Thread2 → Winner: A (Thread1)
Swapped: A=Thread2, B=Thread1 → Winner: A (Thread2)
→ Unterschiedlicher Thread gewinnt, aber immer Position A
Recency Bias (Position B bevorzugt):
Original: A=Thread1, B=Thread2 → Winner: B (Thread2)
Swapped: A=Thread2, B=Thread1 → Winner: B (Thread1)
→ Unterschiedlicher Thread gewinnt, aber immer Position B
9.5 Likert-Score Stabilität¶
Prüft ob der gleiche Thread ähnliche Scores erhält, unabhängig ob als A oder B:
Thread 123 als Position A: quality=4, empathy=5
Thread 123 als Position B: quality=3, empathy=5
→ quality Δ=1 (stabil), empathy Δ=0 (sehr stabil)
Stabilitäts-Kriterien: - Δ ≤ 1: Stabil - Δ > 1: Instabil (Position beeinflusst Bewertung)
9.6 API Endpoint¶
GET /api/judge/sessions/{id}/position-swap-analysis
Response:
{
"summary": {
"total_swap_pairs": 30,
"consistency_rate": 0.8333,
"consistent_wins": 20,
"consistent_ties": 5,
"inconsistent": 5
},
"position_bias": {
"primacy_count": 2,
"recency_count": 3,
"dominant_bias": "balanced"
},
"likert_stability": {
"quality": {"mean_delta": 0.5, "stability_rate": 0.85},
"empathy": {"mean_delta": 0.3, "stability_rate": 0.92},
...
},
"interpretation": {
"overall_quality": "excellent",
"recommendations": ["Position-swap consistency is acceptable."]
},
"pairs": [
{
"thread_1_id": 123,
"thread_2_id": 456,
"is_consistent": true,
"consistency_type": "consistent_win",
"likert_comparison": {...}
},
...
]
}
9.7 Empfehlungen bei niedrigem Consistency Rate¶
- Majority Voting: Mehrere Evaluationen pro Paar, Mehrheitsentscheidung
- Score Averaging: Likert-Scores über Positionen mitteln
- Tie Annotation: Bei Inkonsistenz als "Tie" werten (PandaLM Ansatz)
- Few-Shot Prompting: Beispiele im Prompt erhöhen Konsistenz
10. Referenzen¶
- Zheng et al. (2023): "Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena"
- arXiv:2406.07791: "Judging the Judges: Position Bias in Pairwise Assessments"
- LMSYS Chatbot Arena: Position Bias Mitigation Strategies
- Bradley-Terry Model für paarweise Vergleiche