Aller au contenu principal

Structured Output : JSON garanti

Structured Output : JSON garanti

Le Structured Output est l’une des fonctionnalités les plus puissantes de la Responses API. Au lieu d’espérer que le modèle retourne du JSON valide, vous le garantissez en fournissant un schéma. Le modèle est contraint structurellement de respecter ce schéma.

Le problème sans Structured Output

from openai import OpenAI
client = OpenAI()

# Sans structure — le modèle peut retourner n'importe quel format
response = client.responses.create(
    model="gpt-5.3",
    input="Donnez-moi les infos sur Paris en JSON."
)
print(response.output_text)
# Résultat imprévisible :
# Parfois du JSON valide, parfois du texte avec du JSON,
# parfois un format inattendu...

Structured Output avec un schéma JSON

response = client.responses.create(
    model="gpt-5.3",
    input="Donnez-moi les informations sur Paris.",
    text={
        "format": {
            "type": "json_schema",
            "name": "ville_info",
            "strict": True,
            "schema": {
                "type": "object",
                "properties": {
                    "nom": {"type": "string"},
                    "pays": {"type": "string"},
                    "population": {"type": "integer"},
                    "langue_officielle": {"type": "string"},
                    "monuments": {
                        "type": "array",
                        "items": {"type": "string"}
                    }
                },
                "required": ["nom", "pays", "population", "langue_officielle", "monuments"],
                "additionalProperties": False
            }
        }
    }
)

import json
data = json.loads(response.output_text)
print(f"Ville : {data['nom']}")
print(f"Population : {data['population']:,}")
print(f"Monuments : {', '.join(data['monuments'])}")

# Résultat GARANTI en JSON valide :
# Ville : Paris
# Population : 2,161,000
# Monuments : Tour Eiffel, Louvre, Notre-Dame, Arc de Triomphe, Sacre-Coeur

Utiliser Pydantic pour les schémas

Pydantic simplifie la définition des schémas et la validation :

from pydantic import BaseModel
from typing import Optional
import json

class Produit(BaseModel):
    nom: str
    prix: float
    categorie: str
    en_stock: bool
    description: Optional[str] = None

response = client.responses.create(
    model="gpt-5.3",
    input="Décrivez un ordinateur portable gaming haut de gamme.",
    text={
        "format": {
            "type": "json_schema",
            "name": "produit",
            "strict": True,
            "schema": Produit.model_json_schema()
        }
    }
)

# Parser et valider avec Pydantic
produit = Produit.model_validate_json(response.output_text)
print(f"Produit : {produit.nom}")
print(f"Prix : {produit.prix} EUR")
print(f"En stock : {'Oui' if produit.en_stock else 'Non'}")

# Résultat :
# Produit : ASUS ROG Strix G18
# Prix : 2499.99 EUR
# En stock : Oui

Schémas imbriqués

Vous pouvez créer des structures complexes :

from pydantic import BaseModel

class Adresse(BaseModel):
    rue: str
    ville: str
    code_postal: str
    pays: str

class Contact(BaseModel):
    nom: str
    prenom: str
    email: str
    telephone: str
    adresse: Adresse

class Entreprise(BaseModel):
    nom: str
    secteur: str
    employes: int
    contacts: list[Contact]

response = client.responses.create(
    model="gpt-5.3",
    input="Générez une fiche entreprise fictive dans le secteur tech "
          "avec 2 contacts.",
    text={
        "format": {
            "type": "json_schema",
            "name": "entreprise",
            "strict": True,
            "schema": Entreprise.model_json_schema()
        }
    }
)

entreprise = Entreprise.model_validate_json(response.output_text)
print(f"Entreprise : {entreprise.nom} ({entreprise.secteur})")
for c in entreprise.contacts:
    print(f"  - {c.prenom} {c.nom} : {c.email}")

Cas d’usage courants

Extraction de données depuis du texte

class Evenement(BaseModel):
    titre: str
    date: str
    lieu: str
    participants: int

texte = """
La conférence PyCon France 2026 se tiendra les 15 et 16 novembre
au Palais des Congrès de Lyon. Plus de 800 développeurs Python
sont attendus pour cette édition.
"""

response = client.responses.create(
    model="gpt-5.3",
    input=f"Extrayez les informations de cet événement :\n{texte}",
    text={
        "format": {
            "type": "json_schema",
            "name": "evenement",
            "strict": True,
            "schema": Evenement.model_json_schema()
        }
    }
)

evt = Evenement.model_validate_json(response.output_text)
print(f"{evt.titre} - {evt.date} a {evt.lieu} ({evt.participants} participants)")
# Résultat : PyCon France 2026 - 15-16 novembre 2026 a Lyon (800 participants)

Classification avec enum

from enum import Enum

class Sentiment(str, Enum):
    positif = "positif"
    negatif = "negatif"
    neutre = "neutre"

class Analyse(BaseModel):
    sentiment: Sentiment
    confiance: float
    mots_cles: list[str]

response = client.responses.create(
    model="gpt-5.3",
    input="Analysez ce commentaire : 'Super service, livraison rapide !'",
    text={
        "format": {
            "type": "json_schema",
            "name": "analyse_sentiment",
            "strict": True,
            "schema": Analyse.model_json_schema()
        }
    }
)

analyse = Analyse.model_validate_json(response.output_text)
print(f"Sentiment : {analyse.sentiment.value} ({analyse.confiance:.0%})")
# Résultat : Sentiment : positif (95%)

Règles importantes pour les schémas strict

Quand strict: True, certaines contraintes s’appliquent :

  • Toutes les propriétés doivent être dans required
  • additionalProperties doit être False
  • Les types supportés : string, number, integer, boolean, array, object, null
  • Pas de oneOf, anyOf avec des types mixtes
  • Utilisez Optional[str] qui se traduit par {"anyOf": [{"type": "string"}, {"type": "null"}]}

Points clés à retenir

  • Le Structured Output garantit que la réponse respecte votre schéma JSON
  • Utilisez text={"format": {"type": "json_schema", ...}} dans la Responses API
  • Pydantic est l’outil idéal pour définir et valider les schémas
  • Activez strict: True pour la conformité garantie du schéma
  • Idéal pour l’extraction de données, la classification et la génération structurée