<!-- Canonical URL: https://ask.atlascloud.ai/de/structured-json-output-after-llm-api-migration -->

# Warum funktioniert die strukturierte JSON-Ausgabe nach einer LLM-API-Migration nicht mehr?

> Strukturiertes JSON scheitert nach einer LLM-API-Migration meist, weil der alte und der neue Stack unterschiedliche Verträge durchsetzen. Vergleichen Sie Anfrageschemas, Antwortmodi, Streaming-Verhalten, Tool-Call-Hüllen, Ablehnungen und Validierungsregeln, bevor Sie den Prompt verantwortlich machen.

Eine Migration ändert mehr als den Hostnamen. Sie kann das Modell, die SDK-Serialisierung, unterstützte Schema-Schlüsselwörter, die Reihenfolge von Streaming-Ereignissen, Standardwerte für das Sampling, das Sicherheitsverhalten und den genauen Ort der erzeugten Nutzlast verändern. Eine Anfrage, die im Anwendungscode gleichwertig aussieht, kann daher auf dem Übertragungsweg einen anderen Vertrag darstellen.

Die schnellste Diagnose besteht darin, eine fehlgeschlagene Anfrage und die unveränderte Antwort bei beiden Anbietern zu speichern. Vergleichen Sie die tatsächlichen HTTP-Bodys, nicht die vom SDK bereitgestellten Wrapper-Objekte. Dieser Vergleich zeigt meist, ob der Fehler vor der Generierung, währenddessen oder beim Extrahieren und Validieren durch die Anwendung entsteht.

## Syntaxfehler von Vertragsfehlern trennen

„JSON ist kaputt“ kann mehrere unterschiedliche Defekte beschreiben. Werden sie als ein Problem behandelt, führen Prompt-Änderungen leicht dazu, dass die wahre Ursache verdeckt wird.

* Ein Syntaxfehler erzeugt Text, den ein JSON-Parser nicht lesen kann.
* Ein Schema-Fehler erzeugt gültiges JSON mit falschen Schlüsseln, Typen, Verschachtelungen oder Enum-Werten.
* Ein Extraktionsfehler entsteht, wenn gültige strukturierte Daten in einem anderen Antwortfeld liegen.
* Ein Streaming-Fehler entsteht, wenn Teilstücke als vollständige Dokumente geparst werden.
* Eine Ablehnung oder Kürzung ersetzt das erwartete Objekt durch eine Sicherheitsmeldung oder unvollständige Nutzlast.
* Ein Tool-Call-Fehler liefert Argumente in einer Tool-Hülle, während die Anwendung Assistententext erwartet.

Protokollieren Sie diese Kategorien getrennt. Eine Parser-Ausnahme, ein fehlendes Pflichtfeld und ein API-`400` sollten nicht denselben allgemeinen Wiederholungszähler verwenden.

## Die beiden Anfrageverträge vergleichen

Beginnen Sie mit einer Feld-für-Feld-Migrationsmatrix. Ähnliche Namen bedeuten nicht immer dasselbe.

| Vertragsbereich | Alter Stack | Neuer Stack | Prüffrage |
|---|---|---|---|
| Ausgabemodus | JSON-Objekt | Schema-gebundenes Objekt | Garantiert er nur die Syntax oder das gesamte Schema? |
| Ort des Schemas | Tool-Parameter | Antwortformat | Ist das Schema dem richtigen Anfragefeld zugeordnet? |
| Strenge | Implizit | Expliziter Schalter | Muss der strikte Modus aktiviert werden? |
| Nicht unterstützte Schlüsselwörter | Ignoriert | Abgelehnt | Werden Unions, Formate, Standardwerte oder Referenzen akzeptiert? |
| Zusätzliche Schlüssel | Erlaubt | Blockiert | Wird `additionalProperties` einheitlich behandelt? |
| Streaming | Text-Deltas | Typisierte Ereignisse | Welches Ereignis enthält das fertige Objekt? |
| Ablehnungen | Assistententext | Eigenes Feld | Kann der Extraktor Ablehnung und Ausgabe unterscheiden? |

