Comparaison des sorties structurées chez les principaux fournisseurs de LLM : OpenAI, Gemini, Anthropic, Mistral et AWS Bedrock

Des API légèrement différentes nécessitent une approche particulière.

Sommaire

Voici une comparaison détaillée côte à côte du support de la sortie structurée (obtention de JSON fiable) chez les principaux fournisseurs de LLM, ainsi que des exemples Python minimaux.

barres colorées debout

Nous avons déjà examiné comment demander une sortie structurée au LLM hébergé sur Ollama. Une fois le JSON reçu, la validation de la sortie structurée des LLM en Python qui tient la route passe en revue l’analyse, les vérifications Pydantic, les nouvelles tentatives et les tests dans votre service. Ici, nous examinons comment demander la même chose aux autres fournisseurs.

Matrice TL;DR

Fournisseur Mode « JSON » natif Application du Schema JSON Réglage typique Notes
OpenAI Oui Oui (de premier ordre) response_format={"type":"json_schema", ...} Fonctionne via l’API Responses ou les Chat Completions ; peut également faire de l’appel de fonctions.
Google Gemini Oui Oui (de premier ordre) response_schema= + response_mime_type="application/json" Renvoie un JSON strictement validé lorsqu’un schéma est défini.
Anthropic (Claude) Indirect Oui (via l’Utilisation d’Outils avec schéma JSON) tools=[{input_schema=...}] + tool_choice Force le modèle à « appeler » votre outil défini par schéma ; produit des arguments conformes au schéma.
Mistral Oui Partiel (JSON uniquement ; pas de schéma côté serveur) response_format={"type":"json_object"} Garantit le format JSON, mais vous validez par rapport à votre schéma côté client.
AWS Bedrock (plateforme) Varie selon le modèle Oui (via schéma Outil/Converse) toolConfig.tools[].toolSpec.inputSchema L’API Converse de Bedrock valide l’entrée de l’outil par rapport à un schéma JSON.

Sortie structurée des LLM - Informations générales

La sortie structurée des LLM fait référence à la capacité des grands modèles de langage (LLM) (LLMs) à générer des réponses qui se conforment strictement à un format ou une structure prédéfinis et spécifiques, plutôt que de produire du texte libre. Cette sortie structurée peut être au format JSON, XML, tableaux ou modèles, ce qui rend les données lisibles par machine, cohérentes et facilement analysables par des logiciels pour une utilisation dans diverses applications.

Les sorties structurées diffèrent des sorties traditionnelles des LLM, qui génèrent généralement du texte en langage naturel ouvert. Au lieu de cela, les sorties structurées imposent un schéma ou un format, tel que des objets JSON avec des clés et des types de valeurs définis, ou des classes spécifiques dans la sortie (par exemple, des réponses à choix multiples, des classes de sentiment ou des formats de lignes de base de données). Cette approche améliore la fiabilité, réduit les erreurs et les hallucinations, et simplifie l’intégration dans des systèmes tels que les bases de données, les API ou les flux de travail.

La génération de sorties structurées dans les LLM implique souvent des techniques telles que :

  • La spécification d’instructions de prompt détaillées pour guider le modèle à produire une sortie dans le format souhaité.
  • L’utilisation d’outils de validation et d’analyse comme Pydantic en Python pour garantir que la sortie correspond au schéma.
  • Parfois, l’application de contraintes de décodage basées sur la grammaire ou les automates finis pour garantir la conformité au niveau des jetons avec le format.

Les avantages des sorties structurées des LLM incluent :

  • La lisibilité par machine et la facilité d’intégration.
  • La réduction de la variabilité et des erreurs.
  • L’amélioration de la prévisibilité et de la vérifiabilité pour les tâches qui nécessitent des formats de données cohérents.

Les défis incluent la conception de schémas efficaces, la gestion de données complexes imbriquées et les limitations potentielles en capacités de raisonnement par rapport à la génération de texte libre.

Dans l’ensemble, la sortie structurée permet aux LLM d’être plus utiles dans les applications nécessitant des données précises et formatées, plutôt que du texte uniquement lisible par l’humain.

Exemples Python de sortie structurée

Tous les extraits extraient les informations d’événement en JSON : {title, date, location}. Remplacez les clés/modèles selon vos besoins.

1) OpenAI — Schéma JSON (strict)

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)

La fonctionnalité Structured Outputs d’OpenAI applique ce schéma côté serveur.


2) Google Gemini — schéma de réponse + MIME JSON

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

# Configure with your API key
# 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)  # already valid JSON per schema

Gemini renverra un JSON strict conforme à response_schema.


3) Anthropic (Claude) — Utilisation d’Outils avec schéma JSON

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"},  # force schema
    messages=[{"role": "user", "content":
        "Extract the event from: 'PyData Sydney is on 2025-11-03 at Darling Harbour.'"}],
)

# Claude will "call" the tool; grab the args (which match your schema)
tool_use = next(b for b in msg.content if b.type == "tool_use")
print(json.dumps(tool_use.input, indent=2))

Claude n’a pas d’interrupteur générique « JSON mode » ; au lieu de cela, l’Utilisation d’Outils avec un input_schema vous donne des arguments validés et conformes au schéma (et vous pouvez forcer son utilisation).


4) Mistral — Mode JSON (validation côté client)

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"}  # guarantees valid JSON
)

data = json.loads(resp.choices[0].message.content)
print(data)
# Tip: validate `data` against your Pydantic/JSON Schema locally.

Le json_object de Mistral applique la forme JSON (pas votre schéma exact) — validez côté client.


5) AWS Bedrock — Schéma d’outil de l’API Converse (indépendant du modèle)

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"}},  # force schema
    messages=[{"role":"user","content":[{"text":
        "Extract the event from: 'PyData Sydney is on 2025-11-03 at Darling Harbour.'"}]}],
)

# Pull toolUse content
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 valide l’entrée de l’outil par rapport à votre schéma JSON et de nombreux modèles hébergés (par exemple, Claude) le supportent via Converse.


Conseils pratiques et Validation

  • Si vous souhaitez les garanties les plus fortes côté serveur : sorties structurées OpenAI ou schéma de réponse Gemini.
  • Si vous êtes déjà sur Claude/Bedrock : définissez un Outil avec un schéma JSON et forcez son utilisation ; lisez les arguments de l’outil comme votre objet typé.
  • Si vous utilisez Mistral : activez json_object et validez localement (par exemple, avec Pydantic).

Motif de validation (fonctionne pour tous)

from pydantic import BaseModel, ValidationError

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

try:
    event = Event.model_validate(data)  # `data` from any provider
except ValidationError as e:
    # handle / retry / ask model to fix with e.errors()
    print(e)

Liens utiles

S'abonner

Recevez de nouveaux articles sur les systèmes, l'infrastructure et l'ingénierie IA.