Der naive Weg, ein LLM um JSON zu bitten, funktioniert in der Demo und bricht in Produktion. Wir zeigen den belastbaren Pfad mit Claude Tool Use und Structured Outputs: Schema-Design, Validierung, Retries und die Kostenfrage.
Warum "gib mir JSON" in Produktion scheitert
Du willst, dass ein Sprachmodell nicht nur Text ausgibt, sondern Daten, die dein System direkt weiterverarbeitet: einen Datensatz für die Datenbank, ein Objekt für die API, ein Feld im CRM. Der naive Weg, im Prompt einfach Antworte ausschließlich als JSON zu schreiben, sieht in der ersten Demo perfekt aus und bricht in Produktion. Mal steht ein höflicher Einleitungssatz vor der geschweiften Klammer, mal ist die Rechnungssumme als String statt als Zahl formatiert, mal fehlt bei jedem zwanzigsten Aufruf ein Pflichtfeld. Jeder dieser Fälle killt deine Pipeline an genau der Stelle, an der json.loads() läuft.
Das Problem ist nicht das Modell, sondern die Methode. Freitext ist ein weiches Ziel: Es gibt keine Garantie, dass das Ergebnis maschinenlesbar ist. Wenn du Claude in einen automatisierten Ablauf einbaust (Rechnungen auslesen, Leads anreichern, E-Mails klassifizieren), brauchst du eine harte Zusage über die Form der Antwort. Genau die liefern zwei Mechanismen: erzwungenes Tool Use und Structured Outputs.
Tool Use als Vertrag über die Datenstruktur
Der belastbarste Weg zu sauberem JSON führt über die Tool-Definition. Du beschreibst ein Werkzeug nicht, weil du es ausführen willst, sondern weil sein input_schema exakt die Struktur vorgibt, die Claude produzieren soll. Setzt du zusätzlich tool_choice auf {"type": "tool", "name": "extract_invoice"}, dann muss das Modell genau dieses Tool aufrufen. Die Antwort kommt als tool_use-Block zurück, dessen input-Feld schon ein Objekt ist, das dem Schema folgt. Kein Vortext, keine Backticks, kein Parsing von Prosa.
Der Unterschied in der Praxis: Statt einen Absatz Text zu zerlegen, greifst du direkt auf response.content[0].input zu. Das ist der Punkt, an dem viele DACH-Teams von einer Bastellösung zu etwas werden, das man nachts unbeaufsichtigt laufen lassen kann. Neuere Modellversionen bieten darüber hinaus einen strikten Structured-Outputs-Modus, der die Schema-Treue nicht nur nahelegt, sondern erzwingt. Beide Ansätze verfolgen dasselbe Ziel: Die Form der Antwort ist Teil des Vertrags mit dem Modell, nicht eine Bitte im Prompt.
Das Schema ist deine eigentliche Prompt-Arbeit
Bei strukturierter Extraktion verlagert sich die Steuerung vom Fließtext-Prompt ins Schema. Ein gutes input_schema ist präziser als drei Absätze Anweisung. Nutze enum für alles, was einen festen Wertebereich hat (Status, Kategorie, Sprache), damit das Modell nicht kreativ wird. Markiere echte Pflichtfelder über required, damit fehlende Werte auffallen statt still zu verschwinden. Und schreib in jedes Feld eine description, denn diese Beschreibung liest das Modell wie eine Anweisung.
Ein Beispiel für die Rechnungsextraktion: Ein Feld net_amount vom Typ number mit der Beschreibung Nettobetrag in Euro, ohne Währungssymbol, Punkt als Dezimaltrenner löst mehr Probleme als jede globale Anweisung im Prompt. Für Werte, die auch fehlen dürfen, arbeite bewusst mit einem null-fähigen Typ statt das Feld einfach wegzulassen: Ein explizites null ist ein sauberes Signal, eine geratene Zahl ist eine Zeitbombe in deiner Buchhaltung.
- enum statt Freitext für alle Kategorien und Status.
- Beschreibungen als Mini-Prompts pro Feld, inklusive Format und Einheit.
- Verschachtelung flach halten: zwei bis drei Ebenen sind belastbar, tiefer steigt die Fehlerquote.
Validieren, auch wenn das Schema greift
Ein erzwungenes Schema garantiert die Form, nicht die Richtigkeit. Claude kann strukturell korrektes JSON liefern, in dem der Nettobetrag trotzdem falsch abgelesen ist oder ein Datum im falschen Jahrhundert steht. Deshalb gehört hinter den API-Aufruf immer eine zweite Instanz, die den Inhalt prüft. In Python ist Pydantic dafür der Standard: Du spiegelst dein JSON-Schema als Modell, parst die Antwort dagegen und fängst Typ- und Bereichsfehler ab, bevor sie in die Datenbank wandern.
Baue diesen Check als Schleife: Wenn die Validierung fehlschlägt, schick die konkrete Fehlermeldung zurück an das Modell und lass es die Extraktion korrigieren. In der Praxis reicht meist ein einziger Nachschlag, um die verbleibenden ein bis zwei Prozent kaputter Antworten aufzufangen. Wichtig ist, den Retry hart zu deckeln (zwei Versuche, dann in eine manuelle Prüf-Queue), damit ein hartnäckiger Sonderfall nicht in einer Endlosschleife dein Token-Budget verbrennt.
Kosten und Latenz realistisch einplanen
Structured Outputs sind nicht gratis. Ein detailliertes Schema wandert bei jedem Aufruf als Eingabe mit und kostet je nach Umfang einige hundert Tokens zusätzlich. Bei einem Ablauf, der zehntausende Dokumente pro Monat verarbeitet, summiert sich das. Zwei Hebel halten die Rechnung klein: das richtige Modell und das richtige Bündeln.
Für klar umrissene Extraktion aus mittellangen Texten ist ein schnelles, günstiges Modell wie Claude Haiku fast immer die richtige Wahl. Es kostet je Million Tokens etwa ein Drittel eines Sonnet-Modells und liefert bei sauber definiertem Schema kaum schlechtere Ergebnisse, weil das Schema die schwere Arbeit übernimmt. Ein größeres Modell brauchst du erst, wenn echtes Schlussfolgern über den Text nötig wird. Prüfe die aktuelle Preisliste, die Verhältnisse ändern sich mit jeder Modellgeneration. Wo du nicht auf die Antwort warten musst, senkt die Batch-Verarbeitung die Kosten noch einmal deutlich, im Gegenzug für längere Laufzeiten.
Eine Pipeline von Ende zu Ende
So sieht ein belastbarer Ablauf für Eingangsrechnungen konkret aus. Erstens: Rohtext gewinnen (PDF-Text extrahieren oder das Dokument direkt an ein multimodales Modell geben). Zweitens: Aufruf mit erzwungenem Tool und einem Schema, das vendor, invoice_number, net_amount, vat_rate und ein line_items-Array enthält. Drittens: Pydantic-Validierung mit Plausibilitätsregeln, etwa dass Netto plus Steuer den Bruttobetrag ergibt. Viertens: Bei Erfolg der Datensatz in Supabase oder dein ERP, bei Fehlschlag ein Retry, danach die manuelle Queue.
Dasselbe Muster trägt für Lead-Anreicherung (Firmentext rein, strukturierte Felder wie Branche, Mitarbeiterzahl und Region raus), für E-Mail-Triage im Posteingang oder für das Normalisieren von Formularantworten. Der Kern bleibt identisch: klares Schema, erzwungener Tool-Aufruf, Validierung dahinter, gedeckelter Retry. Was sich ändert, sind nur die Felder.
Wann sich der Aufwand lohnt
Für einen einmaligen Export oder eine Handvoll Datensätze reicht ein simpler Prompt und ein manueller Blick auf das Ergebnis. Der beschriebene Aufbau zahlt sich ab dem Moment aus, in dem dieselbe Extraktion wiederholt und unbeaufsichtigt läuft und ein falscher Datensatz echten Schaden anrichtet: in der Buchhaltung, im CRM, in einer Kundenmail. Ab dann ist der Unterschied zwischen 98 und 100 Prozent verlässlicher Verarbeitung genau der Unterschied zwischen einem Werkzeug, dem du traust, und einem, das du jede Woche nachkontrollierst.
Die Investition ist überschaubar: ein sauber durchdachtes Schema, eine Validierungsschicht und eine ehrliche Fehler-Queue für die Fälle, die kein Modell allein löst. Das ist keine Forschung, das ist solides Handwerk. Und es ist der Punkt, an dem eine KI-Integration aufhört, ein Demo-Trick zu sein, und anfängt, ein Teil deiner Infrastruktur zu werden.