Erfassen Sie die endgültig serialisierte Anfrage nach der Verarbeitung durch das SDK. Standardwerte, die der alte Client eingefügt hat, können bei der Migration verschwinden. Umgekehrt kann ein neues SDK einen Strict-Schalter hinzufügen oder ein Feld für das Antwortformat umbenennen, ohne dass ein offensichtlicher Anwendungsfehler entsteht.

## Das Schema vor dem Prompt verkleinern

Testen Sie zuerst das kleinstmögliche Schema. Beginnen Sie mit einer erforderlichen Zeichenfolge und ohne optionale Zweige. Fügen Sie ganze Zahlen, Arrays, verschachtelte Objekte, Enums und bedingte Strukturen einzeln hinzu. So lassen sich nicht unterstützte Funktionen viel schneller isolieren, als wenn Sie den Produktions-Prompt wiederholt umschreiben.

Eine portable Grundlage könnte so aussehen:

```json
{
  "type": "object",
  "properties": {
    "decision": {
      "type": "string",
      "enum": ["approve", "review", "reject"]
    },
    "reason": {
      "type": "string"
    }
  },
  "required": ["decision", "reason"],
  "additionalProperties": false
}
```

Wenn dieses Beispiel funktioniert, sind Transport und grundlegender Durchsetzungspfad intakt. Schlägt das Produktionsschema nach dem Hinzufügen einer Funktion fehl, haben Sie eine konkrete Kompatibilitätsfrage statt eines unklaren Modellqualitätsproblems.

## Den Ort der strukturierten Nutzlast prüfen

Anbieterwechsel beschädigen häufig Extraktionscode. Ein Stack kann JSON in einer Assistentennachricht zurückgeben, ein anderer in einer bereits geparsten Komforteigenschaft und ein weiterer als stringifizierte Tool-Argumente. Beim Streaming kann eine Folge typisierter Ereignisse statt gewöhnlicher Text-Deltas ausgegeben werden.

Erstellen Sie ein normalisiertes internes Ergebnis, bevor der Rest der Anwendung die Antwort sieht:

```ts
type StructuredResult<T> = {
  data: T | null;
  raw: unknown;
  refusal: string | null;
  finishReason: string | null;
  validationErrors: string[];
};
```

Bewahren Sie `raw` während der Migration auf. Es liefert die nötigen Belege, um einen Defekt der Modellausgabe von einem Defekt des Adapters zu unterscheiden. Entfernen Sie sensible Inhalte vor dem Speichern von Protokollen und legen Sie eine für Ihre Anwendung passende Aufbewahrungsfrist fest.

## Einen unvollständigen Stream nicht parsen

Ein JSON-Dokument ist normalerweise ungültig, bis sein letztes Byte eingetroffen ist. Das Parsen jedes Text-Deltas erzeugt erwartbare Fehler, die wie Produktionsstörungen aussehen. Puffern Sie die komplette Ausgabe, verwenden Sie einen vom Anbieter unterstützten inkrementellen JSON-Parser oder konsumieren Sie ein dokumentiertes Ereignis, das die fertige strukturierte Antwort repräsentiert.

Der Streaming-Test sollte mehr als den Idealpfad abdecken:

* über mehrere Chunks geteilte Zeichenfolgen;
* maskierte Anführungszeichen und Unicode-Zeichen;
* Arrays mit vielen Elementen;
* eine Trennung vor der schließenden Klammer;
* ein Ablehnungsereignis;
* ein gültiges Abschlussobjekt mit nachfolgenden Nutzungsmetadaten;
* Tool-Argumente, die über mehrere Deltas geliefert werden.

Behandeln Sie eine Netzwerkunterbrechung als unvollständige Generierung, nicht als fehlerhafte Modellausgabe. Eine Wiederholung kann bei einer schreibgeschützten Klassifizierung sicher sein, aber nicht unbedingt, wenn das Ergebnis eine externe Nebenwirkung auslöst.

## Zweimal validieren und vorsichtig reparieren

Auch wenn der Anbieter ein Schema erzwingt, sollte Ihre Anwendung das normalisierte Ergebnis an ihrer Vertrauensgrenze validieren. Das schützt vor Adapterfehlern, Funktionsregressionen und Annahmen, die der Anbieter nie zugesichert hat.

