Strukturierter Vergleich der Ausgaben führender LLM-Anbieter: OpenAI, Gemini, Anthropic, Mistral und AWS Bedrock

Slight unterschiedliche APIs erfordern einen speziellen Ansatz.

Inhaltsverzeichnis

Hier ist ein detaillierter Vergleich der Unterstützung für strukturierte Ausgabe (das Zurückgeben zuverlässiger JSON-Daten) bei populären LLM-Anbietern.

farbige stehende Balken

Wir haben bereits einen Blick darauf geworfen, wie man strukturierte Ausgabe von dem auf Ollama gehosteten LLM anfordert. Sobald JSON auf dem Draht zurückkommt, führt Validierung strukturierter LLM-Ausgaben in Python, die standhält durch den Prozess des Parsens, Pydantic-Checks, Wiederholungen und Tests in Ihrem Dienst. Hier prüfen wir, wie man dasselbe von anderen Anbietern anfordern kann.

TL;DR-Matrix

Anbieter Native „JSON-Modus“ Durchsetzung des JSON-Schemas Typischer Schalter Anmerkungen
OpenAI Ja Ja (erstklassig) response_format={"type":"json_schema", ...} Funktioniert über die Responses API oder Chat Completions; kann auch Funktionsaufrufe durchführen.
Google Gemini Ja Ja (erstklassig) response_schema= + response_mime_type="application/json" Gibt streng validiertes JSON zurück, wenn ein Schema festgelegt ist.
Anthropic (Claude) Indirekt Ja (über Tool Use mit JSON-Schema) tools=[{input_schema=...}] + tool_choice Erzwingt dem Modell den „Aufruf“ Ihres schemabasierten Tools; liefert Argumente in Schemagestalt.
Mistral Ja Teilweise (nur JSON; kein serverseitiges Schema) response_format={"type":"json_object"} Stellt JSON sicher, aber Sie validieren clientseitig gegen Ihr Schema.
AWS Bedrock (Plattform) Je nach Modell Ja (über Tool/Converse-Schema) toolConfig.tools[].toolSpec.inputSchema Die Converse API von Bedrock validiert Tool-Eingaben gegen ein JSON-Schema.

Strukturierte LLM-Ausgabe – Allgemeine Informationen

Strukturierte LLM-Ausgabe bezieht sich auf die Fähigkeit großer Sprachmodelle (LLMs), Antworten zu generieren, die strikt einem vordefinierten, spezifischen Format oder einer Struktur folgen, anstatt freien Text zu produzieren. Diese strukturierte Ausgabe kann in Formaten wie JSON, XML, Tabellen oder Vorlagen vorliegen, wodurch die Daten maschinenlesbar, konsistent und leicht von Software für den Einsatz in verschiedenen Anwendungen parsbar werden.

Strukturierte Ausnahmen unterscheiden sich von traditionellen LLM-Ausgaben, die typischerweise offene, natürliche Sprachtexte generieren. Stattdessen erzwingen strukturierte Ausgaben ein Schema oder Format, wie beispielsweise JSON-Objekte mit definierten Schlüssel- und Werttypen oder bestimmte Klassen in der Ausgabe (z. B. Multiple-Choice-Antworten, Sentiment-Klassen oder Datenbankzeilenformate). Dieser Ansatz verbessert die Zuverlässigkeit, reduziert Fehler und Halluzinationen und vereinfacht die Integration in Systeme wie Datenbanken, APIs oder Workflows.

Die Generierung strukturierter Ausgaben in LLMs beinhaltet oft Techniken wie:

  • Spezifizieren detaillierter Prompt-Anweisungen, um das Modell zu führen, die Ausgabe im gewünschten Format zu produzieren.
  • Verwendung von Validierungs- und Parsing-Tools wie Pydantic in Python, um sicherzustellen, dass die Ausgabe dem Schema entspricht.
  • Gelegentliches Erzwingen von Decoding-Einschränkungen basierend auf Grammatik oder endlichen Zustandsautomaten, um eine token-pegte Konformität mit dem Format sicherzustellen.

Vorteile strukturierter LLM-Ausgaben umfassen:

  • Maschinenlesbarkeit und einfache Integration.
  • Reduzierte Variabilität und Fehler.
  • Verbesserte Vorhersehbarkeit und Überprüfbarkeit für Aufgaben, die konsistente Datenformate erfordern.

Herausforderungen umfassen das Design effektiver Schemata, die Behandlung komplexer, verschachtelter Daten und potenzielle Einschränkungen in der Schlussfolgerungsfähigkeit im Vergleich zur freien Textgenerierung.

Insgesamt ermöglicht die strukturierte Ausgabe LLMs, in Anwendungen nützlicher zu sein, die präzise, formattierte Daten erfordern, anstatt ausschließlich menschenlesbaren Text.

Beispiele für strukturierte Ausgabe in Python

Alle Snippets extrahieren Ereignis-Informationen als JSON: {title, date, location}. Ersetzen Sie Schlüssel/Modelle nach Belieben.

1) OpenAI — JSON-Schema (strikt)

from openai import OpenAI
import json

client = OpenAI()

schema = {
    "name": "Event",
    "schema": {
        "type": "object",
        "properties": {
            "title": {"type": "string"},
            "date":  {"type": "string", "description": "YYYY-MM-DD"},
            "location": {"type": "string"}
        },
        "required": ["title", "date", "location"],
        "additionalProperties": False
    },
    "strict": True
}

resp = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {"role": "user", "content": "Extract the event from: 'PyData Sydney is on 2025-11-03 at Darling Harbour.'"}
    ],
    response_format={"type": "json_schema", "json_schema": schema},
)

data = json.loads(resp.choices[0].message.content)
print(data)

Die Funktion Structured Outputs von OpenAI erzwingt dieses Schema serverseitig.


2) Google Gemini — response_schema + JSON-MIME

import google.generativeai as genai
from google.genai import types

# Konfigurieren mit Ihrem API-Schlüssel
# genai.configure(api_key="your-api-key")

schema = types.Schema(
    type=types.Type.OBJECT,
    properties={
        "title": types.Schema(type=types.Type.STRING),
        "date": types.Schema(type=types.Type.STRING),
        "location": types.Schema(type=types.Type.STRING),
    },
    required=["title", "date", "location"],
    additional_properties=False,
)

resp = genai.generate_content(
    model="gemini-2.0-flash",
    contents="Extract the event from: 'PyData Sydney is on 2025-11-03 at Darling Harbour.'",
    generation_config=genai.GenerationConfig(
        response_mime_type="application/json",
        response_schema=schema,
    ),
)

print(resp.text)  # bereits gültiges JSON gemäß Schema

Gemini gibt striktes JSON zurück, das response_schema konform ist.


3) Anthropic (Claude) — Tool Use mit JSON-Schema

from anthropic import Anthropic
import json

client = Anthropic()

tool = {
    "name": "extract_event",
    "description": "Return event details.",
    "input_schema": {
        "type": "object",
        "properties": {
            "title": {"type": "string"},
            "date": {"type": "string"},
            "location": {"type": "string"}
        },
        "required": ["title", "date", "location"],
        "additionalProperties": False
    }
}

msg = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=256,
    tools=[tool],
    tool_choice={"type": "tool", "name": "extract_event"},  # Schema erzwingen
    messages=[{"role": "user", "content":
        "Extract the event from: 'PyData Sydney is on 2025-11-03 at Darling Harbour.'"}],
)

# Claude wird das Tool „aufrufen“; holen Sie sich die Argumente (die Ihrem Schema entsprechen)
tool_use = next(b for b in msg.content if b.type == "tool_use")
print(json.dumps(tool_use.input, indent=2))

Claude hat keinen generellen „JSON-Modus“-Schalter; stattdessen liefert Tool Use mit einem input_schema validierte, schemabasierte Argumente (und Sie können dessen Nutzung erzwingen).


4) Mistral — JSON-Modus (clientseitige Validierung)

from mistralai import Mistral
import json

client = Mistral()

resp = client.chat.complete(
    model="mistral-large-latest",
    messages=[{"role":"user","content":
        "Return JSON with keys title, date (YYYY-MM-DD), location for: "
        "'PyData Sydney is on 2025-11-03 at Darling Harbour.'"}],
    response_format={"type": "json_object"}  # garantiert gültiges JSON
)

data = json.loads(resp.choices[0].message.content)
print(data)
# Tipp: Validieren Sie `data` lokal gegen Ihr Pydantic-/JSON-Schema.

Das json_object von Mistral erzwingt die JSON-Form (nicht Ihr exaktes Schema) — validieren Sie clientseitig.


5) AWS Bedrock — Converse API Tool-Schema (modellunabhängig)

import boto3, json

bedrock = boto3.client("bedrock-runtime", region_name="us-east-1")
model_id = "anthropic.claude-3-5-sonnet-20240620-v1:0"

tools = [{
    "toolSpec": {
        "name": "extract_event",
        "inputSchema": {
            "json": {
                "type": "object",
                "properties": {
                    "title": {"type": "string"},
                    "date": {"type": "string"},
                    "location": {"type": "string"}
                },
                "required": ["title","date","location"],
                "additionalProperties": False
            }
        }
    }
}]

resp = bedrock.converse(
    modelId=model_id,
    toolConfig={"tools": tools},
    toolChoice={"tool": {"name": "extract_event"}},  # Schema erzwingen
    messages=[{"role":"user","content":[{"text":
        "Extract the event from: 'PyData Sydney is on 2025-11-03 at Darling Harbour.'"}]}],
)

# ToolUse-Inhalt abrufen
tool_use = next(
    c["toolUse"] for c in resp["output"]["message"]["content"] if "toolUse" in c
)
print(json.dumps(tool_use["input"], indent=2))

Bedrock validiert die Tool-Eingabe gegen Ihr JSON-Schema und viele gehostete Modelle (z. B. Claude) unterstützen dies über Converse.


Praktische Hinweise und Validierung

  • Wenn Sie die stärksten serverseitigen Garantien wünschen: OpenAI Structured Outputs oder Gemini Response Schema.
  • Wenn Sie bereits bei Claude/Bedrock sind: Definieren Sie ein Tool mit einem JSON-Schema und erzwingen Sie dessen Nutzung; lesen Sie die Argumente des Tools als Ihr typisiertes Objekt.
  • Wenn Sie Mistral verwenden: Aktivieren Sie json_object und validieren Sie lokal (z. B. mit Pydantic).

Validierungsmuster (funktioniert für alle)

from pydantic import BaseModel, ValidationError

class Event(BaseModel):
    title: str
    date: str
    location: str

try:
    event = Event.model_validate(data)  # `data` von jedem Anbieter
except ValidationError as e:
    # behandeln / wiederholen / Modell bitten, mit e.errors() zu korrigieren
    print(e)

Abonnieren

Neue Beiträge zu Systemen, Infrastruktur und KI-Engineering.