Vergelijking van gestructureerde output bij populaire LLM-leveranciers: OpenAI, Gemini, Anthropic, Mistral en AWS Bedrock
Ietwat afwijkende API's vereisen een speciale aanpak.
Hieronder volgt een vergelijking van de ondersteuning voor gestructureerde output (betrouwbaar JSON terugkrijgen) bij populaire LLM-aanbieders, plus minimale Python-voorbeelden

We hebben eerder gekeken hoe je gestructureerde output kunt aanvragen bij de LLM die op Ollama is gehost. Zodra JSON weer via de verbinding loopt, behandelt validatie van gestructureerde LLM-output in Python die standhoudt het parseren, Pydantic-controles, herpogingen en tests in je service. Hier bekijken we hoe je hetzelfde kunt aanvragen bij andere aanbieders.
TL;DR-matrix
| Aanbieder | Native “JSON-modus” | JSON-Schema-afdwinging | Typische instelling | Opmerkingen |
|---|---|---|---|---|
| OpenAI | Ja | Ja (eersteklas) | response_format={"type":"json_schema", ...} |
Werkt via de Responses API of Chat Completions; kan ook function calling gebruiken. |
| Google Gemini | Ja | Ja (eersteklas) | response_schema= + response_mime_type="application/json" |
Retourneert strikt gevalideerd JSON als schema is ingesteld. |
| Anthropic (Claude) | Indirect | Ja (via Tool Use met JSON-schema) | tools=[{input_schema=...}] + tool_choice |
Forceer het model om je gedefinieerde tool te “aanroepen”; levert schema-gestalte argumenten op. |
| Mistral | Ja | Gedeeltelijk (alleen JSON; geen server-side schema) | response_format={"type":"json_object"} |
Zorgt voor JSON, maar je valideert client-side tegen je schema. |
| AWS Bedrock (platform) | Verschilt per model | Ja (via Tool/Converse-schema) | toolConfig.tools[].toolSpec.inputSchema |
Bedrock’s Converse API valideert tool-input tegen een JSON-schema. |
Gestructureerde LLM-output — Algemene informatie
Gestructureerde LLM-output verwijst naar het vermogen van grote taalmodellen (LLM’s) om reacties te genereren die strikt voldoen aan een vooraf gedefinieerd, specifiek formaat of structuur, in plaats van vrij tekst te produceren. Deze gestructureerde output kan in formaten zoals JSON, XML, tabellen of sjablonen, waardoor de data machine-leesbaar, consistent en makkelijk parsebaar is door software voor gebruik in verschillende toepassingen.
Gestructureerde outputs verschillen van traditionele LLM-outputs, die doorgaans open-eind, natuurlijke taaltekst genereren. In plaats daarvan dwingen gestructureerde outputs een schema of formaat af, zoals JSON-objecten met gedefinieerde sleutels en waardetypes, of specifieke klassen in de output (bijv. meerkeuze-antwoorden, sentimentklassen of database-regelformaten). Deze aanpak verbetert betrouwbaarheid, vermindert fouten en hallucinaties, en vereenvoudigt integratie in systemen zoals databases, API’s of workflows.
De generatie van gestructureerde outputs in LLM’s omvat vaak technieken zoals:
- Het specificeren van gedetailleerde prompt-instructies om het model te begeleiden bij het produceren van output in het gewenste formaat.
- Het gebruik van validatie- en parsehulpmiddelen zoals Pydantic in Python om te waarborgen dat de output overeenkomt met het schema.
- Soms het afdwingen van decoderingsbeperkingen op basis van grammatica of eindige statemachine om token-niveau-naleving van het formaat te garanderen.
Voordelen van gestructureerde LLM-outputs omvatten:
- Machine-leesbaarheid en gemakkelijke integratie.
- Verminderde variabiliteit en fouten.
- Verbeterde voorspelbaarheid en verificerbaarheid voor taken die consistente dataformaten vereisen.
Uitdagingen omvatten het ontwerpen van effectieve schemas, het afhandelen van complexe genestelde data, en potentiële beperkingen in redeneervermogen in vergelijking met vrij tekstgeneratie.
Over het algemeen maakt gestructureerde output LLM’s nuttiger in toepassingen die precieze, geformatteerde data vereisen in plaats van uitsluitend mens-leesbare tekst.
Python-voorbeelden voor gestructureerde output
Alle fragmenten extraheren evenement-info als JSON: {title, date, location}. Vervang keys/modellen zoals je wilt.
1) OpenAI — JSON Schema (strikt)
from openai import OpenAI
import json
client = OpenAI()
schema = {
"name": "Evenement",
"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)
OpenAI’s Structured Outputs-functie dwingt dit schema af op de serverside.
2) Google Gemini — response schema + JSON MIME
import google.generativeai as genai
from google.genai import types
# Configureer met je API-sleutel
# 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) # al geldige JSON volgens schema
Gemini zal strikt JSON retourneren dat voldoet aan response_schema.
3) Anthropic (Claude) — Tool Use met 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"}, # forceer schema
messages=[{"role": "user", "content":
"Extract the event from: 'PyData Sydney is on 2025-11-03 at Darling Harbour.'"}],
)
# Claude zal de tool "aanroepen"; pak de args (die overeenkomen met je schema)
tool_use = next(b for b in msg.content if b.type == "tool_use")
print(json.dumps(tool_use.input, indent=2))
Claude heeft geen algemene “JSON-modus”-schakelaar; in plaats daarvan geeft Tool Use met een input_schema je gevalideerde, schema-gestalte argumenten (en je kunt het gebruik ervan forceren).
4) Mistral — JSON-modus (client-side validatie)
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"} # garandeert geldige JSON
)
data = json.loads(resp.choices[0].message.content)
print(data)
# Tip: valideer `data` lokaal tegen je Pydantic/JSON Schema.
Mistral’s json_object dwingt JSON-vorm af (niet je exacte schema) — valideer client-side.
5) AWS Bedrock — Converse API Tool-schema (model-onafhankelijk)
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"}}, # forceer schema
messages=[{"role":"user","content":[{"text":
"Extract the event from: 'PyData Sydney is on 2025-11-03 at Darling Harbour.'"}]}],
)
# Haal toolUse-content op
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 valideert tool-input tegen je JSON-schema en veel gehoste modellen (bijv. Claude) ondersteunen dit via Converse.
Praktische richtlijnen en validatie
- Als je de sterkste serverside garanties wilt: OpenAI gestructureerde outputs of Gemini response schema.
- Als je al op Claude/Bedrock zit: definieer een Tool met een JSON-schema en forceer het gebruik; lees de argumenten van de tool als je getypeerde object.
- Als je Mistral gebruikt: schakel
json_objectin en valideer lokaal (bijv. met Pydantic).
Validatiepatroon (werkt voor ze allemaal)
from pydantic import BaseModel, ValidationError
class Event(BaseModel):
title: str
date: str
location: str
try:
event = Event.model_validate(data) # `data` van elke aanbieder
except ValidationError as e:
# afhandelen / opnieuw proberen / vraag model om te fixen met e.errors()
print(e)
Nuttige 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
- Hoe gestructureerde output aan te vragen bij de LLM gehost op Ollama
- Python Cheatsheet
- AWS SAM + AWS SQS + Python PowerTools
- AWS Lambda prestatievergelijking: JavaScript vs Python vs Golang