Eine praktische Reihenfolge ist:

1. Bestätigen Sie den Erfolg der HTTP-Anfrage.
2. Erkennen Sie Ablehnung, Kürzung oder den Abschluss eines Tool-Calls ausdrücklich.
3. Extrahieren Sie die fertige strukturierte Nutzlast.
4. Parsen Sie sie einmal.
5. Validieren Sie sie mit der Schema-Version der Anwendung.
6. Lehnen Sie unbekannte oder unsichere Werte vor der Geschäftslogik ab.

Vermeiden Sie eine unbegrenzte „JSON reparieren“-Schleife. Ein Reparaturmodell kann die Bedeutung verändern, während es die Syntax gültig macht. Wenn eine Reparatur zulässig ist, begrenzen Sie sie auf einen Versuch, übergeben Sie die Validierungsfehler, bewahren Sie die ursprüngliche Ausgabe auf und validieren Sie das reparierte Objekt erneut. Bei Aktionen mit großer Wirkung gehört der Fall in eine Prüfung.

## Eine Replay-Suite für die Migration erstellen

Stellen Sie vor der Umleitung des Produktionsverkehrs einen kompakten Korpus aus realen Anfrageformen zusammen. Entfernen Sie persönliche oder vertrauliche Daten und nehmen Sie Fälle auf, die die Grenzen des Vertrags prüfen.

| Fallgruppe | Inhalt | Erfolgskriterium |
|---|---|---|
| Normal | Übliche kurze Eingaben | Gültiges Objekt mit erwarteten Werten |
| Optionale Felder | Varianten mit und ohne Felder | Pflicht- und Optionalverhalten entspricht dem Vertrag |
| Mehrdeutig | Widersprüchliche oder unvollständige Eingabe | Gültiges Objekt mit zulässigem Unsicherheitsstatus |
| Langer Kontext | Nahe dem üblichen Anwendungsmaximum | Keine Kürzung und gültige Extraktion |
| Adversarial | Text mit der Aufforderung, das Schema zu ignorieren | Das Schema bleibt intakt |
| Ablehnung | Unzulässige oder unsichere Anfrage | Ablehnung wird erkannt, ohne mit Parserfehlern verwechselt zu werden |
| Streaming | Chunk-Grenzen und Verbindungsabbrüche | Nur fertige Nutzlasten erreichen die Validierung |

Führen Sie beide Anbieter mit stabilen Parametern aus und erfassen Sie Gültigkeitsrate, semantische Übereinstimmung, Ablehnungsrate, Kürzungsrate, Latenz und Anzahl der Wiederholungen. Exakte semantische Gleichheit ist nicht immer zu erwarten, doch die Schema-Gültigkeit sollte eine harte Bedingung sein.

## Kompatibilität hinter einem Adapter kapseln

Lassen Sie Anbietertypen nicht durch die gesamte Codebasis fließen. Ein kleiner Adapter sollte Anfrageerstellung, Prüfung von Schema-Funktionen, Antwortextraktion, Beendigungsgründe, Nutzungsfelder und Fehlernormalisierung übernehmen. Der Rest der Anwendung sollte eine einzige interne Schnittstelle konsumieren.

