0Pricing
AI Engineering Academy · Leçon

Mode JSON et response_format

Activez le mode JSON dans l’API OpenAI, rédigez des prompts qui produisent systématiquement un JSON valide et gérez les cas où le modèle parvient malgré tout à ne pas respecter le format.

Mode JSON et response_format est une leçon AI Engineering Academy gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage AI Engineering Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours AI Engineering Academy comprend 4 leçons au total.

Le problème des sorties LLM non structurées

Par défaut, les LLM renvoient du texte libre. Analyser ce texte pour en extraire des données structurées est fragile : une modification du comportement du modèle, une légère variation de l'invite ou un cas particulier dans l'entrée peut modifier le format de sortie de manière inattendue, ce qui casse votre analyseur et fait planter votre application.

Imaginez que vous demandiez à un LLM de « renvoyer le nom et l'âge de l'utilisateur au format JSON ». Parfois, il renvoie {"name":"Alice","age":30}, parfois il place le résultat dans un bloc de code markdown, et parfois il ajoute une explication en toutes lettres. Chacune de ces variations nécessite une logique d'analyse différente. Pour obtenir une sortie lisible de manière fiable par une machine, il faut contraindre le modèle à respecter une structure, plutôt que d'espérer qu'il le fasse.

Mode JSON d'OpenAI

OpenAI a introduit le mode JSON via le paramètre response_format. Lorsqu'il est défini sur {"type": "json_object"}, le modèle est contraint de toujours renvoyer un objet JSON valide. Le modèle ne produira jamais quoi que ce soit qui ne soit pas du JSON valide : pas d'encadrement Markdown, pas de texte explicatif ni de texte supplémentaire à la fin.

import openai
import json

client = openai.OpenAI()

response = client.chat.completions.create(
    model='gpt-4o-mini',
    messages=[
        {
            'role': 'system',
            'content': 'Extract information from the text and return valid JSON only.'
        },
        {
            'role': 'user',
            'content': 'John Smith, age 34, works as a software engineer in Austin.'
        }
    ],
    response_format={'type': 'json_object'}  # Guarantee valid JSON output
)

# Safe to parse - guaranteed valid JSON
data = json.loads(response.choices[0].message.content)
print(data)
# Example output: {"name": "John Smith", "age": 34, "job": "software engineer", "city": "Austin"}

Limites du mode JSON

Le mode JSON garantit une syntaxe JSON valide, mais ne garantit PAS que le JSON contienne les champs dont vous avez besoin. Le modèle décide toujours des clés à inclure, de leurs noms et des types de données utilisés. Vous pouvez demander un champ name et recevoir full_name à la place, ou demander un tableau et recevoir une chaîne de caractères.

Notez également que le mode JSON exige que vous mentionniez JSON dans votre invite. Si vous activez le mode JSON, mais que votre invite ne demande pas de sortie JSON, le modèle peut produire un objet JSON vide ou refuser de générer une réponse. Indiquez toujours explicitement au modèle de répondre au format JSON dans le message système ou utilisateur.

Sorties structurées avec Pydantic (aperçu)

La fonctionnalité plus récente de sorties structurées d'OpenAI va plus loin que le mode JSON : vous fournissez un schéma JSON et le modèle est contraint de renvoyer exactement ce schéma, avec des noms de champs, des types et une imbrication précis. Cela élimine le problème d'incohérence du schéma propre au mode JSON de base.

Le SDK Python accepte directement les modèles Pydantic, les convertit automatiquement en schéma JSON et désérialise la réponse en objet Python typé. C'est la méthode la plus propre pour obtenir des données structurées fiables à partir d'un LLM en Python.

import openai
from pydantic import BaseModel
from typing import Optional

client = openai.OpenAI()

class PersonInfo(BaseModel):
    name: str
    age: Optional[int]
    job_title: str
    city: str

completion = client.beta.chat.completions.parse(
    model='gpt-4o-mini',
    messages=[
        {'role': 'system', 'content': 'Extract person information from the text.'},
        {'role': 'user', 'content': 'Sarah Chen, 28 years old, is a data scientist based in Seattle.'}
    ],
    response_format=PersonInfo  # Pass Pydantic model directly
)

# Already deserialized into a PersonInfo instance
person = completion.choices[0].message.parsed
print(person.name)       # Sarah Chen
print(person.age)        # 28
print(person.job_title)  # data scientist
print(person.city)       # Seattle

