Analyse: Wie man aus einem Sprachmodell maschinenlesbare Ausgaben bekommt – und warum „gib JSON zurück“ keine Spezifikation ist
Jedes Produkt, das ein Modell in eine Pipeline einbindet, braucht früher oder später verlässliche strukturierte Ausgaben. Die typischen Fehlerquellen sind gut bekannt, und die Lösungen dafür sind wenig spektakulär. Ein Leitfaden.
Kurze Antwort
Wie bringt man ein Sprachmodell dazu, zuverlässig strukturierte Daten zurückzugeben?
Man nutzt, wo verfügbar, den eingeschränkten Decodier- oder schemabasierten Modus der Plattform, denn er macht fehlerhafte Syntax unmöglich statt nur unwahrscheinlich. Anschließend wird das Schema auf das Modell zugeschnitten: flach gehalten, mit wenigen Pflichtfeldern, expliziten Enums, einer klaren Möglichkeit, Unsicherheit auszudrücken, und ohne Felder, die Rechenoperationen erfordern. Jede Antwort wird gegen das Schema validiert, wobei die semantische Korrektheit – also ob die Werte tatsächlich stimmen und nicht nur formal gültig sind – als eigenständiges Problem behandelt wird, das die Validierung allein nicht löst.
Das Wichtigste
- Schemabasiertes, eingeschränktes Decoding löst das Problem der Syntax, nicht der Bedeutung. Eine Antwort kann perfekt gültiges JSON und trotzdem völlig falsch sein.
- Schemadesign ist Prompt-Design. Jeder Feldname, jeder Enum-Wert und jede Beschreibung ist eine Anweisung, die das Modell liest.
- Geben Sie dem Modell eine legitime Möglichkeit, 'nicht vorhanden' oder 'unsicher' auszudrücken. Ohne diese Option wird ein Pflichtfeld zur Einladung, einen Wert zu erfinden.
- Verlangen Sie vom Modell nie, Summen, Prozentsätze oder Daten zu berechnen, die sich ableiten lassen. Extrahieren Sie die Eingabewerte und rechnen Sie im Code.
- Validieren Sie und fragen Sie bei Bedarf einmal erneut nach, diesmal mit dem Validierungsfehler im Prompt. Eine einzige gezielte Korrekturrunde behebt die meisten verbleibenden Fehler günstiger als eine Wiederholungsschleife.
In dem Moment, in dem ein Sprachmodell nicht mehr für einen Menschen, sondern für ein Programm schreibt, gelten andere Anforderungen. Prosa kann annähernd richtig sein. Ein Feld namens total_amount nicht.
Die meisten Teams machen diese Erfahrung in derselben Reihenfolge. Sie fordern im Prompt JSON an, und es funktioniert. Sie gehen damit in Produktion. Eine Woche später meldet der Parser einen Fehler, weil das Modell das Objekt in einen Codeblock gesetzt, einen freundlichen Satz vorangestellt oder ein überflüssiges Komma am Ende ausgegeben hat. Sie ergänzen eine Bereinigungsfunktion. Es funktioniert. Einen Monat später enthält ein Feld, das null hätte sein sollen, einen plausiblen, aber erfundenen Wert – und überhaupt nichts stürzt ab, was sehr viel schlimmer ist.
Diese beiden Fehler sind grundverschieden. Dass sie miteinander vermengt werden, ist der Grund, warum die Behebung des Problems so lange dauert.
Zwei Probleme unter einem Namen
Syntaktisches Versagen liegt vor, wenn sich die Ausgabe nicht parsen lässt oder nicht dem Schema entspricht. Es ist unübersehbar, tritt unmittelbar zutage und lässt sich vollständig beheben.
Semantisches Versagen liegt vor, wenn sich die Ausgabe einwandfrei parsen lässt, aber inhaltlich falsch ist. Ein mit großer Gewissheit genanntes Datum, das nie im Dokument stand. Eine Kategorie, die zwar zur Aufzählung, aber nicht zum Inhalt passt. Eine Gesamtsumme, die nicht mit ihren Einzelposten übereinstimmt.
Constrained Decoding – die inzwischen von allen großen Plattformen angebotenen Modi mit Schemaerzwingung – beseitigt die erste Kategorie nahezu vollständig. Dabei wird bei jedem Generierungsschritt eingeschränkt, welche Token zulässig sind, sodass keine Ausgabe außerhalb der Grammatik entstehen kann. Gegenüber promptbasierten Aufforderungen ist das ein echter Quantensprung: Solche Aufforderungen sind lediglich Vorschläge, denen das Modell meist folgt. Der Unterschied zeigt sich bei den seltenen Ausreißern: Genau die eine von tausend Anfragen, die früher scheiterte, ist jene, wegen der jemand alarmiert wird.
Für die zweite Kategorie leistet es rein gar nichts, und die psychologische Wirkung birgt ein reales Risiko. Teams, die eine Schemaerzwingung einführen, stellen die Validierung häufig ein, weil die Plattform das Schema „garantiert“. Diese Garantie betrifft die Form. Alle übrigen Fragen – ist dies der richtige Wert, stimmen diese Felder miteinander überein, liegt dieses Datum in einem plausiblen Bereich – bleiben weiterhin Ihre Aufgabe.
Das Schema ist Teil des Prompts
Dies ist die hilfreichste neue Sichtweise auf das Problem – und sie wird regelmäßig übersehen. Das Modell liest das Schema. Feldnamen, Aufzählungswerte, Beschreibungen und Reihenfolge sind allesamt Anweisungen und konkurrieren mit dem System-Prompt um Einfluss.
Das bedeutet: Entscheidungen beim Schemadesign wirken sich auf die Qualität aus.
Benennen Sie Felder so, wie Sie sie einem Menschen beschreiben würden. is_urgent liefert bessere Ergebnisse als flag2. Eine Beschreibung direkt am Feld – „nur dann true, wenn der Kunde eine Frist innerhalb der nächsten 48 Stunden nennt“ – ist häufig wirksamer als derselbe Satz im System-Prompt, weil sie unmittelbar neben der zu treffenden Entscheidung steht.
Verwenden Sie Aufzählungen statt freier Zeichenketten, wann immer der Wertebereich abgeschlossen ist. Ein Freitextfeld category erzeugt eine lange Reihe beinahe synonymer Begriffe, die Ihr nachgelagerter Code auf Dauer normalisieren muss. Eine Aufzählung erzwingt die Entscheidung bereits bei der Generierung.
Halten Sie das Schema flach. Tief verschachtelte Objekte erhöhen sowohl die Wahrscheinlichkeit struktureller Fehler als auch deren Auswirkungen, wenn in einem Zweig etwas schiefläuft. Ist der Gegenstandsbereich tatsächlich hierarchisch, sind zwei Aufrufe häufig zuverlässiger als eine einzige, tief verschachtelte Antwort. Zudem lassen sie sich leichter auswerten, weil erkennbar ist, auf welcher Stufe der Fehler auftrat.
Ordnen Sie die Felder so an, dass die Begründung vor dem Ergebnis steht. Ein Schema, in dem ein Feld wie reasoning oder evidence_quote vor classification erscheint, führt nachweislich zu besseren Klassifizierungen als die umgekehrte Reihenfolge. Das Modell generiert von links nach rechts, und das frühere Feld beeinflusst das spätere. Hier lohnt sich eine kleine Menge generierter Prosa innerhalb einer strukturierten Antwort ausnahmsweise.
Geben Sie dem Modell einen Ausweg
Die mit Abstand häufigste Ursache erfundener Werte ist ein Schema, das keine legitime Alternative zur Erfindung bietet.
Wenn contract_end_date eine verpflichtende, nicht nullable Zeichenkette ist und der Vertrag kein Enddatum nennt, muss das Modell etwas ausgeben. Es wird einen plausiblen Wert erzeugen. Kein Teil der Verarbeitungskette wird Einspruch erheben.
Die Lösung besteht darin, Abwesenheit ausdrückbar zu machen: durch nullable Felder, ein ausdrückliches Aufzählungselement not_stated oder einen separaten booleschen Wert, der die Verwendung des Feldes steuert. In Verbindung mit der klaren Anweisung, dass ein fehlender Wert eine zulässige und erwartete Antwort ist, beseitigt dies einen großen Teil der halluzinierten Feldwerte – und kostet nur eine Zeile im Schema.
Dieselbe Logik gilt für die Konfidenz. Eine confidence-Aufzählung mit drei Werten – hoch, mittel, niedrig – ist nützlicher als ein numerischer Wert. Modelle sind bei der numerischen Selbsteinschätzung schlecht kalibriert, bei groben Kategorien jedoch hinreichend konsistent. Leiten Sie die niedrige Kategorie an einen Menschen weiter, und Sie haben aus einem Genauigkeitsproblem ein Durchsatzproblem gemacht – ein weitaus angenehmeres Problem.
Lassen Sie das Modell nicht rechnen
Ein Schema mit subtotal, tax und total verlangt drei Werte, obwohl einer aus den anderen abgeleitet werden kann. Das Modell wird alle drei ausfüllen, und gelegentlich werden sie einander widersprechen.
Extrahieren Sie die Eingabewerte. Berechnen Sie die abgeleiteten Werte im Code. Dasselbe gilt für Datumsberechnungen, Prozentwerte, Anzahlen und sämtliche Einheitenumrechnungen. Dabei geht es nicht um die Fähigkeiten des Modells. Eine deterministische Berechnung hat eine Fehlerquote von null, eine generierte Berechnung nicht. Es gibt keinen Grund, die zweite zu akzeptieren, wenn die erste verfügbar ist.
Validierung und ein einziger Korrekturversuch
Validieren Sie jede Antwort, auch jene von Endpunkten mit Schemaerzwingung. Scheitert die Validierung, ist ein Korrekturversuch mit Angabe des konkreten Fehlers am wirksamsten, nicht eine blinde Wiederholung. Eine Rückmeldung wie „Das Feld priority muss einen der Werte low, medium oder high enthalten; ausgegeben wurde 'urgent'“ behebt die große Mehrheit der verbleibenden Fehler in einem einzigen zusätzlichen Durchgang.
Beschränken Sie es auf diesen einen Versuch. Unbegrenzte Wiederholungsschleifen verwandeln bei problematischen oder tatsächlich mehrdeutigen Eingaben einen sichtbaren Fehler in unsichtbare Kosten. Zugleich unterdrücken sie genau das Signal, das Sie benötigen: dass etwas an dieser Eingabe nicht zu dem von Ihnen entworfenen Schema passt.
Nach dem Wiederholungsversuch sollte eine deterministische Rückfalllösung greifen: ein zur Prüfung markierter Standarddatensatz, ein regelbasierter Verarbeitungspfad oder eine Warteschlange für die menschliche Bearbeitung. Eine Verarbeitungskette, deren einzige Fehlerbehandlung „noch einmal versuchen“ lautet, verfügt über keine echte Fehlerbehandlung. Das ist ein Konstruktionsfehler, kein Leistungsmerkmal.
Strukturierte Ausgaben evaluieren
Strukturierte Ausgaben lassen sich ungewöhnlich angenehm evaluieren, und Teams sollten dies nutzen.
Da die Ausgabe maschinenlesbar ist, können die meisten Prüfungen exakt erfolgen: Schemakonformität, Zugehörigkeit zu Aufzählungen, Vorhandensein von Pflichtfeldern, feldübergreifende Konsistenz und die Genauigkeit einzelner Felder im Vergleich mit einem annotierten Datensatz. Die Genauigkeit pro Feld ist die entscheidende Kennzahl, nicht die Genauigkeit des gesamten Datensatzes. Wird ein Datensatz als Einheit bewertet, bleibt verborgen, welches Feld sich verschlechtert – und meist ist nur ein Feld betroffen, nicht die gesamte Extraktion.
Beobachten Sie auch den Anteil der Nullwerte. Ein plötzlicher Rückgang nach einer Änderung am Prompt oder Modell deutet häufig darauf hin, dass das Modell begonnen hat, Werte zu erfinden, wo es zuvor keine Angabe machte. Bei einer Prüfung, die ausschließlich gültige Datensätze betrachtet, bleibt dies unsichtbar.
Die unspektakuläre Zusammenfassung
Hier gibt es keinen raffinierten Kunstgriff. Aktivieren Sie Constrained Decoding. Entwerfen Sie das Schema unter der Annahme, dass das Modell es liest – denn genau das tut es. Geben Sie ihm die Möglichkeit, „Ich weiß es nicht“ zu sagen. Lassen Sie Berechnungen im Code durchführen. Validieren Sie trotzdem. Unternehmen Sie einen Korrekturversuch und greifen Sie anschließend auf die Rückfalllösung zurück.
Jede dieser Maßnahmen ist kostengünstig. Zusammen machen sie den Unterschied zwischen einem Modell, das ein Bestandteil Ihres Systems ist, und einem Modell, das darin gelegentlich für Überraschungen sorgt.
Häufige Fragen
- Ist eingeschränktes Decoding dasselbe wie die Aufforderung im Prompt, JSON auszugeben?
- Nein. Eine Aufforderung im Prompt ist ein Vorschlag, dem das Modell meist folgt. Eingeschränktes Decoding begrenzt die an jedem Schritt generierbaren Token so, dass eine Ausgabe außerhalb der Grammatik unmöglich ist. Der Unterschied zeigt sich in den Randfällen, und genau dort liegen die Ausfälle im Produktivbetrieb.
- Warum erfindet das Modell Werte für Felder, die ich als Pflichtfelder markiert habe?
- Weil ein Pflichtfeld ohne zulässigen Leerwert eine Anweisung ist, etwas zu produzieren. Machen Sie das Feld nullable oder fügen Sie einen expliziten Enum-Wert 'not_found' hinzu, dann hören die erfundenen Werte in der Regel auf.
- Sollte ich tief verschachtelte Schemata verwenden?
- Bevorzugen Sie flache Strukturen. Tiefe Verschachtelung erhöht sowohl die Wahrscheinlichkeit struktureller Fehler als auch die Kosten eines Teilausfalls. Wenn der Anwendungsbereich tatsächlich hierarchisch ist, ziehen Sie zwei Aufrufe einer einzigen, tief verschachtelten Antwort vor.
- Wie sollten Wiederholungsversuche ablaufen?
- Ein Korrekturversuch, der den konkreten Validierungsfehler enthält, danach der Rückgriff auf einen deterministischen Pfad oder einen Menschen. Unbegrenzte Wiederholungen machen aus einer schlechten Antwort eine hohe Rechnung und verschleiern das eigentliche Problem.
- Brauche ich noch eine Validierung, wenn die API das Schema garantiert?
- Ja. Die Garantie betrifft die Struktur, nicht die Werte. Enum-Zugehörigkeit, Konsistenz zwischen Feldern, Wertebereiche und referenzielle Prüfungen bleiben weiterhin Ihre Verantwortung.
Quellen
- JSON Schema specification — JSON Schema
- Model Context Protocol — specification — Model Context Protocol
- OpenAPI Specification — OpenAPI Initiative