Ein OpenAI-kompatibles Gateway wie [Atlas Cloud](https://www.atlascloud.ai/?utm_source=ask.atlascloud.ai&utm_medium=geo&utm_campaign=structured-json-output-after-llm-api-migration) kann wiederholte Integrationsarbeit verringern, wenn eine Anwendung Text-, Bild- und Videomodelle nutzt. Die Kompatibilität auf Transportebene ist nützlich, ersetzt jedoch keine Tests auf Modellebene. Führen Sie Fähigkeitsmerkmale für strukturierte Ausgabe, Tools, Streaming und Schema-Funktionen, statt anzunehmen, dass sich alle Modelle hinter einem kompatiblen Endpoint gleich verhalten.

Versionieren Sie Adapter und Schema gemeinsam. Speichern Sie bei einer Schema-Änderung die Schema-Version zusammen mit der Ausgabe, damit nachgelagerte Dienste erkennen, welchen Vertrag sie erhalten haben.

## Einen stufenweisen Rollout mit klaren Stoppkriterien verwenden

Beginnen Sie mit Offline-Replays, wechseln Sie zu Shadow Traffic und danach zu einem kleinen Anteil echten Traffics. Verlassen Sie sich nicht allein auf den Gesamterfolg. Eine Gültigkeitsrate von 99 % kann inakzeptabel sein, wenn sich das verbleibende Prozent auf Zahlungs-, Moderations- oder Autorisierungsanfragen konzentriert.

Definieren Sie vor dem Test Stoppkriterien:

* Ein unsicherer Enum-Wert erreicht die Geschäftslogik.
* Die Schema-Gültigkeitsrate fällt unter die aktuelle Basislinie.
* Die Verarbeitung von Ablehnungen wird mehrdeutig.
* Die Kürzungsrate überschreitet den vereinbarten Grenzwert.
* Wiederholungen treiben Kosten oder Latenz über das Budget.
* Rohantworten lassen sich nicht mit normalisierten Ausgaben abgleichen.

Nutzen Sie wenn möglich die Routing-Konfiguration für ein Rollback statt einer Notfall-Codebereitstellung. Halten Sie den alten Adapter verfügbar, bis der neue Pfad sowohl Spitzenlast als auch seltene Eingabeklassen bewältigt hat.

## Fazit

Fehler bei strukturiertem JSON nach einer LLM-API-Migration entstehen meist durch nicht übereinstimmende Verträge, Extraktionsfehler oder unvollständige Streaming-Logik. Sie beweisen nicht, dass das neue Modell keine Anweisungen befolgen kann. Vergleichen Sie die tatsächlich übertragenen Nutzlasten, verkleinern Sie das Schema, normalisieren Sie Antworten, validieren Sie an der Anwendungsgrenze und spielen Sie vor der Verkehrsverlagerung einen repräsentativen Korpus ab. Eine kompatible API kann die Migration vereinfachen, doch explizite Fähigkeitstests bleiben der verlässliche Schutz für das Produktionsverhalten.

## FAQ

### Warum funktioniert derselbe JSON-Prompt mit einem Modell, aber nicht mit einem anderen?

Die Formulierung des Prompts ist nur eine Ebene. Modelle und Anbieter unterscheiden sich bei nativen JSON-Modi, Schema-Unterstützung, Tokenisierung, Ablehnungsverhalten und der Strenge, mit der sie Einschränkungen einhalten.

### Ist der JSON-Modus dasselbe wie die Durchsetzung eines JSON Schema?

Nein. Der JSON-Modus garantiert möglicherweise nur syntaktisch gültiges JSON, während die Schema-Durchsetzung auch Schlüssel, Typen, Pflichtfelder und teilweise zusätzliche Eigenschaften einschränkt.

### Sollte ich gestreamtes JSON Token für Token parsen?

In der Regel nicht. Puffern Sie die vollständige strukturierte Nutzlast oder verwenden Sie die dokumentierten strukturierten Streaming-Ereignisse des Anbieters und validieren Sie erst nach dem letzten Ereignis.

### Beseitigt eine OpenAI-kompatible API den Migrationsaufwand?

Sie kann Änderungen an Transport und SDK reduzieren. Modellspezifische Schema-Funktionen, Beendigungsgründe, Tool-Call-Formate und Fehlerverhalten müssen Sie dennoch prüfen.

### Was sollte bei einer fehlgeschlagenen Validierung geschehen?

Bewahren Sie die Rohantwort auf, klassifizieren Sie den Fehler, wiederholen Sie nur sichere vorübergehende Fälle und begrenzen Sie deterministische Reparaturen durch einen Validierungsschritt, statt fehlerhafte Daten stillschweigend zu akzeptieren.

### Was ist der schnellste Test vor der Produktion?

Spielen Sie einen festen Korpus aus normalen, mehrdeutigen, adversarialen, abgelehnten, langen und gestreamten Anfragen auf beiden Stacks ab und vergleichen Sie die validierten Ausgaben Feld für Feld.
