ai-machine-learning

Zuverlässiges JSON aus jedem LLM: Pydantic + Zod-Muster für 2026

Geschrieben von Mert Batur
Aktualisiert May 12, 2026
15 Lesezeit
Zuverlässiges JSON aus jedem LLM: Pydantic + Zod-Muster für 2026

LLM-strukturierte Ausgabe ist der Mechanismus, der garantiert, dass die Antwort eines Sprachmodells einem vordefinierten Schema entspricht -- nicht nur gültiges JSON, sondern schema-gültiges JSON mit genau den Feldern, Typen und Einschränkungen, die Sie angegeben haben. Alle wichtigen Anbieter unterstützen dies jetzt nativ, und es hat verändert, wie Produktions-LLM-Anwendungen gebaut werden.

Kurzübersicht: Strukturierte Ausgaben auf einen Blick

Wenn Sie wenig Zeit haben, hier ist die Landschaft in 2026:

AspektDetails
Was es istSchema-erzwungene Antworten von LLMs -- garantierte Struktur, kein "Best Effort"
Wer es unterstütztOpenAI, Anthropic, Gemini, Cohere, xAI (Grok), plus lokal über Ollama/vLLM
SchlüsselmechanismusConstrained Decoding -- ungültige Tokens werden vor dem Sampling maskiert
JSON-Modus vs. Strict-ModusJSON-Modus = nur gültige Syntax. Strict-Modus = vollständige Schema-Konformität
Python-BibliothekPydantic (BaseModel + Field) für die Schemadefinition
TypeScript-BibliothekZod (z.object + .describe) für die Schemadefinition
Bester EinstiegOpenAI mit Pydantic oder Zod über das native SDK
Beste ProduktionsbibliothekInstructor (Python) oder natives SDK (TypeScript)
Größter FallstrickDas Reasoning-Feld NACH dem Antwortfeld platzieren -- das Modell entscheidet vor dem Denken
Latenz-Overhead50-200ms beim ersten Aufruf (Schema-Kompilierung), danach gecacht

Lassen Sie uns nun jeden Punkt aufschlüsseln.

Was sind LLM-strukturierte Ausgaben?

Strukturierte Ausgabe ist der Unterschied zwischen dem Hoffen, dass ein LLM gültiges JSON zurückgibt, und dem Garantieren davon. Wenn Sie strukturierte Ausgabe aktivieren, kann das Modell physisch keine Tokens produzieren, die Ihr Schema verletzen. Sie definieren ein JSON-Schema (oder ein Pydantic-Modell oder ein Zod-Schema), übergeben es an die API und erhalten jedes Mal eine Antwort zurück, die damit übereinstimmt.

Warum ist das wichtig? Vor strukturierten Ausgaben schrieben Entwickler fragile Regex-Parser, umwickelten jeden LLM-Aufruf in try/catch JSON.parse-Blöcke und hatten dennoch mit "fast richtigen" Antworten zu kämpfen -- gültiges JSON, dem ein Feld fehlte oder das den falschen Typ hatte. Diese gesamte Klasse von Fehlern ist verschwunden.

Es gibt drei Ebenen der Strukturdurchsetzung, die eine klare Entwicklung darstellen:

  1. Prompt Engineering -- "Bitte gib JSON mit diesen Feldern zurück." Unzuverlässig. Das Modell könnte 80-90% der Zeit konform sein.
  2. JSON-Modus -- Garantiert syntaktisch gültiges JSON, erzwingt aber nicht Ihr Schema. Sie könnten {"foo": "bar"} erhalten, wenn Sie {"name": string, "age": number} erwartet haben.
  3. Strict-Modus / Constrained Decoding -- Garantiert 100% Schema-Konformität. Das Modell kann buchstäblich keine ungültigen Tokens ausgeben. Das ist das, was "strukturierte Ausgabe" im Jahr 2026 bedeutet.

Seit Anfang 2026 unterstützen OpenAI, Anthropic und Google Gemini alle native strukturierte Ausgabe. Das Ökosystem hat sich angepasst.

Fazit: Wenn Sie LLM-Antworten in der Produktion mit Regex oder JSON.parse analysieren, machen Sie es auf die schwierige Tour. Native strukturierte Ausgabe eliminiert diese gesamte Fehlerklasse.

JSON-Modus vs. Strict-Modus: Was hat sich wirklich geändert?

Diese Unterscheidung verwirrt viele Entwickler, weil die Namen ähnlich klingen. Das sind sie nicht.

FunktionJSON-ModusStrict-Modus (Strukturierte Ausgaben)
API-Parametertype: "json_object"type: "json_schema" mit strict: true
Garantiert gültiges JSONJaJa
Garantiert Schema-KonformitätNeinJa
MechanismusPost-hoc Token-BiasConstrained Decoding (FSM)
Kann unerwartete Felder zurückgebenJaNein
Kann erforderliche Felder weglassenJaNein
TypüberprüfungKeineVollständig (string, number, array, etc.)
Wann verwendenSie haben kein Schema vorabAlles in der Produktion

