Ein Sprachmodell gibt immer Text zurück, der korrekt aussieht. Das ist tückisch: Die Antwort klingt selbstsicher, auch wenn das Feld erfunden ist, die Zahl außerhalb des Bereichs liegt oder der Schlüssel im JSON anders benannt ist als gestern. Wenn diese Ausgabe direkt in die Datenbank, in eine Rechnung oder in ein anderes System gelangt, kann ein einziger verzerrter Datensatz den gesamten Prozess stoppen. Im Folgenden beschreiben wir das Validierungsmuster, das wir anwenden, damit die LLM-Ausgabe wie Daten und nicht wie Hoffnung behandelt werden kann.
Warum „sieht gut aus“ nicht ausreicht
#Rohtext aus dem Modell hat drei Klassen von Fehlern, die getrennt werden müssen, da jede eine andere Abwehr erfordert. Die erste sind Formfehler: fehlendes Komma, abgeschnittener JSON, zusätzlicher Kommentar vor der Klammer, Feld als String statt Zahl. Die zweite sind Inhaltsfehler: strukturell korrektes Objekt, in dem der Wert eine Halluzination ist — erfundene Vertragsnummer, Datum außerhalb des Bereichs, Kategorie, die nicht im Wörterbuch steht. Die dritte sind gefährliche Ausgaben: Versuch der Injektion von Anweisungen, Datenlecks, Inhalte, die dem Benutzer nicht gezeigt werden dürfen.
Die Validierung muss alle drei adressieren. Die Überprüfung des JSON allein erfasst keine Halluzinationen; die Überprüfung von Geschäftsregeln funktioniert nicht, solange der Text überhaupt nicht geparst wird. Deshalb bauen wir sie schichtweise auf.
Form erzwingen: Schema als Vertrag
#Ausgangspunkt ist JSON Schema — eine formale Beschreibung, wie die Ausgabe aussehen soll: welche Felder, welche Typen, welche erforderlich, welche zulässigen Werte (enum). Das Schema erfüllt zwei Rollen gleichzeitig: Es ist Anweisung für das Modell und Vertrag für den Validator. Es gibt zwei Wege, um es durchzusetzen.
| Ansatz | Funktionsweise | Stärken | Einschränkungen |
|---|---|---|---|
| Nativer structured output | Provider garantiert JSON gemäß Schema (constrained decoding) | Keine Formfehler auf der Dekodierungsseite | Nicht jedes Modell/Host unterstützt dies; kann bei komplexen Schemata langsamer sein |
| Prompt-basierter structured output | Schema im Prompt + Validierung auf Anwendungsseite | Funktioniert mit jedem Modell, volle Kontrolle | Modell kann weitschweifig sein oder vom Schema abweichen — Validierung obligatorisch |
In unseren Implementierungen verwenden wir standardmäßig die prompt-basierte Variante mit Validierung: Schema im Prompt und nach Erhalt der Antwort eine harte Überprüfung mit einer JSON-Schema-Validierungsbibliothek. Der Grund ist praktisch — natives Erzwingen mit starrem response_format ist auf einigen Hosts langsam (Sekunden, manchmal Timeouts) und nicht für jedes Modell verfügbar. Wir möchten das Modell wählen können, das am besten für die Aufgabe geeignet ist, nicht das beste für den API-Modus. Wie man das Modell für eine bestimmte Aufgabe auswählt, beschreiben wir im Text über die Auswahl des LLM-Modells.
Unabhängig von der Variante gilt das gleiche Prinzip: Das Schema validiert die Struktur, nicht den Sinn. Lockere Längenbeschränkungen (Modell schreibt ausführlich), strenge Typen und Enums dort, wo der Wert weiter ins System gelangt.
Validierungs- + Reparaturschleife
#Ein einzelner Aufruf trifft nicht immer das Schema — und das ist normal, kein Ausfall. Deshalb führen wir nach der Validierung, wenn sie fehlschlägt, einen kontrollierten Reparaturversuch durch: Wir geben dem Modell seine eigene Ausgabe zusammen mit einer konkreten Fehlermeldung des Validators („Feld kwota muss eine Zahl sein“, „fehlendes erforderliches Feld kategoria“) und bitten um Korrektur. Das reicht normalerweise aus, da das Modell nun präzise Informationen hat, was falsch war.
Die Schleife muss ein hartes Limit haben. In unserer Praxis hat sich ein, maximal zwei Reparaturversuche bewährt — mehr ändert selten etwas, multipliziert aber Kosten und Verzögerung. Nach Ausschöpfung der Versuche raten wir nicht: Die Ausgabe geht in die Fehlerbehandlung (Warteschlange, Mensch in der Schleife, Standardwert), niemals ins Zielsystem. Schematisch:
- Generieren → Ausgabe gemäß Schema im Prompt.
- Validieren → JSON parsen + JSON Schema prüfen + Geschäftsregeln.
- Reparieren → Bei Fehler Modell die Validatormeldung zurückgeben; Validierung wiederholen (Versuchslimit).
- Entscheiden → Erfolg: durchlassen; Misserfolg nach Limit: fail-closed.
Guardrails: Inhalt und Sicherheit
#Das Schema überwacht die Form, aber es sagt nicht, ob die Bestellnummer erfunden ist oder ob das Modell versucht, eine injizierte Anweisung auszuführen. Das ist die Aufgabe von Guardrails — einer Regelschicht, die nach der strukturellen Validierung und oft auch vor dem Modell (am Eingang) arbeitet. Drei Kontrollen, die wir am häufigsten anwenden:
- Grounding von Werten — Werte, die in der Realität existieren müssen (Vertragsnummer, Kategorie, Kunden-ID), werden mit der Wahrheitsquelle verglichen. Ein Feld, das zu keinem Datensatz passt, wird als Halluzination behandelt und abgelehnt, selbst wenn der Typ stimmt.
- Bereichs- und Regelkontrolle — Beträge, Daten, Zahlen müssen innerhalb der Geschäftsgrenzen liegen. Ein Preis außerhalb des Bereichs oder ein Datum in der Vergangenheit für einen zukünftigen Termin ist ein Fehlersignal, keine Daten.
- Ausgabesicherheit — Filter gegen Datenlecks, Injektionsversuche und Inhalte, die nicht gezeigt werden dürfen. Dies ist derselbe Denkansatz wie bei der Sicherheit von KI-Agenten — die Ausgabe des Modells sind unsichere Daten, bis sie überprüft wurden.
Guardrails setzen wir auch dort ein, wo das Modell klassifiziert — das Ergebnis eines Klassifikators muss zu einem geschlossenen Satz von Labels gehören, sonst sendet das Routing von Meldungen die Angelegenheit an einen unbekannten Ort. Wenn die Ausgabe einen firmeninternen GPT auf Wissensbasis oder ein RAG-System speist, schützt dieselbe Disziplin davor, dem Benutzer eine selbstsicher klingende, aber falsche Antwort zu geben.
Wann fail-closed, wann fail-open
#Die wichtigste Designentscheidung: Was tun, wenn die Validierung nach der Reparatur weiterhin fehlschlägt. Fail-closed bedeutet Ablehnung — das System lässt die unsichere Ausgabe nicht durch, sondern eskaliert zum Menschen, gibt einen Fehler zurück oder verwendet einen sicheren Standardwert. Dies ist der Standardmodus überall dort, wo die Folge unumkehrbar oder kostspielig ist: Zahlungen, Änderungen in der Datenbank, an den Kunden gesendete Inhalte, Entscheidungen mit rechtlichen Konsequenzen.
Fail-open (Durchlassen trotz Unsicherheit) erlauben wir nur dort, wo der Fehler günstig und umkehrbar ist und das Fehlen einer Antwort schlimmer als eine unvollkommene Antwort — zum Beispiel ein Vorschlag für ein Tag, das der Mensch ohnehin überprüft. Faustregel: Wenn du die Folgen einer fehlerhaften Ausgabe nicht günstig rückgängig machen kannst, entwirf fail-closed. Wie man mit einem solchen Muster von einem Pilotprojekt zu stabiler Produktion übergeht, entwickeln wir im Text vom KI-Pilotprojekt zur Produktion.
FAQ
#Erledigt structured output allein die Validierung?
#Nein. Nativer structured output sorgt dafür, dass die Ausgabe ein gültiges JSON gemäß Schema ist — das ist ein Formfehler, eine von drei Klassen. Er prüft nicht, ob die Werte wahr oder sicher sind, daher sind Inhaltsvalidierung und Guardrails weiterhin notwendig. Wir behandeln ihn als Fundament, nicht als vollständige Lösung.
Prompt-basierter oder nativer structured output?
#Kommt auf den Host und das Modell an. Nativer gibt Formgarantie, aber nicht jedes Modell unterstützt ihn und er kann bei komplexen Schemata langsamer sein. In der Praxis wählen wir oft prompt-basiert mit harter Validierung auf Anwendungsseite, weil es mit jedem Modell funktioniert und die Kontrolle über die Reparaturschleife behält.
Wie oft sollte man versuchen, die Ausgabe zu reparieren?
#In unserer Praxis ein, maximal zwei Reparaturversuche. Nach Übermittlung einer konkreten Fehlermeldung an das Modell reicht die erste Korrektur meist aus; weitere helfen selten, multiplizieren aber Kosten und Verzögerung. Nach Ausschöpfung des Limits geht die Ausgabe in die Fehlerbehandlung, nicht ins System.
Wie schützt Validierung vor Halluzinationen?
#Das Schema allein schützt nicht — eine Halluzination kann strukturell korrekt sein. Es schützen Guardrails: Vergleich von Werten mit der Wahrheitsquelle (Grounding), Bereichskontrolle und geschlossene Wörterbücher. Wenn ein Feld zu keinem realen Datensatz passt, lehnen wir es ab, unabhängig davon, wie selbstsicher es klingt.
Verlangsamt Validierung das System stark?
#Strukturelle Validierung und Regeln sind günstig — das sind Millisekunden. Die realen Kosten sind ein möglicher Reparaturdurchlauf, also ein zusätzlicher Modellaufruf, und nur wenn die erste Ausgabe nicht durchkam. Dafür erhältst du Vorhersehbarkeit, die unschätzbar ist, wenn die Ausgabe andere Systeme speist.