Produktions-Qualität & Drift: Degradation erkennen, ohne Labels zu haben
Einführung · 8 Abschnitte · ~8 Min Lesezeit · Stand
Das Grundproblem: Betrieb ohne Ground-Truth
Beim Bauen eines LLM-Systems misst du Qualität gegen ein Eval-Set mit bekannten richtigen Antworten. In Produktion hast du das fast nie: Niemand labelt jede Live-Antwort auf Korrektheit. Du siehst Millionen Ausgaben — und weißt bei keiner sicher, ob sie stimmt.
Trotzdem kann die Qualität jederzeit kippen: Nutzer fragen plötzlich anders, ein Index veraltet, ein Deploy rutscht durch, der Provider tauscht still das Modell. Deine Aufgabe im Betrieb ist nicht, Korrektheit zu messen — das kannst du live nicht —, sondern Degradation früh zu erkennen und ihre Ursache einzugrenzen.
Proxy-Signale: Qualität ohne Labels beobachten
Ein Proxy ist ein billiges, deterministisches Signal, das mit Qualität korreliert — ohne selbst Korrektheit zu sein. Es kippt oft, bevor Beschwerden eintreffen, und braucht kein Label und kein zweites Modell.
| Refusal-/Abstain-Rate | Anteil Antworten, die verweigern oder ausweichen — steigt bei ungedecktem Scope |
|---|---|
| Format-Valid-Anteil | Anteil schema-/formatkonformer Antworten (z. B. valides JSON) — bricht bei Generierungs-Störung ein |
| Antwortlänge-Verteilung | sprunghaft kürzer/länger = etwas hat sich am Generierungs-Pfad verschoben |
| Retrieval-Leerquote | Anteil Anfragen ohne brauchbaren Treffer — Frühindikator für ungedeckte Themen |
| Latenz / Fehlerrate | klassische Service-Signale — nötig, aber blind für inhaltliche Qualität |
Proxys sind Frühwarnung, kein Urteil: Sie können ausschlagen ohne echtes Problem (Fehlalarm) oder eine Regression verpassen, die Format und Länge gar nicht berührt. Bestätigt wird ein Verdacht mit einer Stichprobe oder im Eval-Track — nicht vom Proxy allein.
Baseline: ohne Referenz ist „Drift“ undefiniert
Drift heißt: Die aktuelle Verteilung weicht von einem früheren Normalzustand ab. Das ist ein Vergleichsbegriff — ohne festgelegte Referenzverteilung gibt es kein „Drift“, nur eine Zahl ohne Bedeutung.
- Referenz = ein repräsentatives historisches Fenster (saisonal bereinigt) oder ein Shadow-/Holdout-Lauf, gegen das du die Gegenwart vergleichst.
- Absolute Schwelle allein (z. B. „Refusal > 10 %“) ignoriert, was für *dein* System normal ist — mal Dauer-Fehlalarm, mal blinder Fleck.
- Mitlaufendes Kurzfenster (heute vs. gestern) übersieht schleichende Drift: Die Referenz wandert mit der Degradation mit — der Frosch merkt das langsame Kochen nicht.
Input-Drift: meist ändert sich die Welt, nicht dein Modell
Wenn die Qualität sinkt, aber Prompt, Modell und Config unverändert sind und kein Deploy lief, hat sich meist die Eingabe-Verteilung verschoben — nicht das System. Neue Themen (ein frisch gelaunchtes Feature), eine neue Sprache, deutlich längere oder kürzere Anfragen: Das Modell wird mit etwas konfrontiert, wofür Wissensbestand oder Prompt nicht ausgelegt sind.
Erkannt wird Input-Drift, indem du die aktuelle Eingabe-Verteilung gegen die Baseline hältst: Themencluster, Sprachmix, Query-Länge. Ein steigender Refusal- oder Retrieval-Leerquoten-Proxy zeigt oft genau hierhin.
Output-Drift: das Symptom auf der Ausgabe-Seite
Output-Drift ist die Kehrseite: die Ausgabe-Verteilung verschiebt sich — Refusal-Spike, Tonwechsel, Längensprung, weniger valides Format. Entscheidend ist die Kombination mit den Inputs: Verschiebt sich der Output, während die Eingaben nachweislich stabil sind, liegt die Änderung im Generierungs-Pfad.
Output-Drift ist ein Symptom, keine Ursache. Sie sagt dir *dass* sich etwas geändert hat, nicht *was*. Und nicht jede Output-Drift ist schlecht — ein gewollter Prompt-Fix verschiebt die Verteilung ebenfalls. Deshalb: gegen eine Output-Baseline quantifizieren und mit der eigenen Change-Historie verknüpfen.
Stiller Modellwechsel: was du nicht pinnst, kontrolliert ein anderer
Ein Sonderfall der Output-Drift ohne eigenen Deploy: Der Provider aktualisiert das Modell hinter derselben API-Bezeichnung. Gleiche Schnittstelle, anderes Verhalten — dein Produktionsverhalten ändert sich, ohne dass du etwas ausgerollt hast. Dass sich das Verhalten gehosteter Modelle über die Zeit messbar verschiebt, ist dokumentiert.
- Erkennen: eine Output-Baseline auf stabilen Referenz-Inputs laufen lassen — springt sie ohne eigenen Change, ist ein externer Wechsel die naheliegende Erklärung.
- Begegnen: die Modell-Version pinnen statt auf einem
latest-Alias zu fahren. Pinning kauft dir Kontrolle über den Zeitpunkt der Änderung. - Preis: gepinnte Versionen werden irgendwann deprecatet — du musst ohnehin migrieren, nur zu *deinem* Zeitpunkt; und Verbesserungen/Fixes ziehst du bewusst nach, statt sie geschenkt zu bekommen.
Regressions-Triage: „seit gestern schlechter“ — ohne Labels
Der häufigste Alltag: Jemand leitet zwei schlechte Antworten weiter und sagt „der Bot ist schlechter geworden“. Ohne Labels triagierst du in zwei Schritten — erst ob, dann was.
- Signal vs. Anekdote: zeigt die Proxy-/Verteilungskurve gegen Baseline überhaupt einen Trend — oder sind es zwei Einzelfälle?
- Change-Historie zuerst: „Was haben wir zuletzt geändert?“ — eigener Deploy/Config ist am schnellsten falsifizierbar
- Datenquelle / Index: neu gebaut, veraltet, teilweise leer?
- Input-Drift: hat sich die Eingabe-Verteilung verschoben?
- Externer Modellwechsel: seltener, teurer zu prüfen — deshalb zuletzt
Abgrenzung & gleich im Check
Dieses Modul ist reine Laufzeit-Beobachtung: Signale und Drift im laufenden Betrieb erkennen und triagieren. Wie du ein Eval-Set baust, einen LLM-Judge entwirfst, Metriken auswählst oder Offline gegen Online abwägst, lehrt der Track `llmops/evaluation` — hier wird das nicht gedoppelt. Ein Proxy warnt; bestätigt wird eine Regression dort.
Du kennst jetzt die Achsen: Proxy-Metriken, Baseline als Alarm-Voraussetzung, Input-Drift, Output-Drift, stiller Modellwechsel und Regressions-Triage.