Die Zeitlinie: OpenAI führte den JSON-Modus Ende 2023 ein. Es war ein Fortschritt, aber Entwickler erkannten schnell, dass "gültiges JSON" nicht ausreichte -- sie brauchten schema-gültiges JSON. Im August 2024 startete OpenAI Structured Outputs mit Strict Mode, das Constrained Decoding verwendet, um Schema-Konformität zu garantieren. Bis 2025-2026 hatte jeder große Anbieter denselben Ansatz übernommen.

Der JSON-Modus hat noch einen engen Anwendungsfall: wenn Sie wirklich nicht die Form der Antwort im Voraus kennen und nur irgendein gültiges JSON für unstrukturierte Erkundung möchten. Aber das ist in der Produktion selten.

Fazit: Verwenden Sie den Strict-Modus für alles in der Produktion. Der JSON-Modus ist für schema-gebundene Anwendungsfälle effektiv veraltet. Wenn Sie ein Schema haben (und das sollten Sie), verwenden Sie type: "json_schema" mit strict: true.

Wie funktioniert Constrained Decoding eigentlich?

Hier ist der Mechanismus, der 100% Schema-Konformität ermöglicht -- nicht 99,9%, sondern buchstäblich 100%.

Wenn Sie ein JSON-Schema mit aktiviertem Strict Mode an einen Anbieter senden, wird das Schema in eine finite Zustandsmaschine (FSM) kompiliert. Diese FSM repräsentiert jeden gültigen Pfad durch Ihr Schema. Bei jedem Token-Generierungsschritt prüft die Inference-Engine, welche Tokens die Ausgabe auf einem gültigen Pfad halten und welche nicht. Ungültige Tokens erhalten ihre Logits vor dem Sampling auf negativ unendlich gesetzt, was bedeutet, dass sie eine Nullwahrscheinlichkeit haben, ausgewählt zu werden.

<!-- IMAGE: constrained-decoding diagram showing FSM token masking during structured output generation -->

Stellen Sie sich das wie Autovervollständigung auf Steroiden vor. Wenn das Modell gerade {"rating": ausgegeben hat und Ihr Schema sagt, dass rating eine ganze Zahl ist, sind die einzigen erlaubten nächsten Tokens Zifferntokens. Anführungszeichen, Buchstaben, Klammern -- alle maskiert. Das Modell kann nicht "fünf" ausgeben, auch wenn es das "will".

Dies ist der gleiche Kernmechanismus, der von XGrammar (der Engine hinter vLLM, SGLang und den meisten lokalen Inferenzservern) und Outlines (der Open-Source-Python-Bibliothek für eingeschränkte Generierung) verwendet wird. Die API-Anbieter haben es einfach in ihre Inferenzinfrastruktur integriert.

Es gibt einen Trade-off zu kennen: Die erste Anfrage mit einem neuen Schema verursacht einen Kompilierungslatenz-Treffer (typischerweise 50-200ms), während die FSM aufgebaut wird. Nachfolgende Anfragen mit demselben Schema verwenden eine gecachte FSM und fügen nahezu null Overhead hinzu. Es gibt auch eine subtile Qualitätsüberlegung -- das Einschränken des Token-Vokabulars kann gelegentlich die Ausgabequalität für kreative oder freiform Felder reduzieren, also halten Sie Ihre Schemas auf wirklich strukturierte Daten fokussiert.

Fazit: Constrained Decoding ist das, was "meistens funktioniert" von "immer funktioniert" trennt. Es ist das Engineering, das strukturierte Ausgabe produktionsreif macht.

Multi-Provider-Implementierung: OpenAI, Anthropic und Gemini

Hier ist etwas, das keiner der anderen Leitfäden zeigt: dieselbe Extraktionsaufgabe, implementiert über alle drei großen Anbieter. Wir werden eine strukturierte Produktbewertung aus unstrukturiertem Text extrahieren.

Das Pydantic-Schema (gemeinsam für alle Anbieter):

python
from pydantic import BaseModel, Field
from typing import Literal

class ProductReview(BaseModel):
    reasoning: str = Field(description="Think through the review before scoring")
    rating: int = Field(description="Rating from 1-5", ge=1, le=5)
    sentiment: Literal["positive", "negative", "neutral"]
    pros: list[str] = Field(description="Key positive points")
    cons: list[str] = Field(description="Key negative points")
    summary: str = Field(description="One-sentence summary")

OpenAI-Implementierung

python
from openai import OpenAI

client = OpenAI()

response = client.beta.chat.completions.parse(
    model="gpt-4o-2024-08-06",
    messages=[
        {"role": "system", "content": "Extract a structured review from the text."},
        {"role": "user", "content": review_text}
    ],
    response_format=ProductReview,  # Pydantic-Modell direkt
)

review = response.choices[0].message.parsed  # Typisiertes ProductReview-Objekt

OpenAIs Implementierung ist die ausgereifteste. Die parse()-Methode akzeptiert ein Pydantic-Modell direkt und gibt ein typisiertes Objekt zurück. Eine Einschränkung: OpenAIs Strict Mode unterstützt eine Teilmenge von JSON Schema -- kein $ref, begrenztes anyOf, und alle Felder müssen mit additionalProperties: false erforderlich sein.

Anthropic-Implementierung

python
from anthropic import Anthropic

client = Anthropic()

response = client.messages.create(
    model="claude-sonnet-4-5-20250514",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": f"Extract a structured review:\n\n{review_text}"}
    ],
    output_config={
        "format": {
            "type": "json_schema",
            "json_schema": ProductReview.model_json_schema()
        }
    }
)

