DEV Community

Cover image for OpenAI Strukturierte Ausgaben: Anleitung zur Nutzung
Emre Demir
Emre Demir

Posted on • Originally published at apidog.com

OpenAI Strukturierte Ausgaben: Anleitung zur Nutzung

Am Ende dieses Leitfadens können Sie strukturierte OpenAI-Ausgaben direkt aus Ihrem Code abrufen: Sie übergeben dem Modell ein JSON-Schema, setzen strict: true und erhalten eine Antwort, die der angeforderten Form entspricht. Danach lesen Sie die Antwort, behandeln Grenzfälle und generieren API-Testsammlungen in Apidog, um zu prüfen, ob die Nutzlast wirklich konform ist.

Testen Sie Apidog noch heute

Was Sie vor dem Start benötigen

Strukturierte Ausgaben schränken die Generierung des Modells so ein, dass die Antwort einem von Ihnen bereitgestellten JSON-Schema entspricht. Wenn Sie ein Schema mit strict: true übergeben, darf das Modell keine Felder, Typen oder Enum-Werte ausgeben, die gegen dieses Schema verstoßen.

Das ist robuster als Prompts wie „Antworte nur mit JSON“. Solche Prompts liefern zwar oft gültiges JSON, aber nicht zuverlässig die erwartete Struktur. Strukturierte Ausgaben verschieben den Vertrag von einer Anweisung im Prompt zu einer Einschränkung zur Dekodierungszeit.

Sie benötigen:

  • Einen OpenAI API-Schlüssel als Umgebungsvariable OPENAI_API_KEY
  • Ein Modell, das strikte Schema-Durchsetzung unterstützt
  • Ein JSON-Schema für die gewünschte Ausgabeform
  • Optional: ein Tool wie Apidog, um die Antwort gegen das Schema zu testen

Wählen Sie das richtige Modell

Strukturierte Ausgaben sind bei neueren OpenAI-Modellen verfügbar, beginnend mit der GPT-4o-Familie und fortgesetzt in der GPT-5-Serie. Die OpenAI-Dokumentation empfiehlt derzeit, neue Projekte mit dem neuesten Flaggschiffmodell zu starten, zum Beispiel gpt-5.5 zum Zeitpunkt der Erstellung.

Wichtig: Prüfen Sie vor dem Einsatz, ob die konkrete Modell-ID strict: true unterstützt. Die Unterstützung ist an Modellversionen gebunden.

OpenAI bietet zwei ähnliche, aber unterschiedliche Funktionen:

JSON-Modus

{
  "response_format": {
    "type": "json_object"
  }
}
Enter fullscreen mode Exit fullscreen mode

Der JSON-Modus garantiert syntaktisch gültiges JSON. Er garantiert aber nicht, dass Felder, Typen oder Pflichtwerte Ihrem Schema entsprechen.

Strukturierte Ausgaben

{
  "response_format": {
    "type": "json_schema",
    "json_schema": {
      "strict": true
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Strukturierte Ausgaben garantieren gültiges JSON und Schema-Konformität. Für neuen Code ist das in der Regel die bessere Wahl.

Funktion JSON-Modus Strukturierte Ausgaben mit strict: true
Parameter response_format: {"type":"json_object"} response_format mit type: "json_schema"
Gültiges JSON Ja Ja
Entspricht Ihrem Schema Nein Ja
Erforderliche Felder erzwungen Nein Ja
Typen und Enums erzwungen Nein Ja
Nachgelagerte Validierung Immer nötig Weiterhin empfohlen

Hinweis zu APIs: Der Chat-Completions-Endpunkt verwendet response_format. Die neuere Responses API drückt dieselbe Idee über text.format mit type: "json_schema" aus. Die Schema-Regeln sind gleich; nur der Wrapper unterscheidet sich.

Ihre erste Anfrage stellen

Angenommen, Sie möchten ein Support-Ticket in einen typisierten Datensatz extrahieren. Der folgende curl-Aufruf sendet eine Chat-Completions-Anfrage mit einem strikten Schema:

curl https://api.openai.com/v1/chat/completions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.5",
    "messages": [
      {
        "role": "system",
        "content": "Extract the ticket into the schema."
      },
      {
        "role": "user",
        "content": "My checkout 500s every time I use a saved card. Started today. Account: acct_8842."
      }
    ],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "support_ticket",
        "strict": true,
        "schema": {
          "type": "object",
          "properties": {
            "summary": {
              "type": "string"
            },
            "category": {
              "type": "string",
              "enum": ["billing", "bug", "account", "other"]
            },
            "severity": {
              "type": "integer"
            },
            "account_id": {
              "anyOf": [
                { "type": "string" },
                { "type": "null" }
              ]
            }
          },
          "required": ["summary", "category", "severity", "account_id"],
          "additionalProperties": false
        }
      }
    }
  }'
Enter fullscreen mode Exit fullscreen mode

Die Antwort lesen

Das Modell gibt eine Nachricht zurück, deren content ein JSON-String ist. Dieser String entspricht dem Schema.

Beispiel:

{
  "summary": "Checkout returns HTTP 500 when paying with a saved card",
  "category": "bug",
  "severity": 3,
  "account_id": "acct_8842"
}
Enter fullscreen mode Exit fullscreen mode

account_id verwendet anyOf mit null. Das ist die übliche Methode, um ein Feld in strukturierten Ausgaben als „optional“ zu modellieren: Der Schlüssel ist vorhanden, sein Wert kann aber null sein.

Bleiben Sie innerhalb der unterstützten Schema-Untermenge

Strukturierte Ausgaben akzeptieren eine Untermenge von JSON Schema. Diese Einschränkung hilft OpenAI, Schemas zuverlässig durchzusetzen und zu cachen.

Beachten Sie diese Regeln:

  • Die Wurzel muss ein Objekt sein.

    Ein Array oder String auf oberster Ebene ist nicht erlaubt. Packen Sie Listen in eine Objekteigenschaft.

  • Jede Eigenschaft muss in required stehen.

    Klassisch optionale Felder gibt es nicht. Verwenden Sie stattdessen anyOf mit null.

  • additionalProperties muss bei Objekten false sein.

    So verhindern Sie, dass das Modell zusätzliche Schlüssel erzeugt.

  • Schemas sollten kompakt bleiben.

    Ein Schema kann grob bis zu 100 Objekteigenschaften und bis zu 5 Verschachtelungsebenen enthalten. Glätten Sie komplexe Strukturen, wenn möglich.

  • Nicht alle JSON-Schema-Keywords werden erzwungen.

    Keywords wie pattern, format, minLength oder minimum sind nicht garantiert. Prüfen Sie solche Regeln nachgelagert selbst.

  • Der erste Aufruf mit einem neuen Schema kann langsamer sein.

    OpenAI kompiliert und cached das Schema. Der erste Request kann Sekunden dauern, bei komplexen Schemas auch länger.

Strukturierte Ausgaben garantieren die Form der Antwort, aber nicht automatisch jede Geschäftsregel. Wenn Sie schon einmal optionale oder Union-Felder mit oneOf/anyOf/allOf modelliert haben, ist das mentale Modell ähnlich: Das Schema begrenzt die Struktur, aber Werte müssen weiterhin validiert werden.

Ablehnungen und Kürzungen behandeln

Es gibt Fälle, in denen Sie keinen schemakonformen Inhalt erhalten.

Wenn das Modell eine unsichere Anfrage ablehnt, gibt es stattdessen ein refusal-Feld in der Nachricht zurück. Prüfen Sie dieses Feld vor dem Parsen:

import json

msg = response.choices[0].message

if msg.refusal:
    handle_refusal(msg.refusal)
else:
    ticket = json.loads(msg.content)
Enter fullscreen mode Exit fullscreen mode

Das ist robuster als Text nach Entschuldigungen oder Sicherheitsformulierungen zu durchsuchen.

Weitere Fälle, die Sie behandeln sollten:

  • max_tokens wird erreicht:

    Das JSON kann mitten im Objekt abgeschnitten werden.

  • Parallele Tool-Aufrufe:

    Strukturierte Ausgaben unterstützen keine parallelen Tool-Aufrufe. Setzen Sie parallel_tool_calls auf false, wenn Sie Tool-Aufrufe kombinieren.

Beispiel:

{
  "parallel_tool_calls": false
}
Enter fullscreen mode Exit fullscreen mode

So testen Sie es in Apidog

Der strikte Modus erzwingt das Schema zur Generierungszeit. Trotzdem sollten Sie testen. Modelle werden geändert, Prompts werden angepasst, Schemas entwickeln sich weiter, und Fehler in Ablehnungspfaden oder Token-Limits können in Produktion sichtbar werden.

Hier passt Apidog: Apidog erzwingt das Schema nicht auf Modellebene, validiert aber die zurückerhaltene Antwort gegen das erwartete Schema.

Ein praktischer Workflow:

  1. OpenAI-Anfrage in Apidog anlegen

    Erstellen Sie den Chat-Completions-Request inklusive response_format-Block. Speichern Sie ihn in einer Collection.

  2. Antwort gegen das Schema validieren

    Fügen Sie Assertions hinzu:

    • category ist einer der erlaubten Enum-Werte
    • severity ist eine Ganzzahl
    • account_id ist ein String oder null
    • keine zusätzlichen Felder sind vorhanden

Apidog kann die Antwort gegen ein JSON-Schema validieren. Hängen Sie dasselbe Schema an, das Sie an OpenAI senden.

  1. Collection in CI ausführen

    Führen Sie die Tests bei jeder Änderung an Modell, Prompt oder Schema aus. Wenn die Antwort nicht mehr dem Vertrag entspricht, schlägt der Build fehl.

  2. Mock-API für Konsumenten bereitstellen

    Bevor der Live-Aufruf fertig ist, können Sie eine Mock-API erstellen, die schemakonforme Beispielantworten zurückgibt. Frontend, Backend-Consumer und Integrationstests können dadurch parallel entwickelt werden.

Dieser Mock-Schritt ist besonders hilfreich: Alles, was die strukturierte Ausgabe konsumiert, kann gegen eine stabile Vertragsform entwickelt werden, bevor der echte OpenAI-Aufruf eingebunden wird.

Laden Sie Apidog herunter, um Anfrage, Assertions und Mock an einem Ort zu verwalten.

Häufig gestellte Fragen

Ist der JSON-Modus veraltet?

Nein. Der JSON-Modus funktioniert weiterhin und garantiert gültiges JSON. Er erzwingt aber kein Schema. Für neuen Code ist json_schema mit strict: true die stärkere Option.

Verwenden Sie den JSON-Modus nur, wenn:

  • Ihr Modell keine strukturierten Ausgaben unterstützt
  • Sie keine feste Antwortform benötigen
  • Sie die Validierung vollständig selbst übernehmen möchten

Kann die Wurzel meines Schemas ein Array sein?

Nein. Die oberste Ebene muss ein Objekt sein.

Stattdessen:

{
  "type": "object",
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  },
  "required": ["items"],
  "additionalProperties": false
}
Enter fullscreen mode Exit fullscreen mode

Wie mache ich ein Feld optional?

Strukturierte Ausgaben verlangen, dass jede Eigenschaft in required steht. Modellieren Sie „nicht vorhanden“ deshalb als null.

Beispiel:

{
  "account_id": {
    "anyOf": [
      { "type": "string" },
      { "type": "null" }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Der Schlüssel account_id ist immer vorhanden. Der Wert kann aber null sein.

Kann ich Validierung komplett überspringen?

Nicht vollständig.

Die Struktur ist garantiert, solange kein Sonderfall wie refusal oder abgeschnittenes JSON eintritt. Regeln auf Werteebene wie pattern, format oder numerische Bereiche sollten Sie weiterhin selbst prüfen.

Wenn Sie mit JSON Schema noch nicht vertraut sind, hilft dieser JSON Schema Primer.

Welche Modelle soll ich verwenden?

Strukturierte Ausgaben funktionieren mit GPT-4o und neueren Modellen, einschließlich der GPT-5-Serie. Die OpenAI-Dokumentation empfiehlt, neue Projekte mit dem aktuellen Flaggschiffmodell zu starten.

Prüfen Sie immer die konkrete Modell-ID, bevor Sie strict: true in Produktion einsetzen.

Zusammenfassung

Der Implementierungsablauf ist:

  1. Modell wählen, das strukturierte Ausgaben unterstützt
  2. JSON-Schema definieren
  3. response_format mit type: "json_schema" setzen
  4. strict: true aktivieren
  5. Antwort parsen
  6. refusal, abgeschnittene Antworten und Tool-Call-Grenzen behandeln
  7. Geschäftsregeln nachgelagert validieren
  8. Antwort in Apidog gegen das Schema testen
  9. Collection in CI ausführen
  10. Bei Bedarf eine Mock-API für Konsumenten bereitstellen

Das Modell verspricht die Form. Ihre Tests beweisen, dass sie stabil bleibt.

Top comments (0)