Du gibst einem Sprachmodell eine Supportmail:
Hallo, seit dem Update können unsere Kunden nichts mehr bestellen. Sobald sie auf „Bezahlen“ klicken, erscheint Fehler 500. Bitte dringend ansehen.
Ein Mensch kann mit einer normalen KI-Antwort gut arbeiten:
Das klingt nach einem kritischen technischen Problem im Checkout. Ich würde das Ticket mit hoher Priorität an den technischen Support weiterleiten.
Für eine Automatisierung ist diese Antwort allerdings ausgesprochen unpraktisch.
Die Software muss nun herausfinden:
Was ist die Kategorie?
Wie hoch ist die Priorität?
Muss das Ticket eskaliert werden?
Welcher Textteil enthält welche Information?
Viel besser wäre eine Ausgabe wie:
{
"category": "checkout_error",
"priority": "high",
"requires_escalation": true
}
Nun muss keine Software die natürliche Sprache der KI erneut interpretieren.
Sie kann direkt weiterarbeiten.
Genau darum geht es bei strukturierten KI-Ausgaben.
Menschen mögen Sprache, Software mag Struktur
Ein Sprachmodell ist hervorragend darin, Sprache zu erzeugen.
Software benötigt dagegen möglichst eindeutige Daten.
Ein Mensch versteht problemlos:
Ich würde die Anfrage als technischen Fehler einstufen. Da der Checkout vollständig ausfällt, scheint mir die Priorität hoch.
Eine Automatisierung arbeitet lieber mit:
{
"type": "technical_error",
"priority": 3
}
Der Unterschied ist grundlegend.
Natürliche Sprache
→ flexibel
→ angenehm für Menschen
→ interpretationsbedürftig
gegen:
Strukturierte Daten
→ vorhersehbar
→ maschinenlesbar
→ direkt weiterverarbeitbar
Sobald eine KI-Ausgabe nicht nur angezeigt, sondern von einem weiteren Programm verarbeitet werden soll, wird diese Unterscheidung wichtig.
Was bedeutet „strukturierte Ausgabe“?
Eine strukturierte Ausgabe folgt einer vorher festgelegten Form.
Zum Beispiel:
Name:
E-Mail:
Kategorie:
Priorität:
Das ist bereits Struktur.
Für Software sind jedoch standardisierte Datenformate praktischer.
Besonders verbreitet ist:
JSON.
JSON erlaubt unter anderem Objekte, Arrays, Strings, Zahlen, Booleans und null. JSON Schema kann zusätzlich definieren, welche Eigenschaften erwartet werden, welche Datentypen erlaubt sind und welche Felder verpflichtend sind. (json-schema.org)
Was ist JSON?
JSON steht für:
JavaScript Object Notation.
Trotz des Namens wird JSON längst unabhängig von JavaScript in praktisch allen möglichen Programmiersprachen und Systemen verwendet.
Ein einfaches Objekt sieht so aus:
{
"name": "Anna",
"age": 42,
"active": true
}
Das Objekt besitzt drei Felder.
name
→ String
age
→ Zahl
active
→ Boolean
Software kann diese Werte direkt verarbeiten.
JSON ist Text – aber Text mit festen Regeln
Eine normale KI-Antwort könnte lauten:
Anna ist 42 Jahre alt und ihr Benutzerkonto ist aktiv.
Der Informationsgehalt ist nahezu identisch.
Maschinell ist diese Variante aber wesentlich schwieriger zu verarbeiten.
Bei JSON weiß die Software:
name
→ Anna
age
→ 42
active
→ true
Kein weiteres Sprachverständnis ist notwendig.
JSON-Objekte bestehen aus Schlüssel und Wert
Beispiel:
{
"category": "support"
}
category ist der Schlüssel.
support ist der Wert.
Mehrere Werte können kombiniert werden:
{
"category": "support",
"priority": "high",
"customer_id": 4711
}
Damit lassen sich Informationen sehr eindeutig benennen.
Arrays speichern mehrere Elemente
Ein Modell soll mehrere Probleme aus einer Nachricht extrahieren.
Dann könnte die Ausgabe lauten:
{
"issues": [
"checkout_error",
"payment_failure",
"server_error"
]
}
Das Feld issues enthält ein Array.
Arrays eignen sich für:
mehrere Produkte,
mehrere Personen,
mehrere Aufgaben,
mehrere Suchergebnisse,
mehrere Kategorien.
Strukturen können verschachtelt sein
Zum Beispiel:
{
"customer": {
"id": 4711,
"name": "Anna Beispiel"
},
"ticket": {
"category": "checkout_error",
"priority": "high"
}
}
So können komplexe Informationen in logisch getrennte Bereiche gegliedert werden.
Warum reicht „Antworte als JSON“ nicht aus?
Man könnte dem Sprachmodell einfach sagen:
Antworte ausschließlich als JSON.
Das funktioniert häufig überraschend gut.
Aber „häufig“ ist für einen automatisierten Produktionsprozess nicht unbedingt ausreichend.
Das Modell könnte beispielsweise erzeugen:
{
"category": "support",
"priority": "high"
}
Beim nächsten Fall:
{
"type": "support",
"urgency": "urgent"
}
Beide Antworten sind gültiges JSON.
Aber die Struktur hat sich verändert.
Die nachfolgende Software erwartet vielleicht:
category
priority
und findet stattdessen:
type
urgency
Der Workflow bricht.
Gültiges JSON ist noch kein gültiges Datenmodell
Das ist eine der wichtigsten Unterscheidungen.
Folgende Ausgabe ist syntaktisch vollkommen gültiges JSON:
{
"pizza": "Donnerstag",
"elefant": 892
}
Sie hilft unserem Ticketsystem trotzdem überhaupt nicht.
Wir brauchen also zwei unterschiedliche Anforderungen:
1. Ist die Ausgabe technisch gültiges JSON?
2. Entspricht die Ausgabe der erwarteten Struktur?
Genau für den zweiten Punkt brauchen wir ein Schema.
Was ist ein Schema?
Ein Schema beschreibt, wie erlaubte Daten aussehen müssen.
Für unser Supportticket könnte die Regel lauten:
Die Ausgabe muss ein Objekt sein.
Es muss enthalten:
category
priority
requires_escalation
category muss Text sein.
priority muss einer definierten Auswahl entsprechen.
requires_escalation muss true oder false sein.
Andere Felder sind nicht erlaubt.
Menschen können diese Regeln lesen.
Software benötigt eine formale Beschreibung.
Dafür wird häufig JSON Schema verwendet.
Was ist JSON Schema?
JSON Schema ist eine Sprache zur Beschreibung und Validierung von JSON-Strukturen.
Ein vereinfachtes Schema könnte so aussehen:
{
"type": "object",
"properties": {
"category": {
"type": "string"
},
"priority": {
"type": "string"
},
"requires_escalation": {
"type": "boolean"
}
},
"required": [
"category",
"priority",
"requires_escalation"
]
}
JSON Schema verwendet unter anderem type, properties und required, um Datentypen, erlaubte Eigenschaften und verpflichtende Felder zu beschreiben. (json-schema.org)
type legt den Datentyp fest
Zum Beispiel:
{
"type": "string"
}
erwartet Text.
{
"type": "integer"
}
erwartet eine Ganzzahl.
{
"type": "boolean"
}
erwartet:
true
oder:
false
JSON Schema unterscheidet grundlegende Typen wie Objekte, Arrays, Strings, Zahlen, Booleans und null; für Zahlen kann zusätzlich zwischen allgemeinen Zahlen und Ganzzahlen unterschieden werden. (json-schema.org)
properties beschreibt die Felder eines Objekts
Zum Beispiel:
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "integer"
}
}
}
Damit sagen wir:
Ein Objekt darf die Eigenschaften:
name
age
besitzen.
Aber damit sind sie noch nicht automatisch verpflichtend.
required definiert Pflichtfelder
Dazu dient:
{
"required": [
"name",
"age"
]
}
Fehlt eines dieser Felder, entspricht das JSON nicht dem Schema. (JSON Schema Tour)
Das ist für Automatisierungen sehr wichtig.
Die nachfolgende Software kann sich darauf verlassen, dass bestimmte Daten vorhanden sein müssen – sofern die verwendete Structured-Output-Implementierung das Schema tatsächlich erzwingt beziehungsweise die Ausgabe erfolgreich validiert wurde.
enum beschränkt erlaubte Werte
Angenommen, priority darf nur sein:
low
normal
high
critical
Dann können wir das formal festlegen:
{
"type": "string",
"enum": [
"low",
"normal",
"high",
"critical"
]
}
JSON Schema verwendet enum, um einen Wert auf eine definierte Menge zulässiger Optionen zu beschränken. (json-schema.org)
Das ist wesentlich robuster als die Anweisung:
Verwende bitte eine vernünftige Prioritätsbezeichnung.
Ohne enum kann das Modell Varianten erzeugen
Zum Beispiel:
high
oder:
urgent
oder:
very_high
oder:
important
Für einen Menschen bedeuten diese Werte ungefähr dasselbe.
Für Software sind es vier verschiedene Strings.
Eine geschlossene Werteliste beseitigt diese Mehrdeutigkeit.
Erlaubte Werte sollten stabile Maschinenbegriffe sein
Für die Anzeige kann später aus:
checkout_error
werden:
Fehler im Checkout
oder:
Bestellabschluss gestört
Der interne Wert sollte dagegen stabil bleiben.
So kann die Oberfläche verändert oder übersetzt werden, ohne die Workflowlogik umzubauen.
Maschinenwerte und Anzeigetexte sollten getrennt werden
Schlecht:
{
"priority": "Hohe Priorität – bitte möglichst sofort bearbeiten"
}
Besser:
{
"priority": "high"
}
Die Benutzeroberfläche entscheidet anschließend:
high
→ Hohe Priorität
Das reduziert unnötige Abhängigkeiten zwischen KI und Oberfläche.
additionalProperties kann unerwartete Felder verhindern
Ein Sprachmodell könnte auf die Idee kommen:
{
"category": "support",
"priority": "high",
"requires_escalation": true,
"helpful_comment": "Das sieht wirklich dringend aus."
}
Für Menschen nett.
Für Software vielleicht unerwünscht.
JSON Schema kann mit:
{
"additionalProperties": false
}
festlegen, dass nur ausdrücklich definierte Eigenschaften erlaubt sind. Ohne diese Einschränkung sind zusätzliche Eigenschaften im allgemeinen JSON-Schema-Verhalten grundsätzlich möglich. (JSON Schema Tour)
Strikte Schemas reduzieren Überraschungen
Ein Schema könnte deshalb lauten:
{
"type": "object",
"properties": {
"category": {
"type": "string",
"enum": [
"support",
"sales",
"billing",
"other"
]
},
"priority": {
"type": "string",
"enum": [
"low",
"normal",
"high",
"critical"
]
},
"requires_escalation": {
"type": "boolean"
}
},
"required": [
"category",
"priority",
"requires_escalation"
],
"additionalProperties": false
}
Nun ist sehr präzise beschrieben, welche Form das Ergebnis besitzen soll.
null ist ein ausgesprochen wichtiger Wert
Angenommen, eine E-Mail enthält keine Kundennummer.
Eine schlechte KI könnte versuchen:
{
"customer_id": 4711
}
obwohl 4711 nirgendwo steht.
Viel besser:
{
"customer_id": null
}
null bedeutet:
Es liegt kein Wert vor.
Das ist keine Schwäche.
Es ist eine wichtige Information.
„Nicht vorhanden“ ist besser als „plausibel erfunden“
Eine robuste Datenstruktur muss fehlende Information zulassen.
Beispiel:
{
"invoice_number": null,
"amount": null,
"currency": null
}
Die nachfolgende Software kann nun entscheiden:
invoice_number = null
↓
manuelle Prüfung
Eine halluzinierte Rechnungsnummer könnte dagegen den falschen Datensatz öffnen.
Das Schema sollte Unsicherheit modellieren
Statt die KI zu zwingen, immer eine Kategorie auszuwählen:
{
"category": "other"
}
könnte ein Modell enthalten:
{
"category": null,
"requires_review": true
}
Nun kann ein schwieriger Fall korrekt eskaliert werden.
Diese Eigenschaft ist für produktive KI-Systeme sehr wertvoll.
Ein Datenmodell sollte reale Fehlerfälle abbilden
Wenn ein Workflow fünf mögliche Zustände besitzt, das Schema aber nur vier darstellen kann, zwingt man das Modell möglicherweise zu einer falschen Auswahl.
Gutes Schema-Design beginnt deshalb nicht beim JSON.
Sondern bei der Frage:
Welche Zustände können in der Realität tatsächlich auftreten?
Was ist JSON Mode?
Einige KI-APIs bieten oder boten einen speziellen JSON-Modus.
Dabei wird stärker sichergestellt, dass die Ausgabe syntaktisch gültiges JSON ist.
Das löst jedoch nicht automatisch das Schemaproblem.
OpenAI unterscheidet ausdrücklich zwischen älterem JSON Mode und Structured Outputs: JSON Mode zielt auf gültiges JSON, garantiert aber nicht, dass eine konkrete gewünschte JSON-Schema-Struktur eingehalten wird. Für schemafeste Ausgaben wird bei unterstützten Modellen json_schema beziehungsweise Structured Outputs empfohlen. (OpenAI)
Das ist die entscheidende Unterscheidung:
JSON Mode
→ gültiges JSON
gegen:
Structured Outputs
→ gültiges JSON nach vorgegebenem Schema
Ein Beispiel zeigt den Unterschied
Gewünschtes Schema:
{
"category": "support",
"priority": 3
}
JSON Mode könnte erzeugen:
{
"ticket_category": "support",
"urgency": "high"
}
Technisch korrektes JSON.
Falsches Datenmodell.
Structured Outputs sollen dagegen die Ausgabe an die vorgegebene Schemaform binden. (OpenAI)
Was sind Structured Outputs?
Der Begriff wird für Verfahren verwendet, bei denen ein Modell nicht nur gebeten wird, eine Struktur einzuhalten, sondern das Ausgabesystem diese Struktur wesentlich stärker erzwingt.
Bei OpenAI können beispielsweise JSON Schemas für strukturierte Antworten beziehungsweise Funktionsargumente verwendet werden; mit strikter Schemaeinhaltung sollen die erzeugten Daten der unterstützten Schemaform entsprechen. (OpenAI)
Das ist ein großer Unterschied zu:
Prompt:
"Bitte mach keinen Fehler beim JSON."
Denn nun existiert zusätzlich eine technische Begrenzung der möglichen Ausgabe.
Wie kann eine Ausgabe technisch begrenzt werden?
Ein Sprachmodell erzeugt normalerweise Token für Token.
Ohne weitere Beschränkung kann es theoretisch nach:
{
"priority":
viele verschiedene Fortsetzungen erzeugen.
Bei constrained decoding werden dagegen nur Fortsetzungen zugelassen, die zum vorgegebenen Ausgabeformat passen.
OpenAI beschreibt seine Structured-Outputs-Implementierung beispielsweise so, dass das Schema in eine Grammatik überführt wird und bei jedem Generationsschritt Tokens ausgeschlossen werden, die an dieser Stelle zu einer ungültigen Struktur führen würden. (OpenAI)
Das Modell bekommt gewissermaßen Leitplanken
Ohne strukturelle Einschränkung:
mögliches nächstes Token
→ praktisch gesamtes Modellvokabular
Mit einem Schema kann die zulässige Menge abhängig von der aktuellen Position stark eingeschränkt sein.
Beispiel:
{
"priority": "
Wenn das Schema nur erlaubt:
low
normal
high
critical
muss die Generierung innerhalb dieses erlaubten Raums bleiben.
Das macht Ausgaben wesentlich besser für Software geeignet.
Ein Schema verbessert die Form – nicht automatisch den Inhalt
Das ist die wichtigste Grenze strukturierter Ausgaben.
Folgende Antwort kann perfekt zum Schema passen:
{
"category": "billing",
"priority": "high",
"requires_escalation": false
}
Aber vielleicht handelte die ursprüngliche Nachricht eindeutig von einem Loginproblem.
Dann ist:
die Struktur korrekt
und:
der Inhalt falsch.
OpenAI weist bei Structured Outputs ausdrücklich darauf hin, dass schemafeste Ausgabe nicht alle Modellfehler verhindert; Werte innerhalb der Struktur können weiterhin inhaltlich falsch sein. (OpenAI)
Schema-Konformität ist keine Faktenprüfung
Das müssen wir sauber trennen.
Schema Validation
→ Hat die Ausgabe die richtige Form?
Faktenvalidierung
→ Sind die Werte tatsächlich richtig?
Beides ist notwendig, wenn Fehler Folgen haben können.
Ein JSON Schema kann keine Wahrheit erzwingen
Schema:
{
"age": {
"type": "integer"
}
}
Antwort:
{
"age": 983
}
Technisch gültig.
Vielleicht faktisch absurd.
Schema bedeutet nur:
age muss eine Ganzzahl sein.
Nicht:
Das Alter muss tatsächlich zur Person passen.
Fachliche Regeln gehören teilweise zusätzlich in Validierungscode
Angenommen, ein Bestellrabatt darf sein:
0 bis 100 Prozent
Das Schema kann Werte einschränken.
Aber vielleicht lautet eine Geschäftsregel:
Über 30 Prozent braucht es eine Freigabe.
Diese Regel sollte nicht allein vom Sprachmodell abhängen.
KI
→ Rabattwert extrahieren
anschließend:
Software
→ rabatt > 30?
→ Freigabe erforderlich
Klassische Software bleibt für harte Regeln die bessere Instanz.
Structured Outputs machen probabilistische KI nicht deterministisch
Das Modell darf vielleicht nur vier Kategorien erzeugen.
Welche davon es auswählt, bleibt eine Modellentscheidung.
Ausgabeform
→ stark eingeschränkt
aber:
inhaltliche Klassifikation
→ weiterhin probabilistisch
Das ist ein grundlegendes Architekturprinzip.
Darum sollte man strukturierte Ausgaben validieren
Selbst wenn eine API strikte Structured Outputs unterstützt, sollte die Anwendung weiterhin prüfen:
Kam eine normale Modellantwort zurück?
Wurde die Generierung vollständig abgeschlossen?
Trat ein Fehler auf?
Gab es einen speziellen Ablehnungs- oder Ausnahmezustand?
Sind fachliche Werte plausibel?
Bei OpenAI können beispielsweise Refusals und vorzeitig beendete Generierungen eigene Zustände darstellen, die eine Anwendung gesondert behandeln muss. (OpenAI)
Die Software sollte niemals blind vertrauen
Schlecht:
LLM
↓
JSON
↓
direkt Datenbank überschreiben
Besser:
LLM
↓
Structured Output
↓
technische Validierung
↓
fachliche Validierung
↓
Berechtigung
↓
Aktion
Je höher der mögliche Schaden, desto mehr Kontrollschichten sind sinnvoll.
JSON Parsing ist die erste Prüfung
Wenn man lediglich normalen Text mit JSON erwartet, muss zunächst geprüft werden:
Kann die Ausgabe überhaupt als JSON gelesen werden?
Zum Beispiel:
parse()
schlägt fehl.
Dann darf der Workflow nicht so tun, als wäre alles okay.
Danach folgt Schema Validation
Nehmen wir:
{
"category": "support"
}
Das JSON ist syntaktisch gültig.
Unser Schema verlangt aber zusätzlich:
priority
requires_escalation
Schema Validation schlägt daher fehl.
Das ist genau ihr Zweck.
Danach folgt fachliche Validierung
Ausgabe:
{
"category": "support",
"priority": "critical",
"requires_escalation": false
}
Technisch perfekt.
Aber vielleicht gilt intern:
priority = critical
→ requires_escalation muss true sein
Diese Geschäftsregel kann die Software zusätzlich prüfen.
Damit entstehen drei unterschiedliche Ebenen
Ebene 1
Syntax
→ gültiges JSON?
Ebene 2
Schema
→ richtige Felder und Datentypen?
Ebene 3
Business Rules
→ fachlich zulässige Kombination?
Das ist ein sehr robuster Ansatz.
Eine vierte Ebene kann Quellenprüfung sein
Das Modell extrahiert:
{
"invoice_total": 1843.17
}
Das System kann anschließend prüfen:
Steht dieser Betrag tatsächlich auf der Rechnung?
Bei kritischen Daten ist das wesentlich stärker als:
Die KI scheint sicher zu sein.
Strukturierte Ausgaben erleichtern genau solche Prüfungen
In einem Fließtext:
Die Rechnung scheint sich auf einen Gesamtbetrag von 1.843,17 Euro zu belaufen.
müsste man zuerst wieder den Wert extrahieren.
Bei:
{
"invoice_total": 1843.17
}
kann normale Software sofort arbeiten.
Das ist einer der größten Vorteile.
Strukturierte Ausgaben machen KI zu einer Softwarekomponente
Ohne Struktur:
Software
↓
LLM
↓
Text für Menschen
Mit strukturierter Ausgabe:
Software
↓
LLM
↓
definierte Daten
↓
Software
Nun kann das Sprachmodell mitten in einer normalen Verarbeitungskette arbeiten.
Ein typischer n8n-Workflow
Zum Beispiel:
Neue E-Mail
↓
LLM klassifiziert
↓
Structured Output
↓
Switch
│
├── support
├── sales
├── billing
└── other
Die KI interpretiert die unstrukturierte Nachricht.
n8n führt anschließend deterministische Aktionen aus.
Das ist eine sehr natürliche Arbeitsteilung.
Beispiel: automatische E-Mail-Sortierung
Eingabe:
Hallo, ich habe die Rechnung 2026-481 doppelt bezahlt. Können Sie mir den zweiten Betrag zurücküberweisen?
Gewünschte Ausgabe:
{
"category": "billing",
"subcategory": "duplicate_payment",
"invoice_number": "2026-481",
"priority": "normal",
"requires_human_review": true
}
Danach:
category = billing
↓
Buchhaltung
requires_human_review = true
↓
keine automatische Rückzahlung
Das Modell versteht Sprache.
Die Software kontrolliert den Prozess.
Beispiel: Content-Workflow
Ein Artikelbriefing wird analysiert.
Ausgabe:
{
"topic": "Core Web Vitals",
"content_type": "knowledge_article",
"primary_intent": "informational",
"required_sections": [
"LCP",
"INP",
"CLS"
],
"fact_check_required": true
}
Nun können unterschiedliche Prozessschritte automatisiert werden.
fact_check_required = true
↓
Rechercheworkflow starten
Beispiel: interne Verlinkung
Ein Modell erhält einen Absatz und eine Liste erlaubter Linkziele.
Ausgabe:
{
"links": [
{
"target_id": 172,
"anchor": "Caching",
"relevance": "high"
},
{
"target_id": 183,
"anchor": "Core Web Vitals",
"relevance": "medium"
}
]
}
Die KI muss keine URL erfinden.
Sie wählt nur vorhandene IDs.
Die Software setzt anschließend die echte URL ein.
IDs sind oft besser als vom Modell erzeugte URLs
Schlecht:
{
"url": "/wissen/wordpress-cache-richtig-optimal-erklart/"
}
Vielleicht existiert diese URL nicht.
Besser:
{
"target_id": 172
}
Die Datenbank weiß:
172
→ /wissen/caching/
Damit wird technische Wahrheit nicht vom Sprachmodell erfunden.
Dasselbe gilt für Benutzer, Produkte und Dokumente
Wenn das Modell aus vorgegebenen Datensätzen wählen soll, können interne IDs verwendet werden.
{
"product_id": 8172
}
statt:
{
"product_name": "Super Backup Professional Plus 2026"
}
Die exakte Bezeichnung kann die Datenbank liefern.
Strukturierte Ausgaben sind hervorragend für Extraktion
Ein Vertrag enthält:
Vertragsbeginn.
Laufzeit.
Kündigungsfrist.
Vertragspartner.
Das Modell soll nicht bewerten.
Nur extrahieren.
{
"start_date": "2026-01-01",
"duration_months": 24,
"notice_period_days": 90,
"party_a": "...",
"party_b": "..."
}
Die strukturierten Werte können anschließend separat geprüft und gespeichert werden.
Extraktion und Bewertung sollten häufig getrennt werden
Stufe 1:
Dokument
↓
Fakten extrahieren
Stufe 2:
Fakten
↓
Regeln / Analyse
Das ist oft robuster als ein einzelner Prompt:
Lies den Vertrag, interpretiere alles und entscheide, was wir tun sollen.
Strukturierte Daten schaffen überprüfbare Zwischenzustände
Nach Stufe 1 kann ein Mensch sehen:
{
"notice_period_days": 90
}
Ist das korrekt?
Erst dann läuft die nächste Stufe.
Damit lassen sich Fehler wesentlich leichter lokalisieren.
Das ist ein wichtiger Unterschied zu einem Mega-Prompt
Mega-Prompt:
Dokument
↓
LLM
↓
endgültige Entscheidung
Fehler am Ende.
Warum?
Extraktion falsch?
Regel falsch?
Interpretation falsch?
Unklar.
Modularer Workflow:
Dokument
↓
Extraktion JSON
↓
Validierung
↓
Entscheidung
↓
Aktion
Jeder Schritt ist überprüfbar.
Gute Schemas sollten klein und klar sein
Man kann theoretisch ein gigantisches Schema mit hunderten Feldern bauen.
Das ist nicht automatisch sinnvoll.
Je komplexer die Struktur:
desto schwieriger wird die Aufgabe.
Ein Modell sollte nur Informationen erzeugen müssen, die der nächste Schritt tatsächlich benötigt.
Ein hilfreiches Prinzip lautet
Keine Felder auf Vorrat.
Wenn der Workflow nicht braucht:
customer_mood
sollte das Modell es nicht zwingend beurteilen.
Jedes zusätzliche Feld ist:
zusätzliche Modellarbeit,
zusätzliche Fehlerchance,
zusätzliche Wartung.
Schemas sind Schnittstellenverträge
Ein guter Vergleich ist eine API.
System A sagt:
Ich liefere dir immer diese Felder in diesen Datentypen.
System B kann darauf aufbauen.
Das Schema wird damit zu einem Vertrag zwischen KI und Software.
LLM
↓
Schema
↓
Anwendung
Wenn dieser Vertrag stabil ist, können beide Seiten unabhängig weiterentwickelt werden.
Schema-Versionierung wird deshalb wichtig
Heute:
ticket-schema-v1
mit:
category
priority
Später:
ticket-schema-v2
zusätzlich:
requires_review
Bestehende Workflowkomponenten erwarten vielleicht weiterhin v1.
Darum sollte ein Schema nicht unbemerkt verändert werden.
Breaking Changes gibt es auch bei KI-Schemas
Beispiel:
Alt:
{
"priority": "high"
}
Neu:
{
"priority": 3
}
Inhaltlich vielleicht sinnvoll.
Technisch hat sich der Datentyp geändert.
Bestehende Software kann brechen.
Ein Schema ist damit genauso versionswürdig wie eine normale API.
Maschinenwerte sollten langfristig stabil bleiben
Kategorie heute:
customer_service
Morgen möchte Marketing lieber:
Kundenbetreuung
Der interne Maschinenwert muss deshalb nicht geändert werden.
Darstellung und technische Schnittstelle sollten getrennt bleiben.
Schema-Feldnamen sollten eindeutig sein
Schlecht:
{
"value": 17
}
Was ist value?
Besser:
{
"delivery_delay_days": 17
}
Ein Schema sollte auch nach sechs Monaten noch verständlich sein.
Einheiten gehören in die Felddefinition
Schlecht:
{
"duration": 5
}
Fünf was?
Sekunden?
Minuten?
Tage?
Besser:
{
"duration_minutes": 5
}
oder:
{
"duration": {
"value": 5,
"unit": "minutes"
}
}
Strukturierte Ausgaben zwingen zu genau der Präzision, die automatisierte Prozesse brauchen.
Datumsformate sollten vereinheitlicht werden
Menschen schreiben:
9.8.26
09/08/26
August 9
9. August 2026
Software sollte möglichst ein definiertes Format erhalten.
Zum Beispiel:
{
"date": "2026-08-09"
}
Die Anzeige kann später wieder lokal formatiert werden.
Geld braucht Betrag und Währung
Schlecht:
{
"price": "49,90"
}
Besser:
{
"amount": 49.90,
"currency": "EUR"
}
Nun weiß die Software:
Wert und Einheit sind getrennt.
Prozentangaben brauchen ebenfalls klare Semantik
{
"discount": 0.2
}
Bedeutet das:
0,2 Prozent?
Oder:
20 Prozent?
Besser:
{
"discount_percent": 20
}
oder ein klar dokumentiertes 0-bis-1-Schema.
Eindeutigkeit ist wichtiger als Kürze.
Booleans sollten echte Booleans sein
Schlecht:
{
"urgent": "yes"
}
Dann kommen vielleicht später:
yes
true
ja
urgent
1
Besser:
{
"urgent": true
}
Nun besitzt die Software exakt zwei reguläre Zustände:
true
false
Wenn zusätzlich „unbekannt“ benötigt wird, kann das Datenmodell null vorsehen.
Drei Zustände sind manchmal besser als zwei
Zum Beispiel:
true
→ bestätigt
false
→ ausdrücklich verneint
null
→ nicht bestimmbar
Das ist semantisch wesentlich sauberer als:
false
für:
Ich weiß es nicht.
Confidence-Felder sind verführerisch – aber problematisch
Man könnte die KI bitten:
{
"category": "billing",
"confidence": 0.93
}
Das sieht wissenschaftlich aus.
Aber was bedeutet:
0.93
genau?
Ist das ein kalibrierter Wahrscheinlichkeitswert?
Oder nur eine vom Modell erzeugte Zahl?
Ohne entsprechende Evaluation sollte ein selbstberichteter Confidence-Wert nicht wie eine objektive Fehlerwahrscheinlichkeit behandelt werden.
Bessere Unsicherheitssignale können aus dem System kommen
Zum Beispiel:
Keine passende Quelle gefunden.
Zwei Quellen widersprechen sich.
Pflichtinformation fehlt.
Modelloutputs verschiedener Durchläufe widersprechen sich.
Retrievalscore schwach.
Dann kann normale Logik entscheiden:
{
"requires_human_review": true
}
Das ist häufig belastbarer als eine frei erfundene Konfidenzzahl.
Freitext kann innerhalb strukturierter Ausgaben trotzdem sinnvoll sein
Structured Output bedeutet nicht:
Jedes Feld muss eine Zahl oder Kategorie sein.
Zum Beispiel:
{
"category": "support",
"priority": "high",
"summary": "Checkout schlägt seit dem letzten Update mit Serverfehler 500 fehl."
}
Das Feld summary enthält natürlichen Text.
Die übergeordnete Struktur bleibt trotzdem maschinenlesbar.
Struktur und Sprache können gemeinsam existieren
Ein hervorragendes Datenmodell kann enthalten:
{
"status": "needs_review",
"reasons": [
"invoice_number_missing",
"amount_ambiguous"
],
"human_summary": "In der Nachricht werden zwei Beträge genannt, aber keine Rechnungsnummer."
}
Die ersten Felder sind ideal für Software.
Das letzte hilft Menschen.
Arrays brauchen klare Elementstrukturen
Beispiel:
{
"tasks": [
{
"title": "Kunden zurückrufen",
"owner": "sales",
"due_date": "2026-08-10"
},
{
"title": "Rechnung prüfen",
"owner": "billing",
"due_date": null
}
]
}
Damit können beliebig viele Aufgaben nach demselben Muster ausgegeben werden.
Leere Liste und fehlendes Feld sind nicht dasselbe
Keine Aufgaben vorhanden:
{
"tasks": []
}
ist eindeutig.
Fehlt:
tasks
komplett, kann das bedeuten:
Das Modell hat das Feld vergessen.
Oder:
Es gab keine Aufgaben.
Darum sind Pflichtfelder häufig sinnvoll, selbst wenn ihr Wert leer sein darf.
Strukturierte Ausgaben helfen beim Retry-Handling
Ohne Schema:
KI-Antwort nicht parsebar.
Workflow weiß nicht genau warum.
Mit Validierung:
Schemafehler:
priority missing
Nun kann die Anwendung gezielt reagieren.
Zum Beispiel:
Versuch 1
↓
ungültig
↓
einmal erneut anfordern
↓
weiterhin ungültig
↓
manuelle Queue
Retries sollten allerdings begrenzt sein.
Endlosschleifen sind keine Fehlerbehandlung
Schlecht:
solange JSON ungültig
→ Modell erneut fragen
Wenn die Aufgabe grundsätzlich nicht lösbar ist, entstehen:
Kosten,
Latenz,
Endlosschleifen.
Besser:
maximal 2 Versuche
↓
danach definierter Fehlerzustand
Fehler sollten selbst strukturiert sein
Ein Workflow kann beispielsweise unterscheiden:
{
"status": "success",
"data": {
"category": "billing"
}
}
oder:
{
"status": "insufficient_information",
"missing_fields": [
"invoice_number"
]
}
Damit lässt sich Scheitern genauso sauber verarbeiten wie Erfolg.
Allerdings sollte nicht jeder technische Providerfehler ins Modell-Schema gepresst werden
Es gibt einen Unterschied zwischen:
Die KI kann den Inhalt nicht bestimmen.
und:
Die API war nicht erreichbar.
Der zweite Fehler stammt aus der Infrastruktur.
Er sollte von der Anwendung behandelt werden.
Nicht vom Sprachmodell erfunden werden.
Geschäftliche und technische Fehler sollten getrennt bleiben
LLM-Ergebnis:
insufficient_information
gegen:
HTTP/API-Fehler:
timeout
oder:
Schema Parser:
invalid response
Diese Ebenen brauchen unterschiedliche Reaktionen.
Function Calling verwendet ebenfalls strukturierte Argumente
Strukturierte Ausgaben werden besonders interessant, wenn ein Modell ein Werkzeug aufrufen soll.
Statt:
Bitte sende Anna eine E-Mail mit dem Betreff Rechnung.
kann das Modell strukturierte Argumente erzeugen:
{
"recipient": "anna@example.com",
"subject": "Rechnung",
"body": "..."
}
Die eigentliche E-Mail-Funktion erhält diese Daten.
Function Calling verbindet Sprachmodelle mit externen Funktionen und nutzt dafür definierte Parameter; bei OpenAI werden diese Parameter über ein Schema beschrieben, und strikte Structured Outputs können die erzeugten Funktionsargumente an dieses Schema binden. (OpenAI Help Center)
Das Modell ruft dabei nicht zwingend selbst die Funktion aus
Architektonisch passiert häufig:
Nutzer
↓
LLM entscheidet:
Tool X mit Argumenten Y
↓
Anwendung prüft
↓
Anwendung führt Tool aus
Das ist ein wichtiger Sicherheitsunterschied.
Das Modell schlägt eine Aktion in strukturierter Form vor.
Software kontrolliert die tatsächliche Ausführung.
Beispiel Wettertool
Schema verlangt:
{
"location": "string",
"date": "string"
}
Das Modell erzeugt:
{
"location": "Wien",
"date": "2026-08-10"
}
Das Wettertool erhält genau diese Parameter.
Das Sprachmodell muss keine URL bauen und keine API-Syntax erfinden.
Beispiel Datenbankabfrage
Nutzer:
Zeige mir alle offenen Rechnungen von Kunde 4711.
Statt dem Sprachmodell direkten SQL-Zugriff zu geben:
{
"customer_id": 4711,
"status": "open"
}
Eine kontrollierte Funktion übersetzt diese Werte in eine sichere Datenbankabfrage.
Das ist erheblich besser als:
LLM, erzeuge beliebiges SQL und führe es direkt auf Produktion aus.
Strukturierte Toolargumente sind ein Sicherheitsgewinn – aber keine vollständige Sicherheit
Auch gültige Argumente können unerwünscht sein.
{
"customer_id": 4711,
"action": "delete"
}
Wenn delete laut Schema erlaubt ist, ist die Struktur korrekt.
Darum braucht die Software zusätzlich:
Berechtigungsprüfung.
Freigabe.
Geschäftslogik.
Audit Logging.
Das Schema sollte gefährliche Möglichkeiten möglichst gar nicht anbieten
Wenn ein Assistent nur lesen soll:
get_customer
search_orders
braucht er kein:
delete_customer
Werkzeug.
Die stärkste Berechtigungsregel lautet oft:
Die gefährliche Funktion steht überhaupt nicht zur Verfügung.
Strukturierte Ausgaben passen perfekt zu Agenten
Ein Agent könnte erzeugen:
{
"next_action": "search_documentation",
"query": "WordPress white screen after plugin update"
}
Danach führt der Agentencontroller die Suche aus.
Ergebnis kommt zurück.
Nächste strukturierte Entscheidung:
{
"next_action": "inspect_log",
"log_type": "php_error"
}
Damit entsteht ein kontrollierbarer mehrstufiger Prozess.
Aber je mehr Aktionen möglich sind, desto wichtiger wird Schema-Design
Schlecht:
{
"action": "do_whatever_is_necessary"
}
Das ist kaum kontrollierbar.
Besser:
search_documentation
read_log
create_draft
request_approval
Eine kleine klar definierte Aktionsmenge ist wesentlich sicherer.
Ein Schema ist damit auch eine Begrenzung des Handlungsraums
Die KI darf nicht beliebige Befehle erfinden.
Sie kann nur innerhalb der vorhandenen Möglichkeiten wählen.
Freitext-Agent:
"Ich lösche jetzt vielleicht..."
gegen:
Schema:
action ∈
[search, analyze, draft]
Das ist ein großer Unterschied.
Strukturierte Ausgaben eignen sich hervorragend für Routing
Eine Anfrage wird analysiert.
{
"workflow": "wordpress_support"
}
oder:
{
"workflow": "invoice_processing"
}
Dann startet die klassische Workflowengine den richtigen Ablauf.
Die KI muss nicht den gesamten Prozess selbst durchführen.
KI als Router ist oft sinnvoller als KI als Universalagent
Eingabe
↓
KI versteht Bedeutung
↓
strukturierte Auswahl
↓
deterministischer Workflow
Das kombiniert:
Sprachverständnis
mit:
verlässlicher Softwarelogik.
Strukturierte Ausgaben erleichtern Datenbankintegration
Ein Modell extrahiert:
{
"first_name": "Anna",
"last_name": "Muster",
"email": "anna@example.com"
}
Diese Werte können nach Validierung in Datenbankfelder geschrieben werden.
Ohne Struktur müsste zuerst wieder natürliche Sprache geparst werden.
Aber die KI sollte nicht automatisch Datenqualität bestimmen
E-Mail:
anna(at)example
Das Modell könnte daraus machen:
anna@example.com
Vielleicht war das gemeint.
Vielleicht nicht.
Eine strenge Anwendung sollte unterscheiden:
extrahiert
und:
korrigiert beziehungsweise geraten.
Dafür kann das Schema Provenienz enthalten
Zum Beispiel:
{
"email": {
"value": null,
"status": "invalid_in_source"
}
}
statt:
{
"email": "anna@example.com"
}
wenn der ursprüngliche Wert nicht eindeutig war.
Strukturierte Ausgaben können Belege mitführen
Bei einer Dokumentenanalyse:
{
"notice_period_days": 90,
"source_section": "§ 8 Abs. 2",
"source_text": "..."
}
Damit kann die extrahierte Information später gegen die Quelle geprüft werden.
Das verbindet strukturierte Ausgabe mit RAG und Faktenkontrolle.
Quellen-IDs sind besser als frei erfundene Zitate
Das Retrievalsystem liefert:
S1
S2
S3
Das Modell darf nur aus diesen IDs wählen.
{
"answer": "Die Kündigungsfrist beträgt 90 Tage.",
"source_ids": [
"S2"
]
}
Danach weiß die Anwendung exakt, auf welchen abgerufenen Dokumentabschnitt sich die Antwort bezieht.
Das verhindert allerdings keine falsche Zuordnung
Das Modell könnte:
S2
nennen, obwohl dort etwas anderes steht.
Auch strukturierte Quellenreferenzen müssen bei hohen Genauigkeitsanforderungen geprüft werden.
Wieder gilt:
saubere Struktur
≠
inhaltliche Wahrheit
KI-Halluzinationen werden dadurch leichter kontrollierbar
Im Fließtext kann das Modell zehn Aussagen miteinander vermischen.
In einer Struktur kann jedes Feld separat untersucht werden.
{
"product": "X",
"version": "7.2",
"release_date": "2026-05-18"
}
Nun können drei einzelne Werte validiert werden.
Das erleichtert automatische Faktenprüfung erheblich.
Strukturierte Ausgaben reduzieren also nicht nur Parsingprobleme
Sie ermöglichen:
Validierung,
Monitoring,
Statistik,
Tests,
Vergleiche,
Fehleranalyse.
Das ist mindestens genauso wichtig.
Ergebnisse lassen sich statistisch auswerten
Bei 100.000 Supportanfragen kann man einfach zählen:
checkout_error:
17.392
billing:
13.881
login:
9.274
Mit freien KI-Texten wäre das wesentlich schwieriger.
Struktur verwandelt generative Ausgaben in analysierbare Daten.
Das ermöglicht wiederum Qualitätsmonitoring
Man kann erkennen:
Kategorie other steigt plötzlich von:
3 %
auf:
18 %
Vielleicht:
neue Anfragearten,
schlechtes Modell,
geänderter Prompt,
Fehler in der Pipeline.
Strukturierte Outputs machen solche Veränderungen messbar.
Schemas sind damit Voraussetzung für viele Evals
Ein Testfall besitzt erwartete Ausgabe:
{
"category": "billing"
}
Modell liefert:
{
"category": "support"
}
Automatische Bewertung:
falsch.
Bei einem langen Fließtext wäre die Bewertung wesentlich komplizierter.
Genau definierte Aufgaben sind leichter zu optimieren
Das gilt für:
Prompting.
Fine-Tuning.
Modellvergleiche.
A/B-Tests.
Wenn das Ziel formal beschrieben ist, kann Qualität systematisch gemessen werden.
Beispiel Modellvergleich
Modell A:
Accuracy:
94,2 %
Modell B:
Accuracy:
96,1 %
Latenz:
A = 300 ms.
B = 1.200 ms.
Kosten:
A niedriger.
Nun kann eine echte Produktentscheidung getroffen werden.
Strukturierte Outputs verwandeln „welches Modell fühlt sich besser an?“ in eine messbare Frage.
Ein Schema sollte die spätere Evaluation bereits berücksichtigen
Wenn du später wissen möchtest:
Wie häufig war menschliche Prüfung nötig?
Dann sollte ein Feld existieren:
{
"requires_human_review": true
}
Wenn du später Ursachen analysieren möchtest:
{
"review_reason": "ambiguous_invoice_number"
}
Gutes Schema-Design ist damit auch gutes Analytics-Design.
Zu viele Felder verschlechtern wiederum Übersicht
Ein Schema mit:
97 Feldern
nur weil irgendwann irgendeine Analyse möglich wäre, ist keine gute Lösung.
Die Balance lautet:
genug Struktur für Prozess und Messung
aber
nicht mehr als notwendig
Schemas sollten nach Geschäftsobjekten gestaltet werden
Beispiel Supportticket:
{
"classification": {
"category": "billing",
"priority": "normal"
},
"extracted_data": {
"invoice_number": "2026-481"
},
"workflow": {
"requires_human_review": true
}
}
Das ist oft übersichtlicher als 30 gleichwertige Felder auf oberster Ebene.
Tiefe Verschachtelung kann jedoch ebenfalls problematisch sein
object
→ object
→ array
→ object
→ array
→ object
wird schnell kompliziert.
Sowohl für Menschen als auch für Modelle.
Das Schema sollte die reale Datenstruktur spiegeln, aber nicht künstlich akademisch werden.
Einige Structured-Output-Systeme unterstützen nur Teile von JSON Schema
Das ist praktisch wichtig.
JSON Schema ist umfangreich.
Ein KI-Anbieter muss nicht zwangsläufig sämtliche Möglichkeiten davon unterstützen.
OpenAI weist beispielsweise darauf hin, dass seine Structured Outputs nur eine unterstützte Teilmenge von JSON Schema akzeptieren. (OpenAI)
Deshalb gilt:
Das konkrete Schema immer gegen die Dokumentation des verwendeten Modells beziehungsweise Anbieters prüfen.
Ein normales JSON-Schema kann mehr können als ein Modellanbieter
JSON Schema bietet umfangreiche Validierungs- und Kompositionsmöglichkeiten.
Eine bestimmte Structured-Output-API kann davon nur einen Teil implementieren.
Man sollte daher zwischen zwei Dingen unterscheiden:
JSON Schema Standard
und:
vom jeweiligen KI-System
unterstützte Schema-Teilmenge
Externe Validierung bleibt deshalb nützlich
Selbst wenn die Generierung bereits strukturell eingeschränkt wurde, kann die eigene Anwendung anschließend noch einmal mit ihrem normalen JSON-Schema-Validator prüfen.
Das schafft eine saubere Schnittstellengrenze.
Modellprovider
↓
eigene Anwendung
↓
eigener Validator
Schemas sollten zentral verwaltet werden
Schlecht:
Dasselbe Ticket-Schema wird:
in Python kopiert,
in n8n noch einmal erstellt,
im Prompt ein drittes Mal beschrieben,
im Frontend ein viertes Mal.
Irgendwann stimmen die Versionen nicht mehr überein.
Besser:
eine definierte Source of Truth.
Typisierte Programmiersprachen können dabei helfen
In vielen Frameworks lassen sich Datenmodelle beispielsweise über Klassen beziehungsweise Typdefinitionen beschreiben und anschließend in JSON Schema übersetzen.
OpenAI nennt für seine SDKs etwa Pydantic in Python und Zod in JavaScript/TypeScript als Wege, Datenmodelle in unterstützte Structured-Output-Schemata zu überführen und Ergebnisse wieder typisiert zu parsen. (OpenAI)
Das kann Doppeldefinitionen reduzieren.
Ein Datenmodell könnte in Python sinngemäß aussehen
class Ticket:
category: str
priority: str
requires_escalation: bool
Eine Bibliothek erzeugt daraus ein Schema.
Nach der KI-Antwort entsteht wieder ein typisiertes Objekt.
Damit passt generative KI wesentlich natürlicher in normale Softwareentwicklung.
Strukturierte Ausgaben sind trotzdem kein Ersatz für Typprüfung
Wenn die Anwendung erwartet:
integer
sollte sie nicht intern plötzlich mit:
"42"
als String weiterarbeiten.
Saubere Datentypen verhindern viele spätere Fehler.
Strings sollten nicht als Universaltyp missbraucht werden
Schlecht:
{
"age": "42",
"active": "yes",
"amount": "49.90"
}
Besser:
{
"age": 42,
"active": true,
"amount": 49.90
}
Die Struktur sollte echte Datentypen ausdrücken.
enum kann Geschäftslogik stabilisieren
Kategorie darf sein:
[
"support",
"sales",
"billing",
"other"
]
Dann kann Software einen Switch verwenden.
support
→ Workflow A
sales
→ Workflow B
billing
→ Workflow C
Keine heuristische Textinterpretation mehr.
Eine Kategorie „other“ kann allerdings problematisch werden
Wenn das Modell zu häufig:
other
wählt, verschwinden wertvolle Informationen.
Vielleicht braucht das Kategoriensystem:
eine neue Klasse.
Oder die Definitionen sind zu unklar.
Structured Outputs machen dieses Problem wenigstens messbar.
Ein unbekannter Wert sollte nicht heimlich zu „other“ werden
Es kann sinnvoll sein, zwischen:
other
→ tatsächlich andere Kategorie
und:
unknown
→ nicht ausreichend bestimmbar
zu unterscheiden.
Denn:
„passt in keine vorhandene Kategorie“
ist etwas anderes als:
„ich habe nicht genug Informationen“.
Gute Schemas spiegeln solche Bedeutungsunterschiede
Zum Beispiel:
{
"category": null,
"classification_status": "insufficient_information"
}
statt:
{
"category": "other"
}
für jeden unsicheren Fall.
Strukturierte Ausgaben sind besonders stark bei mehrstufigen Workflows
Stufe 1:
{
"document_type": "invoice"
}
Stufe 2:
Das Rechnungs-Extraktionsschema wird gewählt.
{
"invoice_number": "...",
"amount": 123.45
}
Stufe 3:
Software prüft den Betrag.
Stufe 4:
Workflow entscheidet über Verbuchung.
Jede KI-Aufgabe bleibt klein.
Das ist besser als ein Universalschema für alle Dokumente
Ein einziges Schema für:
Rechnung,
Lebenslauf,
Vertrag,
Supportmail,
Bestellung
würde riesig werden.
Besser:
Dokument klassifizieren
↓
passendes Spezialschema wählen
Das reduziert Komplexität.
Routing und Structured Outputs ergänzen sich hervorragend
Erster Modellaufruf:
{
"document_type": "contract"
}
Dann lädt die Anwendung:
contract_schema_v3
Zweiter Modellaufruf extrahiert genau die Vertragsinformationen.
So kann aus kleinen Modulen ein komplexes System entstehen.
Kleine Schemas erleichtern außerdem Fehleranalyse
Wenn ein 100-Felder-Schema scheitert, ist die Ursache schwerer zu finden.
Wenn ein Schritt nur fünf Werte extrahiert, ist deutlich schneller sichtbar:
Welches Feld macht Probleme?
Modularität verbessert Wartbarkeit.
Structured Outputs sind auch für lokale Modelle möglich
Das Prinzip ist nicht auf Cloud-APIs beschränkt.
Auch lokale Inference-Systeme können je nach Software:
Grammatiken,
JSON-Schemas,
Regex-basierte Constraints
oder andere Formen constrained generation unterstützen.
Die konkrete Unterstützung hängt von der verwendeten Engine ab.
Für ein lokales KI-System sollte deshalb geprüft werden:
Unterstützt die Inference Engine
schema- oder grammatikgebundene Generierung?
Das kann bei kleinen lokalen Modellen besonders hilfreich sein
Ein kleines Modell erzeugt vielleicht häufiger Formatfehler.
Wenn die Ausgabe technisch auf ein Schema beschränkt wird, entfällt zumindest ein Teil dieser Fehlerklasse.
Damit kann ein kleineres Modell für klar definierte Automatisierungsaufgaben deutlich brauchbarer werden.
Aber auch lokal bleibt die Inhaltsprüfung notwendig
Ein lokales Modell kann perfekt erzeugen:
{
"category": "billing"
}
obwohl:
support
richtig gewesen wäre.
Der Unterschied zwischen:
Format
und:
Semantik
bleibt unabhängig vom Hostingmodell bestehen.
Structured Outputs können API-Kosten senken
Vergleiche:
"Ich habe Ihre Nachricht ausführlich analysiert.
Nach sorgfältiger Betrachtung würde ich ..."
mit:
{
"category": "billing"
}
Wenn nur die Kategorie benötigt wird, ist die zweite Ausgabe wesentlich kürzer.
Bei sehr vielen Aufrufen spart das:
Output-Tokens,
Latenz,
Verarbeitungsaufwand.
Die Ausgabe sollte deshalb nur das enthalten, was gebraucht wird
Keine künstlichen Begründungen, wenn sie niemand nutzt.
Wenn eine Begründung für Audit oder Mensch wichtig ist, gehört sie selbstverständlich hinein.
Zum Beispiel:
{
"category": "billing",
"reason": "Die Nachricht nennt eine doppelte Zahlung und eine Rechnungsnummer."
}
Aber nicht bloß:
Weil eine ausführliche Antwort professioneller wirkt.
Freie Begründungen können allerdings neue Halluzinationen enthalten
Das Modell klassifiziert korrekt:
billing
und schreibt als Begründung:
Der Kunde nennt eine Zahlung vom 3. August.
Dieses Datum kam gar nicht vor.
Wenn die Begründung nicht gebraucht wird:
weglassen.
Jedes generierte Feld ist eine zusätzliche Fehlerfläche.
Strukturierte Ausgaben sollten minimal sein
Ein starkes Produktionsprinzip lautet:
So viel Struktur wie nötig, so wenig generierte Information wie möglich.
Das erhöht:
Zuverlässigkeit,
Geschwindigkeit,
Testbarkeit.
Ein vollständiger robuster Ablauf
Nehmen wir die Supportmail vom Anfang.
E-Mail
↓
Eingabe bereinigen
↓
LLM
↓
Structured Output
Ausgabe:
{
"category": "checkout_error",
"priority": "high",
"requires_escalation": true,
"order_id": null
}
Dann:
JSON / Schema prüfen
↓
Geschäftsregeln prüfen
↓
Berechtigung prüfen
Danach:
checkout_error
↓
Technikteam
und:
requires_escalation = true
↓
Incident-Kanal informieren
Das Sprachmodell hat nur den Teil übernommen, für den es besonders gut geeignet ist:
unstrukturierte Sprache interpretieren.
Was die KI nicht übernimmt
Sie entscheidet nicht selbst:
welche Datenbank geschrieben wird.
Sie berechnet keine Berechtigungen.
Sie sendet nicht ungeprüft Nachrichten.
Sie erfindet keine Workflowstruktur.
Diese Dinge bleiben deterministische Software.
Das ist eine sehr starke Arbeitsteilung
LLM
→ unscharfe Bedeutung verstehen
Schema
→ möglichen Output begrenzen
Validator
→ Struktur prüfen
Software
→ harte Regeln ausführen
Mensch
→ kritische Sonderfälle entscheiden
Damit wird KI wesentlich berechenbarer.
Wann braucht man keine strukturierte Ausgabe?
Nicht jede KI-Antwort muss JSON sein.
Frage:
Erkläre mir DNS.
Der Nutzer möchte einen verständlichen Text.
Dann ist:
{
"answer": "DNS ist..."
}
möglicherweise nur unnötiger Overhead.
Strukturierte Ausgaben sind für Maschinen gedacht
Wenn der nächste Empfänger:
ein Mensch
ist, kann normale Sprache optimal sein.
Wenn der nächste Empfänger:
Software
ist, wird Struktur wichtig.
Das ist die einfachste Entscheidungsregel.
Mischformen sind häufig ideal
Eine Anwendung benötigt:
Maschinendaten
und:
einen lesbaren Text.
Dann:
{
"category": "billing",
"priority": "normal",
"message_to_customer": "Vielen Dank für Ihre Nachricht. Wir prüfen die doppelte Zahlung."
}
Software verarbeitet die ersten Felder.
Der Mensch beziehungsweise Kunde sieht das letzte.
Auch UI-Inhalte können strukturiert erzeugt werden
Ein Modell könnte beispielsweise erzeugen:
{
"title": "Serverstatus",
"status": "warning",
"items": [
{
"label": "Webserver",
"value": "online"
},
{
"label": "Datenbank",
"value": "degraded"
}
]
}
Die Anwendung entscheidet anschließend, wie diese Daten dargestellt werden.
OpenAI nennt dynamisch erzeugte Benutzeroberflächen und die Extraktion strukturierter Informationen aus unstrukturierten Eingaben ausdrücklich als Anwendungsfälle für Structured Outputs. (OpenAI)
Die KI sollte möglichst Daten erzeugen, nicht beliebigen ausführbaren Code
Für eine Benutzeroberfläche ist:
{
"component": "button",
"label": "Speichern"
}
in vielen Architekturen sicherer und kontrollierbarer als:
Erzeuge beliebiges JavaScript und führe es direkt aus.
Strukturierte Zwischenrepräsentationen begrenzen den möglichen Handlungsraum.
Das Schema kann zur Sicherheitsarchitektur beitragen
Wenn erlaubte Aktion:
create_draft
ist, kann das Modell nicht über das Schema plötzlich:
delete_database
auswählen – sofern dieser Wert nicht zugelassen wird und die technische Implementierung das Schema tatsächlich erzwingt.
Natürlich muss auch die Werkzeugschicht entsprechend begrenzt sein.
Schema und Berechtigungen ergänzen sich
Schema
→ Was kann vorgeschlagen werden?
Berechtigung
→ Was darf tatsächlich ausgeführt werden?
Beide sollten unabhängig voneinander existieren.
Was du dir über strukturierte KI-Ausgaben merken solltest
Ein Sprachmodell erzeugt von Natur aus hervorragend natürliche Sprache.
Automatisierte Software benötigt dagegen möglichst vorhersehbare Daten.
Deshalb verwandeln strukturierte Ausgaben:
KI sagt etwas
in:
KI liefert definierte Daten
Das häufigste Format dafür ist JSON.
{
"category": "billing",
"priority": "high",
"requires_review": true
}
JSON allein reicht jedoch nicht.
Denn auch:
{
"elephant": "Thursday"
}
ist gültiges JSON.
Deshalb benötigen robuste Anwendungen ein Schema.
JSON Schema kann unter anderem festlegen:
welche Felder existieren
welche Felder Pflicht sind
welche Datentypen gelten
welche Werte erlaubt sind
ob zusätzliche Felder zulässig sind
Dazu dienen unter anderem Schlüsselwörter wie type, properties, required, enum und additionalProperties. (json-schema.org)
Ein besonders wichtiger Unterschied lautet:
"Antworte als JSON"
→ sprachliche Anweisung
JSON Mode
→ gültiges JSON erzwingen beziehungsweise fördern
Structured Outputs
→ Ausgabe zusätzlich an ein definiertes Schema binden
OpenAI unterscheidet genau zwischen JSON Mode und Structured Outputs: Gültiges JSON allein garantiert keine Übereinstimmung mit einer bestimmten Schemaform. (OpenAI)
Bei streng schemaorientierten Systemen kann die Generierung technisch eingeschränkt werden, sodass nur Ausgaben erzeugt werden können, die zur zugelassenen Grammatik passen. (OpenAI)
Aber:
Schema korrekt
≠
Inhalt korrekt
Ein Modell kann perfekt strukturiert antworten:
{
"birth_year": 1973
}
und das Geburtsjahr kann trotzdem falsch sein.
Structured Outputs lösen deshalb primär das Problem:
Wie bekomme ich verlässlich verarbeitbare Daten aus einem Sprachmodell?
Sie lösen nicht automatisch:
Sind diese Daten wahr?
Für robuste Automatisierungen ergibt sich deshalb eine mehrstufige Architektur:
unstrukturierte Eingabe
↓
LLM
↓
Structured Output
↓
Schema Validation
↓
fachliche Validierung
↓
Berechtigungsprüfung
↓
deterministische Softwareaktion
Besonders wertvoll ist außerdem ein sauberer Umgang mit fehlender Information.
{
"invoice_number": null
}
ist besser als eine erfundene Rechnungsnummer.
Ein gutes Schema sollte daher nicht nur den idealen Erfolgsfall darstellen.
Es sollte auch Zustände abbilden wie:
unbekannt
nicht vorhanden
mehrdeutig
menschliche Prüfung erforderlich
Strukturierte Ausgaben bilden damit einen entscheidenden Übergang in der KI-Architektur.
Aus:
Chatbot
wird:
Softwarekomponente
Denn nun kann das Sprachmodell genau dort eingesetzt werden, wo klassische Software schwach ist:
unstrukturierte Sprache
↓
Bedeutung erkennen
und normale Software übernimmt anschließend das, worin sie besonders gut ist:
klare Daten
↓
klare Regeln
↓
vorhersehbare Aktion
Diese Kombination ist eine der wichtigsten Grundlagen zuverlässiger KI-Automatisierung.