import json
review_data = json.loads(response.content[0].text)
review = ProductReview(**review_data)

Anthropics native strukturierte Ausgabe verwendet output_config.format mit einem JSON-Schema. Es erreichte GA Anfang 2026. Anthropic unterstützt auch das ältere Muster der Definition eines "gefälschten" Tools und der Extraktion über tool_use -- das funktioniert noch, aber native strukturierte Ausgabe ist sauberer für reine Extraktion.

Gemini-Implementierung

python
from google import genai

client = genai.Client()

response = client.models.generate_content(
    model="gemini-2.0-flash",
    contents=f"Extract a structured review:\n\n{review_text}",
    config={
        "response_mime_type": "application/json",
        "response_schema": ProductReview,  # Pydantic-Modell direkt
    }
)

import json
review = ProductReview(**json.loads(response.text))

Gemini unterstützt Pydantic-Modelle direkt im Python-SDK über response_schema. Ein einzigartiges Feature: Gemini respektiert propertyOrdering im Schema, sodass Sie die Feldausgabereihenfolge steuern können (nützlich für das Reasoning-First-Muster).

Anbietervergleich

FunktionOpenAIAnthropicGemini
API-Parameterresponse_formatoutput_config.formatresponse_schema
Schema-EingabePydantic oder JSON SchemaJSON SchemaPydantic oder JSON Schema
Strict-Modusstrict: trueImplizit mit json_schemaImplizit
StreamingJa (partielles JSON)JaJa
Verweigerungsbehandlungmessage.refusal-FeldFehlerantwortFehlerantwort
Tool-Use-AlternativeJaJa (ursprüngliche Methode)Ja
Schema-KompilierungscacheJa (serverseitig)JaJa
EigenschaftsreihenfolgeKeine native UnterstützungNeinJa (propertyOrdering)

Fazit: OpenAI hat den ausgereiftesten DX mit seiner parse()-Methode. Anthropic bietet die fähigsten zugrunde liegenden Modelle. Gemiinis Eigenschaftsreihenfolge ist einzigartig nützlich. Alle drei erledigen die Aufgabe -- wählen Sie basierend auf Ihrer bestehenden Anbieterbeziehung.

Pydantic-Muster für Python-Entwickler

Pydantic ist der De-facto-Standard für die Definition von strukturierten Ausgabe-Schemas in Python. Hier sind die wichtigsten Muster.

Grundlegendes Schema mit Beschreibungen

python
from pydantic import BaseModel, Field
from typing import Literal, Optional

class ExtractedEntity(BaseModel):
    reasoning: str = Field(description="Think step by step about the entity")
    name: str = Field(description="Full name of the entity")
    entity_type: Literal["person", "company", "location"]
    confidence: float = Field(description="Confidence score 0.0-1.0", ge=0.0, le=1.0)
    context: Optional[str] = Field(description="Surrounding context, if relevant")

Diese description-Strings sind nicht nur zur Dokumentation -- sie werden Teil des JSON-Schemas, das an das Modell gesendet wird, und beeinflussen direkt, was das Modell generiert. Betrachten Sie sie als Prompt Engineering innerhalb des Schemas.

Verschachtelte Modelle

python
class Address(BaseModel):
    street: str
    city: str
    country: str
    postal_code: Optional[str] = None

class Company(BaseModel):
    reasoning: str = Field(description="Analysis of the company details")
    name: str
    industry: Literal["tech", "finance", "healthcare", "retail", "other"]
    headquarters: Address  # Verschachteltes Modell
    key_products: list[str] = Field(description="Top 3 products or services")

Halten Sie die Verschachtelung auf maximal 2-3 Ebenen. Tief verschachtelte Schemas erhöhen die Fehlerrate und verlangsamen die Schema-Kompilierung.

Das Reasoning-First-Muster

Dies ist das einflussreichste Schema-Design-Muster. Setzen Sie ein reasoning-Feld vor Ihre Antwortfelder:

python
# Schlecht -- Modell verpflichtet sich zu einer Antwort vor dem Denken
class ClassificationBad(BaseModel):
    category: Literal["spam", "ham"]
    confidence: float

# Gut -- Modell denkt zuerst durch das Problem
class ClassificationGood(BaseModel):
    reasoning: str = Field(description="Analyze the text before classifying")
    category: Literal["spam", "ham"]
    confidence: float = Field(ge=0.0, le=1.0)

LLMs generieren Tokens von links nach rechts. Wenn category zuerst kommt, wählt das Modell eine Kategorie und rationalisiert sie dann. Wenn reasoning zuerst kommt, arbeitet das Modell das Problem durch und verpflichtet sich dann zu einer Kategorie. Es ist Chain-of-Thought, das ins Schema eingebaut ist.

JSON-Schema-Export

python
# Generiere das JSON-Schema für jedes Pydantic-Modell
schema = ProductReview.model_json_schema()
# Übergebe dies an jeden Anbieter, der rohes JSON-Schema akzeptiert

Fazit: Pydantic + beschreibende Felder + Reasoning-First-Reihenfolge ist das Python-Trio für strukturierte Ausgaben. Beherrschen Sie diese drei Muster und Sie werden 90% der Anwendungsfälle bewältigen.

Zod-Muster für TypeScript-Entwickler

Zod ist das TypeScript-Äquivalent von Pydantic -- und es ist genauso zentral für strukturierte Ausgabe-Workflows.

Grundlegendes Schema mit Beschreibungen

typescript
import { z } from "zod";

const ProductReview = z.object({
  reasoning: z.string().describe("Think through the review before scoring"),
  rating: z.number().int().min(1).max(5),
  sentiment: z.enum(["positive", "negative", "neutral"]),
  pros: z.array(z.string()).describe("Key positive points"),
  cons: z.array(z.string()).describe("Key negative points"),
  summary: z.string().describe("One-sentence summary"),
});

// TypeScript-Typ automatisch ableiten
type ProductReview = z.infer<typeof ProductReview>;

Wie Pydantics Field(description=...) wird Zods .describe() Teil des JSON-Schemas und lenkt die Ausgabe des Modells.

Integration mit dem OpenAI Node SDK

typescript
import OpenAI from "openai";
import { zodResponseFormat } from "openai/helpers/zod";

const client = new OpenAI();

const response = await client.beta.chat.completions.parse({
  model: "gpt-4o-2024-08-06",
  messages: [
    { role: "system", content: "Extract a structured review." },
    { role: "user", content: reviewText },
  ],
  response_format: zodResponseFormat(ProductReview, "product_review"),
});

const review = response.choices[0].message.parsed; // Typisiert!

Integration mit dem Vercel AI SDK

typescript
import { generateObject } from "ai";
import { openai } from "@ai-sdk/openai";

const { object: review } = await generateObject({
  model: openai("gpt-4o"),
  schema: ProductReview,
  prompt: `Extract a structured review:\n\n${reviewText}`,
});
// review ist vollständig als ProductReview typisiert

Das Vercel AI SDK verwendet Zod nativ mit generateObject(), was es zur saubersten TypeScript-Integration macht. Es funktioniert mit OpenAI, Anthropic, Gemini und anderen Anbietern über eine einheitliche API.

JSON-Schema-Konvertierung

typescript
import { zodToJsonSchema } from "zod-to-json-schema";

const jsonSchema = zodToJsonSchema(ProductReview);
// Verwenden mit jedem Anbieter, der rohes JSON-Schema akzeptiert

Fazit: Zod + .describe() + das Vercel AI SDK ist der TypeScript-Stack für strukturierte Ausgaben. Wenn Sie im Node/Next.js-Ökosystem sind, ist dies der Weg des geringsten Widerstands.

Strukturierte Ausgabe vs. Function Calling: Wann verwenden Sie was?

Dies ist eine der häufigsten Verwirrungsquellen. Beide beinhalten Schemas, beide geben strukturierte Daten zurück -- aber sie lösen unterschiedliche Probleme.

Strukturierte Ausgabe sagt: "Gib mir Daten in genau dieser Form." Es geht um Extraktion, Klassifizierung und Formatierung. Sie ziehen strukturierte Informationen aus unstrukturiertem Text.

Function Calling (Tool Use) sagt: "Hier sind Aktionen, die Sie ausführen können -- entscheiden Sie, welche ausgeführt werden soll, und geben Sie die Argumente an." Es geht um Agent-Workflows, bei denen das Modell aus mehreren Tools auswählt und Aktionen auslöst.

Die Verwirrung macht historisch Sinn. Anthropics ursprüngliche "strukturierte Ausgabe" war buchstäblich Function Calling -- Sie definierten ein gefälschtes Tool namens extract_review und griffen die Argumente heraus. Das funktioniert noch, aber native strukturierte Ausgabe ist einfacher für reine Extraktion.

