Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Lesedauer 7 Min.

Von Text zu Struktur: JSON-Ausgaben aus LLMs zuverlässig nutzen

Mit JSON-Schema lassen sich LLM-Ausgaben direkt deserialisieren, typsicher verarbeiten und in bestehende Workflows integrieren.
© EMGenie

Large Language Models sind beeindruckende Textgeneratoren, doch in produktiven Anwendungen reicht der Fließtext oft nicht aus. Wer eine Analyse durchführt, Daten extrahiert oder Entscheidungen trifft, braucht strukturierte Ausgaben: Objekte mit definierten Feldern, klaren Datentypen, maschinenlesbaren Werten. Also kurz: JSON statt Prosa.

Die gute Nachricht: Moderne LLMs können strukturierte Daten zurückgeben. Die schlechte: Bis vor Kurzem war das eine Glückssache. Man konnte dem Modell zwar sagen „Antworte als JSON“, aber ob es das auch tat, besonders in Fehlerfällen, stand in den Sternen. Seit 2023 hat sich das grundlegend geändert: Mit JSON-Schema lassen sich Strukturen erzwingen, und das Modell liefert garantiert valides JSON zurück.

Für .NET-Entwickler bedeutet das: Man kann LLM-Ausgaben direkt deserialisieren, typsicher verarbeiten und in bestehende Workflows integrieren. Aus einem unberechenbaren Textgenerator wird ein verlässlicher Datenlieferant. Dieser Artikel zeigt, wie das funktioniert, von den Grundlagen über Best Practices bis zu konkreten Implementierungen.

Warum überhaupt strukturierte Ausgaben?

Stellen wir uns eine typische Aufgabe vor: Ein Kundenservice-System analysiert eingehende E-Mails und extrahiert relevante Informationen: Kundennummer, Produktname, Art der Anfrage, Dringlichkeit. Mit einem LLM ist das trivial machbar, aber wie kommt man an die Daten?

Variante 1 wäre, das LLM einen Fließtext schreiben zu lassen:

"Der Kunde mit der Nummer 12345 hat eine dringende Anfrage zu Produkt XY-900. Es handelt sich um eine Reklamation bezüglich eines defekten Teils."

 

Jetzt müsste man diesen Text parsen: RegEx-Patterns schreiben, nach Keywords suchen, hoffen, dass das Format immer gleich bleibt. Das ist fehleranfällig, wartungsintensiv und bricht bei unerwarteten Formulierungen.

Variante 2: Das LLM liefert direkt ein strukturiertes Objekt:

 

{
   "kundennummer": "12345",
   "produkt": "XY-900",
   "anfragetyp": "Reklamation",
   "dringlichkeit": "hoch",
   "beschreibung": "Defektes Teil"
}

 

Dieses JSON lässt sich in C# direkt in ein typisiertes Objekt deserialisieren. Keine RegEx, kein Parsing, keine Fehleranfälligkeit. Das ist der Kern dessen, warum strukturierte Ausgaben so wertvoll sind: Sie machen LLM-Ergebnisse programmatisch verarbeitbar.

Also sage ich dem Prompt, es soll JSON zurückgeben?

Vor der Einführung von JSON Schema war die einzige Möglichkeit, JSON-Ausgaben zu erhalten, eine Anweisung im Prompt:

 

Analysiere die E-Mail und gib die Informationen im folgenden JSON-Format zurück: 
 
{
   "kundennummer": "",
   "produkt": "",
   "anfragetyp": "",
   "dringlichkeit": "",
   "beschreibung": ""
}
 
Antworte ausschließlich mit dem JSON-Objekt, ohne zusätzlichen Text.

 

Auf den allerersten Blick betrachtet und in gewissen Standardfällen funktionierte das vielleicht ganz gut, vielleicht 70 bis 80 Prozent der Zeit. Das Modell hat gelernt, dass JSON ein häufiges Ausgabeformat ist, und konnte die Struktur nachahmen. 

Wer jedoch etwas mit LLMs zu tun hatte, weiß auch, dass Prompts niemals reproduzierbar sind und in gewissen Randfällen Probleme auftreten können:


Beispiel 1: Unvollständige Informationen

User: "Analysiere diese E-Mail: 'Hallo, ich habe ein Problem.'"
LLM: "Die E-Mail enthält nicht genug Informationen, um die Felder zu füllen. Bitte fordern Sie Kundennummer und Produktname nach."

 

Statt dem gewünschten JSON haben wir hier plötzlich einen Fließtext erhalten. Serialisieren oder eine logische Weiterverarbeitung ist so nicht möglich.

 