Rédiger des invites pour obtenir un JSON cohérent

Même lorsque le mode JSON est activé, la conception de votre invite influe sur la qualité de la sortie. Bonnes pratiques pour les invites JSON :

  • Nommer explicitement les champs : indiquez au modèle les champs attendus avec précision, plutôt que de demander simplement de « renvoyer du JSON »
  • Spécifier les types : « Renvoyez le prix sous forme de nombre, et non de chaîne de caractères » évite les incompatibilités de types
  • Définir les énumérations : « La catégorie doit être l'une des suivantes : bug, fonctionnalité, question » évite les valeurs inattendues
  • Gérer les données manquantes : « Si un champ n'est pas présent dans le texte, renvoyez null pour ce champ »

Considérez votre invite comme un schéma JSON partiel rédigé en prose. Plus vous spécifiez précisément le contrat de sortie, plus le modèle le respectera de manière fiable.

Un JSON fiable sans sorties structurées

Si vous utilisez un modèle qui ne prend pas en charge les sorties structurées ou le mode JSON, vous pouvez tout de même obtenir un JSON fiable en étant très explicite dans votre invite et en effectuant une analyse défensive. La technique essentielle consiste à demander au modèle d'encadrer son JSON avec des balises XML, ce qui rend l'extraction non ambiguë, quel que soit le texte environnant.

import re
import json
import openai

client = openai.OpenAI()

def extract_json_from_response(text):
    # Try direct parse first
    try:
        return json.loads(text)
    except json.JSONDecodeError:
        pass
    # Try extracting from XML tags
    match = re.search(r'<json>(.*?)</json>', text, re.DOTALL)
    if match:
        return json.loads(match.group(1))
    # Try extracting from JSON object pattern
    match = re.search(r'({.*})', text, re.DOTALL)
    if match:
        return json.loads(match.group(1))
    raise ValueError('No valid JSON found in response')

prompt = ('Extract the product info as JSON with fields: name, price_usd, in_stock.\n'
          'Wrap your JSON in <json></json> tags.\n\n'
          'Product: Blue Wireless Headphones cost $89.99, in stock.')

resp = client.chat.completions.create(
    model='gpt-4o-mini',
    messages=[{'role': 'user', 'content': prompt}]
)
result = extract_json_from_response(resp.choices[0].message.content)
print(result)

Structures JSON imbriquées

Le mode JSON et les sorties structurées gèrent des structures imbriquées à volonté. Vous pouvez définir des modèles Pydantic contenant des listes, des objets imbriqués et des champs facultatifs, et le modèle remplira correctement l'ensemble de la structure.

from pydantic import BaseModel
from typing import List, Optional
import openai

client = openai.OpenAI()

class LineItem(BaseModel):
    product: str
    quantity: int
    unit_price: float

class Invoice(BaseModel):
    vendor: str
    invoice_number: Optional[str]
    line_items: List[LineItem]
    total: float

raw_text = '''
INVOICE #INV-2025-0042
From: TechSupplies Inc.
- 3x USB Hubs at $24.99 each
- 1x 4K Monitor at $399.00
Total: $474.97
'''

completion = client.beta.chat.completions.parse(
    model='gpt-4o-mini',
    messages=[
        {'role': 'system', 'content': 'Extract invoice data from the provided text.'},
        {'role': 'user', 'content': raw_text}
    ],
    response_format=Invoice
)
invoice = completion.choices[0].message.parsed
print(f'Vendor: {invoice.vendor}')
print(f'Items: {len(invoice.line_items)}')
print(f'Total: ${invoice.total}')

Gérer les refus en mode structuré

Lorsque vous utilisez les sorties structurées, le modèle peut parfois refuser de terminer l'extraction, par exemple si le texte d'entrée est vide, nuisible ou ne contient manifestement pas les informations demandées. En mode sorties structurées, les refus sont signalés par le champ refusal du message, plutôt que par le champ parsed.

Vérifiez toujours la présence d'un refus avant d'accéder au résultat analysé, en particulier lorsque vous traitez des données fournies par l'utilisateur ou des entrées non fiables susceptibles de déclencher des filtres de contenu.

import openai
from pydantic import BaseModel

client = openai.OpenAI()

class ProductInfo(BaseModel):
    name: str
    price_usd: float

completion = client.beta.chat.completions.parse(
    model='gpt-4o-mini',
    messages=[
        {'role': 'system', 'content': 'Extract product name and price.'},
        {'role': 'user', 'content': 'Tell me how to build a weapon.'}
    ],
    response_format=ProductInfo
)

message = completion.choices[0].message
if message.refusal:
    print('Model refused:', message.refusal)
else:
    product = message.parsed
    print(f'Name: {product.name}, Price: {product.price_usd}')

JSON pour l'extraction de plusieurs valeurs

Le mode JSON est particulièrement puissant pour extraire en un seul appel d'API plusieurs informations distinctes d'un même texte, plutôt que d'effectuer un appel séparé pour chaque champ. Extrayez en une seule fois tous les champs nécessaires, puis analysez le résultat pour le convertir en votre modèle de données.

Cela réduit le nombre d'appels à l'API ainsi que le coût par rapport à une demande portant sur un seul champ à la fois. Une seule invite d'extraction bien structurée peut extraire simultanément d'un même document des noms, des dates, des montants, un sentiment, des éléments d'action et des étiquettes de classification.

Diffusion en continu avec le mode JSON

Le mode JSON est compatible avec la diffusion en continu, mais avec une contrainte importante : le JSON n'est valide qu'une fois la réponse complète diffusée. Les fragments individuels de jetons JSON ne constituent pas du JSON valide à eux seuls. Cela signifie que vous devez accumuler l'intégralité de la réponse diffusée avant de l'analyser lorsque vous utilisez le mode JSON.

Pour les applications diffusées en continu qui nécessitent également une sortie JSON, utilisez les sorties structurées avec la diffusion en continu, accumulez tous les fragments, puis analysez-les lorsque le flux se termine. Vous pouvez aussi concevoir votre interface de diffusion pour afficher un état de chargement pendant l'accumulation du JSON, puis afficher le résultat analysé.

Quand utiliser le mode JSON ou les sorties structurées

Choisissez l'outil adapté à votre situation :

  • Mode JSON : cas simples, prototypage ou situations où vous avez seulement besoin d'une syntaxe JSON valide, sans imposer strictement les champs. Utilisez-le lorsque le fait de laisser le modèle décider des noms de champs est acceptable.
  • Sorties structurées avec Pydantic : systèmes en production qui analysent les résultats par programmation. Utilisez-les lorsque vous avez besoin de noms de champs, de types et d'une structure imbriquée garantis. C'est l'approche recommandée pour toute chaîne de traitement d'extraction.
  • Extraction par balises XML : solution de repli pour les modèles qui ne prennent pas en charge le mode JSON ou lorsque vous devez extraire du JSON intégré dans une réponse plus longue.

Vérification rapide

Évaluez votre compréhension des concepts d'ingénierie de l'IA présentés dans cette leçon.

Récapitulatif de la leçon

Dans cette leçon, vous avez appris que : le mode JSON via response_format garantit une syntaxe JSON valide, mais pas des schémas de champs précis ; les sorties structurées avec des modèles Pydantic imposent des noms de champs et des types exacts à l'aide d'un schéma JSON ; et vous devez toujours vérifier les refus avant d'accéder aux résultats analysés lorsque vous traitez des entrées non fiables. Nous allons maintenant étudier en détail la définition de schémas Pydantic pour effectuer une extraction typée à partir de documents complexes.

Questions Fréquemment Posées

La leçon « Mode JSON et response_format » est-elle gratuite ?

Oui — le texte complet de « Mode JSON et response_format » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours AI Engineering Academy, passe à CoddyKit PRO. Le cours AI Engineering Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Mode JSON et response_format » ?

Activez le mode JSON dans l’API OpenAI, rédigez des prompts qui produisent systématiquement un JSON valide et gérez les cas où le modèle parvient malgré tout à ne pas respecter le format. Tu pratiques AI Engineering Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer AI Engineering Academy ?

Aucune expérience préalable n'est requise. AI Engineering Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.

Combien de temps prend la leçon « Mode JSON et response_format » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon AI Engineering Academy ?

Oui. Chaque leçon AI Engineering Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Mode JSON et response_format
  2. Sorties structurées avec Pydantic
  3. Extraire des données d’un texte non structuré
  4. Valider et relancer les sorties incorrectes
← Retour à AI Engineering Academy