SzenarioBester AnsatzWarum
Daten aus Text extrahierenStrukturierte AusgabeDirekt, geringere Latenz, ein Schema
In Kategorien klassifizierenStrukturierte AusgabeEine Antwort, ein Schema
Agent entscheidet, welches Tool aufgerufen werden sollFunction CallingModell wählt aus mehreren Tools
Mehrstufige OrchestrierungFunction CallingSequenzielle Tool-Aufrufe
Daten extrahieren UND nächste Aktion entscheidenBeidesStrukturierte Ausgabe für Extraktion, Function Calling für Orchestrierung

Strukturierte Ausgabe treibt die Tool-Calling-Pipelines in KI-Agent-Systemen an. Sehen Sie unseren Leitfaden zu KI-Agenten für Unternehmen für die Frage, wie diese in Produktions-Workflows passen.

Fazit: Verwenden Sie strukturierte Ausgabe, wenn Sie die Form der Daten kennen. Verwenden Sie Function Calling, wenn das Modell eine Aktion wählen muss. In der Praxis verwenden die meisten Anwendungen beides -- strukturierte Ausgabe für die Datenextraktion und Function Calling für die Agent-Orchestrierung.

Produktionsmuster: Fehler, Retries und Streaming

Strukturierte Ausgabe in einer Demo zum Laufen zu bringen ist einfach. Sie in der Produktion zuverlässig zu halten erfordert drei Dinge: Verweigerungen, Validierungsfehler und Streaming.

Verweigerungsbehandlung

Manchmal verweigert ein Modell die Generierung Ihrer angeforderten Ausgabe -- typischerweise weil Sicherheitsfilter die Eingabe markiert haben. In diesem Fall geben strukturierte Ausgabe-APIs nicht Ihr Schema zurück. Sie geben eine Verweigerung zurück.

python
response = client.beta.chat.completions.parse(
    model="gpt-4o-2024-08-06",
    messages=messages,
    response_format=ProductReview,
)

# Prüfe IMMER auf Verweigerung, bevor du auf geparste Inhalte zugreifst
if response.choices[0].message.refusal:
    print(f"Model refused: {response.choices[0].message.refusal}")
else:
    review = response.choices[0].message.parsed

Wenn Sie die Verweigerungsprüfung überspringen und versuchen, auf .parsed bei einer Verweigerung zuzugreifen, erhalten Sie None und einen verwirrenden nachgelagerten Fehler. Prüfen Sie immer zuerst.

Retry-Muster mit Validierungsfeedback

Schema-Konformität wird durch Constrained Decoding garantiert, aber semantische Korrektheit nicht. Das Modell könnte {"rating": 1, "sentiment": "positive"} zurückgeben -- gültiges Schema, widersprüchlicher Inhalt. Hier kommen Validierung + Retries ins Spiel.

python
import instructor

client = instructor.from_openai(OpenAI())

# Instructor behandelt Retries automatisch
review = client.chat.completions.create(
    model="gpt-4o",
    response_model=ProductReview,
    max_retries=3,  # Retries mit Validierungsfehlerfeedback
    messages=[
        {"role": "user", "content": review_text}
    ],
)

Instructor gibt den Validierungsfehler beim Retry an das Modell zurück, damit es sich selbst korrigieren kann. Für manuelle Retry-Muster ohne Instructor:

python
from pydantic import ValidationError

for attempt in range(3):
    try:
        response = client.beta.chat.completions.parse(
            model="gpt-4o-2024-08-06",
            messages=messages,
            response_format=ProductReview,
        )
        review = response.choices[0].message.parsed
        # Führe hier zusätzliche semantische Validierung durch
        break
    except ValidationError as e:
        messages.append({"role": "assistant", "content": str(response)})
        messages.append({"role": "user", "content": f"Validation error: {e}. Fix it."})

Streaming strukturierter Ausgaben

Für große strukturierte Antworten -- lange Arrays, viele Felder, komplexe verschachtelte Objekte -- ermöglicht Streaming das progressive Rendern von Teilergebnissen.

python
import instructor

client = instructor.from_openai(OpenAI())

# Teilweise Ergebnisse streamen, während Felder befüllt werden
review_stream = client.chat.completions.create_partial(
    model="gpt-4o",
    response_model=ProductReview,
    messages=[{"role": "user", "content": review_text}],
)

for partial_review in review_stream:
    # Felder werden nacheinander befüllt, während Tokens streamen
    if partial_review.summary:
        print(f"Summary so far: {partial_review.summary}")

Ein Fallstrick: Einzelne Streaming-Chunks sind für sich allein nicht schema-gültig. Das reasoning-Feld könnte befüllt sein, während rating noch None ist. Planen Sie Ihre UI entsprechend -- zeigen Sie einen Ladezustand für nicht befüllte Felder.