Beispiel 2: Formatfehler

 

{ "kundennummer": 12345, // Sollte String sein, ist aber Number "dringlichkeit": "Sehr hoch" // Sollte Enum sein, ist aber Freitext }

 

Insbesondere bei Datentypen oder gar Enumerationen (zum Beispiel bei der Eigenschaft Dringlichkeit), optionalen Parametern und dergleichen ist es mit diesem Ansatz kaum möglich, konsistente Ergebnisse zu erzielen. 

 

Beispiel 3: Zusatztext

 

Hier ist die Analyse: 
{ 
   "kundennummer": "12345", ... 
} 
Ich hoffe, das hilft weiter!

 

Der JSON-Block war von Text umgeben, Deserialisierung ohne Weiteres nicht möglich. Hier muss man also wiederum via RegEx oder anderen Konstrukten das JSON vom restlichen Text „befreien“. 

Diese Unzuverlässigkeit machte Prompt-basiertes JSON zwar für Experimente oder Proof-of-Concepts nutzbar, aber nicht für produktive Systeme. Man konnte sich nie darauf verlassen, dass die Ausgabe valide war. Auch wir hatten bei uns solche Fälle, und die Bibliothek, welche auf diverse Fehlerfälle reagierte und Validierungen sowie Parsen durchführen musste, wurde immer länger. 

JSON als Feature des LLM nutzen

Seit 2023 unterstützen führende LLM-APIs, wie zum Beispiel die von OpenAI, Anthropic oder Google, sogenannte Structured Outputs oder JSON Mode. Das Prinzip: Man gibt dem Modell nicht nur einen Prompt, sondern auch ein JSON Schema, das die erwartete Struktur definiert. Das Modell ist dann gezwungen, ein Objekt zurückzugeben, das diesem Schema entspricht.

Ein JSON Schema ist eine standardisierte Spezifikation, die beschreibt, wie ein JSON-Objekt aussehen soll:

 

{
   "type": "object",
   "properties": {
     "kundennummer": { "type": "string" },
     "produkt": { "type": "string" },
     "anfragetyp": { 
       "type": "string",
       "enum": ["Anfrage", "Reklamation", "Bestellung", "Sonstiges"]
     },
     "dringlichkeit": {
       "type": "string",
       "enum": ["niedrig", "mittel", "hoch", "kritisch"]
     },
     "beschreibung": { "type": "string" }
   },
   "required": ["kundennummer", "produkt", "anfragetyp", "dringlichkeit"]
}

 

Dieses Schema definiert

  • welche Felder existieren,
  • welche Datentypen sie haben,
  • welche Werte erlaubt sind (bei Enums),
  • welche Felder zwingend erforderlich sind.

 

Mit diesem Schema kann das LLM kein ungültiges JSON mehr zurückgeben. Selbst wenn man eigentlich Text ausgeben wollte („Informationen fehlen“), wird es gezwungen, die Struktur einzuhalten, etwa durch leere Strings oder Standardwerte.

Implementierung in .NET mit OpenAI

OpenAI bietet Structured Outputs über das Chat Completions API an. In C# sieht das so aus, dass man dem ChatRequest die Eigenschaft ResponseFormat mitliefert.

 

var schema = new { … };
 
var request = new ChatRequest { Model = "gpt-4o", Messages = new[] { … }, ResponseFormat = new { type = "json_schema", json_schema = new{ schema } } };

 

Das Ergebnis: ein korrekt strukturiertes, typisiertes Objekt, ohne Fehlerbehandlung für Parsing-Probleme.

Wichtige Einschränkungen bei JSON Schema

Trotz der Mächtigkeit gibt es Einschränkungen, besonders bei OpenAI:

  • 1. Nur grundlegende Datentypen: Unterstützt werden: string, number, integer, boolean, array, object, null. Komplexere Typen wie Datum/Zeit müssen als String formatiert werden.
  • 2. Keine regulären Ausdrücke: Man kann nicht verlangen, dass ein String einem bestimmten Pattern entspricht (zum Beispiel E-Mail-Format). Das Modell wird versuchen, plausible Werte zu liefern, aber nachträglich muss eine Validierung erfolgen.
  • 3. Keine bedingten Schemas:if/then/else-Konstrukte aus JSON Schema werden nicht unterstützt. Die Struktur muss statisch sein. Für verschiedene Fälle sollten entsprechende Eigenschaften genutzt werden, die dann in der Weiterverarbeitung evaluiert werden.
  • 4. Maximale Verschachtelungstiefe: Sehr tief verschachtelte Objekte können Probleme machen. Flache Strukturen sind zu bevorzugen.

 

Das bedeutet: JSON Schema in LLMs ist mächtiger als Prompt-basierte Ansätze, aber nicht so flexibel wie vollständige JSON-Schema-Validatoren.

Best Practice: Status und Error-Handling in der Struktur

Ein häufiges Problem: Was, wenn das LLM die Aufgabe nicht erfüllen kann? Etwa weil Informationen fehlen oder die Anfrage unklar ist?

Früher hätte das Modell einen Text ausgegeben: „Ich kann das nicht beantworten.“ Mit JSON Schema ist das nicht mehr möglich, es muss ein Objekt zurückgeben. Die Lösung: Error-Handling direkt in der Datenstruktur. Wie hier im Beispiel, wo ein Status, das Ergebnis und gegebenenfalls Fehler in einem Objekt behandelt werden.

 

{
   "type": "object",
   "properties": {
     "status": {
       "type": "string",
       "enum": ["success", "error"]
     },
     "data": {
       "type": "object",
       "properties": {
         "kundennummer": { "type": "string" },
         "produkt": { "type": "string" },
         ...
       }
     },
     "error": {
       "type": "object",
       "properties": {
         "message": { "type": "string" },
         "missingFields": {
           "type": "array",
           "items": { "type": "string" }
         }
       }
     }
   },
   "required": ["status"]
}

 

Dieser Ansatz macht Systeme robust: Anstelle eines Deserialisierungsfehlers bekommt man eine klare, strukturierte Fehlermeldung.

Fazit: Weniger raten, sondern mehr Struktur

Mit JSON Schema können Entwickler sicher sein, dass sie valide, maschinenlesbare Daten zurückbekommen, und das nicht irgendwann, sondern jedes Mal.

Die Kombination aus Schema, durchdachtem Error-Handling und Few-Shot-Prompting, um ein paar Beispiele mitzuliefern und die Qualität zu erhöhen, schafft Systeme, die robust, wartbar und skalierbar sind. LLMs werden damit zu verlässlichen Komponenten in größeren Architekturen, nicht als Black Box, sondern als definierte, testbare Services.

Und das Beste: Die Integration ist einfach. Ein Schema definieren, an das API senden, JSON deserialisieren, fertig. Keine komplexen Parsing-Bibliotheken, keine RegEx-Schlachten, keine vage Hoffnung, dass diesmal das Format stimmt.

Neueste Beiträge

Wissensquellen liefern Daten für präzise Antworten - Low Code/No Code und KI mit Copilot Studio, Teil 3
Wissensquellen (Knowledge Sources) stellen dem KI-Agenten zusätzliche, durchsuchbare Informationen bereit, um fundierte, kontextbezogene Antworten auf Basis von Unterneh-menswissen oder fachspezifischen Informationen zu generieren.
7 Minuten
7. Apr 2026
ROI von KI
Wie Entwickler die Lücke bei der Bereitschaft, KI einzusetzen, schließen können.
7 Minuten
SQLite in ein .NET-Projekt integrieren - SQLite für .NET-Entwickler, Teil 2
Der eleganteste Aspekt von SQLite in .NET ist die Migration vom Prototyp zur Produktion.
6 Minuten

Das könnte Dich auch interessieren

00:00
Vibe Coding war gestern – Vise Coding ist die Zukunft - KI-gestützte Softwareentwicklung
Der Begriff Vibe Coding geistert durch die Branche – aber was steckt wirklich dahinter? Gregor Biswanger erklärt im DWX-Interview, warum nicht alle KI-Agenten-Workflows gleich sind, wo Vise Coding den Unterschied macht und warum die Branche gerade eine ziemlich wilde Dating-Show erlebt.
31. Mär 2026
00:00
MCP: Der USB-C-Stecker für Deine KI-App - Model Context Protocol auf der DWX
Jonah Andersson bringt es auf den Punkt: Das Model Context Protocol ist kein Hype-Buzzword, sondern eine echte Hilfe für .NET-Entwickler:innen. Wer MCP richtig einsetzt, spart sich aufwändige Integrationsarbeit – und behält trotzdem die Kontrolle über die eigene Business-Logik.
7. Apr 2026
Infinite AI Conference: So setzt Du KI in jedem Schritt des Software-Lifecycle ein - KI gehört in Deinen Workflow
Von den Anforderungen über Design, Implementierung bis zum Testen, Deployment und Monitoring: Auf der Infinite AI Conference 2026 erfährst Du, wie Dich die KI im gesamten Lifecycle unterstützen kann.
4 Minuten
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige