Strukturierter Output-Vergleich bei beliebten LLM-Anbietern - OpenAI, Gemini, Anthropic, Mistral und AWS Bedrock
Leicht unterschiedliche APIs erfordern einen speziellen Ansatz.
Hier ist ein Seitenvergleich der Unterstützung für strukturierte Ausgaben (zuverlässige JSON-Rückgabe) bei beliebten LLM-Anbietern, plus minimale Python-Beispiele
Wir haben bereits untersucht, wie man strukturierte Ausgaben vom auf Ollama gehosteten LLM anfordert. Hier überprüfen wir, wie man dasselbe von anderen Anbietern anfordert.
TL;DR-Matrix
Anbieter | Nativer „JSON-Modus“ | JSON Schema-Erzwingung | Typischer Regler | Hinweise |
---|---|---|---|---|
OpenAI | Ja | Ja (erster Klasse) | response_format={"type":"json_schema", ...} |
Funktioniert über die Responses API oder Chat Completions; kann auch Funktionaufrufe durchführen. |
Google Gemini | Ja | Ja (erster Klasse) | 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, dass das Modell Ihr schema-definiertes Tool „aufruft“; ergibt schemaförmige Argumente. |
Mistral | Ja | Teilweise (JSON-only; kein serverseitiges Schema) | response_format={"type":"json_object"} |
Gewährleistet JSON, aber Sie validieren gegen Ihr Schema clientseitig. |
AWS Bedrock (Plattform) | Variiert je nach Modell | Ja (über Tool/Converse-Schema) | toolConfig.tools[].toolSpec.inputSchema |
Bedrocks Converse-API validiert Tool-Eingaben gegen ein JSON-Schema. |
LLM-Strukturierte Ausgaben - Allgemeine Informationen
LLM-Strukturierte Ausgaben beziehen sich auf die Fähigkeit großer Sprachmodelle (LLMs), Antworten zu generieren, die streng einem vordefinierten, spezifischen Format oder einer Struktur folgen, anstatt frei formulierten Text zu produzieren. Diese strukturierten Ausgaben können in Formaten wie JSON, XML, Tabellen oder Vorlagen vorliegen und machen die Daten maschinenlesbar, konsistent und einfach für Software parsbar, um sie in verschiedenen Anwendungen zu nutzen.
Strukturierte Ausgaben unterscheiden sich von traditionellen LLM-Ausgaben, die typischerweise offenen, natürlichen Sprachtext generieren. Stattdessen erzwingen strukturierte Ausgaben ein Schema oder Format, wie z. B. JSON-Objekte mit definierten Schlüsseln und Werttypen oder spezifische 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 Erzeugung strukturierter Ausgaben in LLMs umfasst oft Techniken wie:
- Spezifizierung detaillierter Prompt-Anweisungen, um das Modell anzuleiten, 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.
- Manchmal Erzwingung von Decodierungsbeschränkungen basierend auf Grammatik oder endlichen Automaten, um die Token-Ebene-Konformität mit dem Format sicherzustellen.
Vorteile strukturierter LLM-Ausgaben sind:
- 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, das Handling komplexer verschachtelter Daten und potenzielle Einschränkungen in den Denkfähigkeiten im Vergleich zur Erzeugung von frei formuliertem Text.
Insgesamt ermöglichen strukturierte Ausgaben LLMs, in Anwendungen nützlicher zu sein, die präzise, formatierte Daten erfordern, anstatt nur menschenlesbaren Text.
Python-Beispiele für strukturierte Ausgaben
Alle Code-Snippets extrahieren Event-Informationen als JSON: {title, date, location}
. Ersetzen Sie die Schlüssel/Modelle nach Belieben.
1) OpenAI — JSON-Schema (streng)
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": "Extrahieren Sie das Event aus: 'PyData Sydney findet am 2025-11-03 im Darling Harbour statt.'"}
],
response_format={"type": "json_schema", "json_schema": schema},
)
data = json.loads(resp.choices[0].message.content)
print(data)
OpenAIs Strukturierte Ausgaben-Funktion erzwingt dieses Schema auf Serverseite.
2) Google Gemini — response schema + JSON MIME
import google.generativeai as genai
from google.genai import types
# Konfigurieren Sie 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="Extrahieren Sie das Event aus: 'PyData Sydney findet am 2025-11-03 im Darling Harbour statt.'",
generation_config=genai.GenerationConfig(
response_mime_type="application/json",
response_schema=schema,
),
)
print(resp.text) # bereits gültiges JSON gemäß Schema
Gemini gibt strenges JSON zurück, das dem response_schema
entspricht.
3) Anthropic (Claude) — Tool Use mit JSON-Schema
from anthropic import Anthropic
import json
client = Anthropic()
tool = {
"name": "extract_event",
"description": "Gibt Event-Details zurück.",
"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":
"Extrahieren Sie das Event aus: 'PyData Sydney findet am 2025-11-03 im Darling Harbour statt.'"}],
)
# 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 generischen „JSON-Modus“-Schalter; stattdessen gibt Tool Use mit einem input_schema
Ihnen validierte, schemaförmige Argumente (und Sie können dessen Verwendung 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":
"Geben Sie JSON mit den Schlüsseln title, date (YYYY-MM-DD), location für: "
"'PyData Sydney findet am 2025-11-03 im Darling Harbour statt.'"}],
response_format={"type": "json_object"} # garantiert gültiges JSON
)
data = json.loads(resp.choices[0].message.content)
print(data)
# Tipp: Validieren Sie `data` gegen Ihr Pydantic/JSON-Schema lokal.
Mistrals json_object
erzwingt JSON-Form (nicht Ihr genaues 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":
"Extrahieren Sie das Event aus: 'PyData Sydney findet am 2025-11-03 im Darling Harbour statt.'"}]}],
)
# 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 Tool-Eingaben gegen Ihr JSON-Schema und viele gehostete Modelle (z. B. Claude) unterstützen dies über Converse.
Praktische Anleitung und Validierung
- Wenn Sie die stärksten serverseitigen Garantien wünschen: OpenAI-Strukturierte Ausgaben oder Gemini-Response-Schema.
- Wenn Sie bereits Claude/Bedrock verwenden: Definieren Sie ein Tool mit einem JSON-Schema und erzwingen Sie dessen Verwendung; 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 / bitten Sie das Modell, mit e.errors() zu reparieren
print(e)
Nützliche Links
- https://platform.openai.com/docs/guides/structured-outputs
- https://ai.google.dev/gemini-api/docs/structured-output
- https://docs.mistral.ai/capabilities/structured-output/json_mode/
- https://aws.amazon.com/blogs/machine-learning/structured-data-response-with-amazon-bedrock-prompt-engineering-and-tool-use
- https://github.com/aws-samples/anthropic-on-aws/blob/main/complex-schema-tool-use/README.md
- https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages.html
- Anforderung von strukturierten Ausgaben vom LLM, das auf Ollama gehostet wird
- Python Cheatsheet
- AWS SAM + AWS SQS + Python PowerTools
- AWS Lambda Performancevergleich: JavaScript vs Python vs Golang