Fazit: Verweigerungsprüfungen sind nicht verhandelbar. Retries mit Validierungsfeedback fangen semantische Fehler ab. Streaming lohnt sich für jede Antwort, die mehr als ein paar Sekunden dauert.

Strukturierte Ausgabe-Bibliotheken im Vergleich

Sie können strukturierte Ausgabe über native APIs verwenden, aber Bibliotheken fügen Validierung, Retries, Streaming und Multi-Provider-Unterstützung hinzu. Hier ist die Landschaft.

Instructor ist die beliebteste Option mit 11K+ GitHub-Stars und 3M+ monatlichen Downloads. Es umhüllt OpenAI, Anthropic, Gemini, Cohere, Ollama und mehr mit einer einheitlichen Pydantic-basierten Schnittstelle. Schlüsselfunktionen: automatische Retries mit Validierungsfeedback, Streaming über create_partial() und einfaches Setup (instructor.from_openai(client)). Wenn Sie ein Python-Team sind, fangen Sie hier an.

BAML verfolgt einen anderen Ansatz: Schema-first über eine benutzerdefinierte DSL. Sie definieren Schemas in .baml-Dateien und auto-generieren Clients für Python, TypeScript, Ruby und mehr. Sein SAP-Algorithmus (Schema-Aligned Parsing) behandelt unordentliche Modellausgaben elegant. Am besten für sprachübergreifende Teams oder wenn Sie Verträge zwischen Ihrer LLM-Schicht und Anwendungsschicht möchten. Trade-off: zusätzlicher Build-Schritt und eine neue Syntax zum Lernen.

LangChain bietet .with_structured_output(schema) für anbieterunabhängige strukturierte Ausgabe. Praktisch, wenn Sie bereits im LangChain-Ökosystem sind. Trade-off: Es ist eine schwere Abhängigkeit, und die Abstraktion kann anbieterspezifische Funktionen verbergen, die Sie möglicherweise benötigen.

Native APIs -- direkte Aufrufe mit response_format / output_config -- erfordern keine Abhängigkeiten außer dem Anbieter-SDK. Sie erhalten volle Kontrolle und volle Sichtbarkeit. Am besten für einfache Anwendungsfälle oder Teams, die minimale Abstraktion bevorzugen.

BibliothekSprachenAnbieterAuto-RetriesStreamingGitHub-StarsLernkurve
InstructorPython, TS15+JaJa11K+Niedrig
BAMLPython, TS, Ruby, GoAlle (DSL-agnostisch)JaJa7K+Mittel
LangChainPython, TS20+TeilweiseJa100K+Mittel-Hoch
Native APIsAlle1 pro SDKNeinJaN/ANiedrig

Die Wahl der richtigen strukturierten Ausgabe-Bibliothek ist Teil einer umfassenderen KI-Stack-Entscheidung. Wir analysieren den vollständigen Stack in unserem Best AI Stack für SaaS-Leitfaden.

Sehen Sie unsere Besten Bibliotheken für LLM-Strukturierte Ausgaben [demnächst] für einen eingehenden Vergleich von Instructor, BAML, Mirascope und mehr.

Fazit: Beginnen Sie mit Instructor für Python, native APIs für TypeScript. Wechseln Sie zu BAML, wenn Sie sprachübergreifende Schema-Verträge benötigen. Vermeiden Sie LangChain nur für strukturierte Ausgabe -- es ist zu viel des Guten.

Best Practices für Schema-Design (und häufige Fehler)

Ihr Schema-Design beeinflusst direkt die Ausgabequalität. Hier sind die Muster, die wichtig sind, und die Fehler, die Ihre Genauigkeit kosten.

Reasoning vor Antworten setzen

Wir haben dies im Pydantic-Abschnitt behandelt, aber es lohnt sich zu wiederholen, weil es die folgenreichste Design-Entscheidung ist:

python
# Vorher: Modell rät die Antwort, rationalisiert sie dann
class Bad(BaseModel):
    answer: str
    reasoning: str

# Nachher: Modell denkt zuerst, verpflichtet sich dann
class Good(BaseModel):
    reasoning: str = Field(description="Think step by step")
    answer: str

LLMs generieren von links nach rechts. Feldreihenfolge ist Prompt-Reihenfolge. Reasoning zuerst bedeutet, dass das Modell das Problem durcharbeiten muss, bevor es sich zu einer Antwort verpflichtet.

Die Anti-Pattern-Tabelle

FehlerProblemLösung
Reasoning-Feld nach AntwortModell entscheidet vor dem DenkenReasoning vor Antwort verschieben
Tief verschachtelt (4+ Ebenen)Höhere Fehlerrate, langsamere KompilierungAuf 2-3 Ebenen abflachen
Keine FeldbeschreibungenModell rät, was Sie wollen.describe() / Field(description=...) hinzufügen
Fehlende Null-BehandlungModell halluziniert einen Wert zum Ausfüllen des FeldsOptional / .nullable() verwenden
Zu große Schemas (50+ Felder)Kompilierungstimeout, QualitätsverschlechterungIn mehrere Aufrufe aufteilen
Vage Enum-OptionenModell wählt die falsche KategorieSpezifische, nicht überlappende Optionen verwenden

