Gestructureerde vergelijking van uitvoer over populaire LLM-aanbieders - OpenAI, Gemini, Anthropic, Mistral en AWS Bedrock

Zichtbaar verschillende APIs vereisen een speciale aanpak.

Inhoud

Hier is een zij-aan-zij vergelijking van de ondersteuning voor gestructureerde uitvoer (het verkrijgen van betrouwbare JSON) bij populaire LLM-aanbieders, plus minimale Python-voorbeelden

kleurrijke balken die staan

We hebben al gekeken hoe je gestructureerde uitvoer kan aanvragen van de LLM die is gehost op Ollama. Hieronder bekijken we hoe je dezelfde uitvoer kan aanvragen van andere aanbieders.

TL;DR matrix

Aanbieder Native “JSON mode” JSON Schema-toepassing Typische knop Opmerkingen
OpenAI Ja Ja (eersteklas) response_format={"type":"json_schema", ...} Werkt via de Responses API of Chat Completions; kan ook functie-aanroepen.
Google Gemini Ja Ja (eersteklas) response_schema= + response_mime_type="application/json" Geeft strikt gevalideerde JSON terug wanneer schema is ingesteld.
Anthropic (Claude) Indirect Ja (via Tool Use met JSON schema) tools=[{input_schema=...}] + tool_choice Zet het model aan om je schema-gedefinieerde tool aan te roepen; levert schema-gestuurde argumenten op.
Mistral Ja Gedeeltelijk (alleen JSON; geen serverside schema) response_format={"type":"json_object"} Zorgt voor JSON, maar je valideert tegen je schema client-side.
AWS Bedrock (platform) Varieert per model Ja (via Tool/Converse schema) toolConfig.tools[].toolSpec.inputSchema Bedrock’s Converse API valideert tool input tegen een JSON schema.

Gestructureerde uitvoer bij LLMs - Algemene informatie

Gestructureerde uitvoer bij LLMs verwijst naar de mogelijkheid van grote taalmodellen (LLMs) om reacties te genereren die strikt voldoen aan een vooraf gedefinieerde, specifieke indeling of structuur, in plaats van vrije tekst te produceren. Deze gestructureerde uitvoer kan in formaten zoals JSON, XML, tabellen of sjablonen, waardoor de data machine-leesbaar, consistent en gemakkelijk te verwerken is voor software in verschillende toepassingen.

Gestructureerde uitvoer verschilt van traditionele LLM-uitvoer, die meestal open-gevormde, natuurlijke taaltekst genereert. In plaats daarvan dwingt gestructureerde uitvoer een schema of indeling op, zoals JSON-objecten met gedefinieerde sleutels en waarde-typen, of specifieke klassen in de uitvoer (bijvoorbeeld meervoudige keuze-antwoorden, sentimentklassen of database-rijindelingen). Dit verbetert betrouwbaarheid, verminderd fouten en hallucinaties, en vereenvoudigt integratie in systemen zoals databases, APIs of workflows.

De generatie van gestructureerde uitvoer bij LLMs vereist vaak technieken zoals:

  • Het opstellen van gedetailleerde instructies in de prompt om het model te beïnvloeden om uitvoer in de gewenste indeling te genereren.
  • Het gebruik van validatie- en parseringsgereedschappen zoals Pydantic in Python om ervoor te zorgen dat de uitvoer overeenkomt met het schema.
  • Soms het dwingen van decoderingsbeperkingen op basis van grammatica of eindige toestandsmachines om tokenniveau-compliance met het formaat te waarborgen.

Voordelen van gestructureerde LLM-uitvoer zijn:

  • Machine-leesbaarheid en eenvoudige integratie.
  • Verminderde variabiliteit en fouten.
  • Verbeterde voorspelbaarheid en verifieerbaarheid voor taken die consistente data-indelingen vereisen.

Uitdagingen omvatten het ontwerpen van effectieve schema’s, het afhandelen van complexe geneste data en potentieel beperkte redeneervaardigheden in vergelijking met vrije tekstgeneratie.

Over het algemeen maakt gestructureerde uitvoer LLMs nuttiger in toepassingen die nauwkeurige, gestructureerde data vereisen in plaats van alleen mensleesbare tekst.

Gestructureerde uitvoer Python-voorbeelden

Alle codefragmenten extraheren gebeurtenis-informatie als JSON: {titel, datum, locatie}. Vervang sleutels/modellen naar wens.

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": "Extraheer de gebeurtenis uit: 'PyData Sydney is op 2025-11-03 in Darling Harbour.'"}
    ],
    response_format={"type": "json_schema", "json_schema": schema},
)

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

OpenAI’s Gestructureerde uitvoer-functie dwingt dit schema aan 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="Extraheer de gebeurtenis uit: 'PyData Sydney is op 2025-11-03 in Darling Harbour.'",
    generation_config=genai.GenerationConfig(
        response_mime_type="application/json",
        response_schema=schema,
    ),
)

print(resp.text)  # al geldig JSON per schema

Gemini zal streng JSON retourneren die overeenkomt met response_schema.


3) Anthropic (Claude) — Tool Use met JSON schema

from anthropic import Anthropic
import json

client = Anthropic()

tool = {
    "name": "extract_event",
    "description": "Geef gebeurtenisdetails terug.",
    "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"},  # dwing schema
    messages=[{"role": "user", "content":
        "Extraheer de gebeurtenis uit: 'PyData Sydney is op 2025-11-03 in Darling Harbour.'"}],
)

# Claude zal de tool aanroepen; haal de argumenten op (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 mode”-schakelaar; in plaats daarvan geeft Tool Use met een input_schema je geverifieerde, schema-gestuurde argumenten (en je kunt het gebruik ervan dwingen).


4) Mistral — JSON mode (client-side validatie)

from mistralai import Mistral
import json

client = Mistral()

resp = client.chat.complete(
    model="mistral-large-latest",
    messages=[{"role":"user","content":
        "Geef JSON met sleutels titel, datum (YYYY-MM-DD), locatie voor: "
        "'PyData Sydney is op 2025-11-03 in Darling Harbour.'"}],
    response_format={"type": "json_object"}  # garandeert geldige JSON
)

data = json.loads(resp.choices[0].message.content)
print(data)
# Tip: valideer `data` tegen je Pydantic/JSON Schema lokaal.

Mistral’s json_object dwingt JSON-indeling aan (niet je exacte schema) — valideer client-side.


5) AWS Bedrock — Converse API Tool schema (model-agnostisch)

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"}},  # dwing schema
    messages=[{"role":"user","content":[{"text":
        "Extraheer de gebeurtenis uit: 'PyData Sydney is op 2025-11-03 in Darling Harbour.'"}]}],
)

# Haal toolUse-inhoud 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-invoer tegen je JSON-schema en veel gehechte modellen (bijvoorbeeld Claude) ondersteunen het via Converse.


Praktische richtlijnen en validatie

  • Als je de sterkste serverside garanties wilt: Gestructureerde uitvoer bij OpenAI of Gemini response schema.
  • Als je al op Claude/Bedrock zit: definieer een Tool met een JSON-schema en dwing het gebruik ervan; lees de tool’s argumenten als je getypeerde object.
  • Als je Mistral gebruikt: schakel json_object in en valideer lokaal (bijvoorbeeld met Pydantic).

Validatiepatroon (werkt voor 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:
    # verwerk / herprobeer / vraag model om te corrigeren met e.errors()
    print(e)