Nulls explizit behandeln

Wenn ein Feld möglicherweise keine Daten im Quelltext hat, machen Sie es optional. Ein erforderliches Feld zu erzwingen, wenn Daten nicht vorhanden sind, führt zu Halluzination:

python
class PersonInfo(BaseModel):
    name: str  # Immer vorhanden
    email: Optional[str] = Field(None, description="Email if mentioned, null otherwise")
    phone: Optional[str] = Field(None, description="Phone if mentioned, null otherwise")

Schemas fokussiert halten

Ein Schema pro Aufgabe. Versuchen Sie nicht, alles in einem einzigen massiven Schema zu extrahieren. Wenn Sie 50+ Felder benötigen, teilen Sie auf mehrere Extraktionsaufrufe auf. OpenAIs Strict Mode hat praktische Grenzen für Schema-Komplexität, und selbst wenn es funktioniert, verschlechtern sehr große Schemas die Ausgabequalität.

Fazit: Reasoning-first, beschreibende Felder, explizite Nulls und fokussierte Schemas. Bringen Sie diese vier richtig und Ihre Genauigkeit bei strukturierten Ausgaben steigt messbar.

Strukturierte Ausgabe mit lokalen LLMs

Sie brauchen keinen API-Anbieter für strukturierte Ausgabe. Lokale Inferenz-Engines unterstützen sie durch grammatikbasiertes Constrained Decoding -- den gleichen fundamentalen Mechanismus, der auf Ihrer eigenen Hardware läuft.

Ollama

Der einfachste Weg für lokale strukturierte Ausgabe. Ollama akzeptiert ein JSON-Schema über den format-Parameter:

python
import ollama
from pydantic import BaseModel

class Country(BaseModel):
    name: str
    capital: str
    languages: list[str]

response = ollama.chat(
    model="llama3.2",
    messages=[{"role": "user", "content": "Tell me about Japan."}],
    format=Country.model_json_schema(),
)

import json
country = Country(**json.loads(response.message.content))

Ollama verwendet XGrammar intern für Constrained Decoding. Dieselbe Garantie wie die API-Anbieter: 100% Schema-Konformität.

vLLM und SGLang

Für produktionsreife lokale Inferenz unterstützen vLLM und SGLang beide strukturierte Ausgabe durch guided_json und guided_regex-Parameter. XGrammar ist das Standard-Backend und liefert nahezu null Overhead bei der JSON-Generierung -- bis zu 3,5x schneller als alternative Grammatik-Engines.

Outlines

Outlines ist die Open-Source-Python-Bibliothek, die grammatikbasierte eingeschränkte Generierung pioniert hat. Es funktioniert mit jedem Hugging Face-Modell und unterstützt JSON-Schema, Regex und vollständige kontextfreie Grammatik (CFG/EBNF)-Einschränkungen. Es ist auch in vLLM und SGLang als Grammatik-Backend-Option integriert.

Der Hauptunterschied zu API-Anbietern: Lokale strukturierte Ausgabe hat keine Schema-Teilmengenbeschränkungen. Sie kontrollieren die Grammatik vollständig. Aber die Modellqualität variiert mehr -- ein lokales 7B-Parameter-Modell wird nicht GPT-4o oder Claude bei komplexen Extraktionsaufgaben entsprechen. Das Schema wird immer gültig sein; die Inhaltsqualität hängt vom Modell ab.

Fazit: Ollama für die Entwicklung, vLLM/SGLang mit XGrammar für die Produktion. Lokale strukturierte Ausgabe ist für die meisten Anwendungsfälle reif genug, mit dem Vorbehalt, dass kleinere Modelle qualitativ geringere Inhalte innerhalb des Schemas produzieren.

FAQ

Was ist strukturierte Ausgabe in LLMs?

Strukturierte Ausgabe ist ein Mechanismus, der garantiert, dass die Antwort eines LLM einem vordefinierten JSON-Schema entspricht. Im Gegensatz zu einfachem Text oder sogar dem JSON-Modus verwendet strukturierte Ausgabe Constrained Decoding, um sicherzustellen, dass jedes Feld, jeder Typ und jede Einschränkung in Ihrem Schema erfüllt ist -- 100% der Zeit, nicht "meistens".

Was ist der Unterschied zwischen JSON-Modus und strukturierten Ausgaben?

JSON-Modus garantiert syntaktisch gültiges JSON, erzwingt aber nicht Ihr Schema -- Sie könnten ein beliebiges gültiges JSON-Objekt erhalten. Strukturierte Ausgaben (Strict Mode) garantieren durch Constrained Decoding vollständige Schema-Konformität. Verwenden Sie Strict Mode für die Produktion; JSON-Modus ist nur relevant, wenn Sie kein Schema im Voraus haben.

Welche LLM-Anbieter unterstützen strukturierte Ausgabe nativ?

OpenAI (seit August 2024), Google Gemini (2024, erweitert 2026), Anthropic (Beta November 2025, GA Anfang 2026), Cohere und xAI (Grok) unterstützen alle native strukturierte Ausgabe. Auf der lokalen Seite unterstützen Ollama, vLLM und SGLang sie durch grammatikbasiertes Constrained Decoding.

Wie garantiert Constrained Decoding Schema-Konformität?

Das JSON-Schema wird in eine finite Zustandsmaschine (FSM) kompiliert. Bei jedem Token-Generierungsschritt sind nur Tokens erlaubt, die die Ausgabe auf einem gültigen Pfad durch die FSM halten -- ungültige Tokens erhalten ihre Logits auf negativ unendlich gesetzt. Das bedeutet, dass ungültige Tokens eine Nullwahrscheinlichkeit haben, generiert zu werden, was Ihnen eine mathematische Garantie gibt, keine statistische.

Soll ich strukturierte Ausgabe oder Function Calling verwenden?

Verwenden Sie strukturierte Ausgabe für Extraktion und Klassifizierung -- wenn Sie Daten in einer bestimmten Form möchten. Verwenden Sie Function Calling für Agent-Workflows -- wenn das Modell entscheiden muss, welche Aktion ausgeführt werden soll. Viele Produktionsanwendungen verwenden beides: strukturierte Ausgabe für die Datenextraktion und Function Calling für die Orchestrierung.

Kann ich strukturierte Ausgabe streamen?

Ja. OpenAI unterstützt Streaming mit der parse()-Methode, und Instructor bietet create_partial() für das Streaming von Pydantic-Modellen, die Feld für Feld befüllt werden. Beachten Sie, dass einzelne Streaming-Chunks nicht individuell schema-gültig sind -- Felder werden inkrementell befüllt.

Was ist die Instructor-Bibliothek?

Instructor ist die beliebteste strukturierte Ausgabe-Bibliothek (11K+ GitHub-Stars, 3M+ monatliche Downloads). Es umhüllt Anbieter-SDKs mit Pydantic-basierter Validierung, automatischen Retries mit Validierungsfeedback und Streaming-Unterstützung. Es funktioniert mit OpenAI, Anthropic, Gemini, Cohere, Ollama und 10+ anderen Anbietern.

Funktioniert strukturierte Ausgabe mit lokalen LLMs?

Ja. Ollama unterstützt strukturierte Ausgabe über den format-Parameter mit JSON-Schema. vLLM und SGLang unterstützen sie durch guided_json-Parameter. Alle drei verwenden XGrammar oder Outlines für Constrained Decoding. Die Schema-Konformitätsgarantie ist dieselbe wie bei API-Anbietern; die Inhaltsqualität hängt vom Modell ab.

Was sind häufige Schema-Design-Fehler?

Die häufigsten Fehler: das Reasoning-Feld nach dem Antwortfeld platzieren (Modell entscheidet vor dem Denken), tief verschachtelte Schemas (4+ Ebenen erhöhen Fehler), fehlende Feldbeschreibungen (Modell rät die Absicht), keine Null-Behandlung für optionale Daten (erzwingt Halluzination) und übermäßig große Schemas (50+ Felder verschlechtern die Qualität).

Fügt strukturierte Ausgabe Latenz hinzu?

Es gibt einen Schema-Kompilierungs-Overhead bei der ersten Anfrage -- typischerweise 50-200ms, während die FSM aufgebaut wird. Nachfolgende Anfragen mit demselben Schema verwenden eine gecachte FSM und fügen nahezu null Latenz hinzu. Für die meisten Anwendungen ist dies im Vergleich zur gesamten Modell-Inferenzzeit vernachlässigbar.

Kann ich strukturierte Ausgabe mit Bildern oder multimodalen Eingaben verwenden?

Ja. Strukturierte Ausgabe gilt für das Antwort-Format, nicht die Eingabe. Sie können ein Bild an GPT-4o oder Gemini mit einem strukturierten Ausgabe-Schema senden und eine schema-konforme Analyse des Bildes zurückerhalten. Dies ist leistungsstark für visuelle Extraktions-Workflows -- Extrahieren strukturierter Daten aus Quittungen, Formularen oder Produktbildern.

Quellen

Tags

llm strukturierte ausgabestructured outputsjson schemapydanticzodopenaianthropicgemini

Diesen Artikel teilen

Ihr Projekt starten

Bereit, etwas Außergewöhnliches zu bauen?

Machen wir aus Ihrer Vision ein fertiges Produkt. Unser Team baut mit Ihnen Software, die spürbar etwas bewegt.