Guide

Statut éditorial : En attente de relecture

Structurer les sorties d’un LLM avec Instructor et Pydantic

Obtenir des objets Python validés depuis un modèle, gérer les erreurs et limiter les nouvelles tentatives avec Instructor et Pydantic.

Classification du contenu

Types

  • Intelligence artificielle

Technologies

Niveau
Intermédiaire
Publié le
13 août 2026
Prochaine vérification
13 novembre 2026

Une application exploite plus facilement un objet validé qu’un bloc de texte à parser. Instructor adapte les clients de modèles pour demander une réponse conforme à un modèle Pydantic, valider le résultat et, si vous l’autorisez, renvoyer les erreurs au modèle pour une nouvelle tentative.

Le problème du « JSON presque valide »

Demander « réponds en JSON » ne suffit pas. Le modèle peut ajouter du Markdown, oublier un champ, changer un type ou produire une valeur hors domaine. Un parseur JSON vérifie la syntaxe ; il ne vérifie pas qu’une priorité vaut de 1 à 3 ou qu’une adresse possède la forme attendue.

Pydantic exprime ces contraintes dans un schéma utilisé à la fois pour guider le modèle et valider la réponse.

Définir la sortie attendue

from typing import Literal

from pydantic import BaseModel, Field


class TicketAnalyse(BaseModel):
    resume: str = Field(min_length=10, max_length=240)
    priorite: Literal["basse", "normale", "haute"]
    equipe: Literal["facturation", "technique", "commercial"]
    confiance: float = Field(ge=0, le=1)

Le schéma doit décrire ce dont le programme a réellement besoin. Évitez les dizaines de champs facultatifs : ils augmentent l’ambiguïté et rendent l’évaluation plus difficile.

Appeler le modèle avec Instructor

L’API exacte dépend du fournisseur et de la version du client. Une forme courante consiste à créer un client Instructor puis à passer le modèle Pydantic comme response_model :

import instructor
from openai import OpenAI

client = instructor.from_openai(OpenAI())

analyse = client.chat.completions.create(
    model="gpt-5",
    response_model=TicketAnalyse,
    messages=[
        {
            "role": "user",
            "content": (
                "Analyse ce ticket sans inventer de contexte : "
                "Le paiement est débité deux fois depuis ce matin."
            ),
        }
    ],
)

print(analyse.priorite)

Le résultat est un objet TicketAnalyse, pas une chaîne JSON. Le code aval bénéficie des types et des erreurs de validation explicites.

Validation de forme et validation métier

Pydantic peut vérifier des longueurs, bornes, formats et relations déterministes. Il ne peut pas savoir à lui seul si le résumé est fidèle au ticket ou si l’équipe choisie est pertinente.

Séparez trois niveaux :

  1. **syntaxe** : le résultat peut-il être décodé ?
  2. **schéma** : champs, types et contraintes sont-ils valides ?
  3. **sémantique** : la réponse est-elle exacte et utile pour ce cas ?

Les deux premiers niveaux sont automatisables. Le troisième nécessite règles métier, données de référence, évaluations et parfois validation humaine.

Utiliser les nouvelles tentatives avec prudence

Instructor peut renvoyer au modèle les erreurs de validation. Cela aide à corriger une valeur hors borne ou un champ manquant. Définissez un petit nombre maximal de reprises : chaque tentative augmente latence et coût, et une erreur sémantique ne disparaît pas nécessairement.

analyse = client.chat.completions.create(
    model="gpt-5",
    response_model=TicketAnalyse,
    max_retries=2,
    messages=[...],
)

Une configuration max_retries=2 signifie généralement l’essai initial puis jusqu’à deux reprises. Enregistrez le nombre d’essais et la cause finale sans conserver de données sensibles inutiles.

Concevoir un bon schéma

Si le modèle doit citer une source, demandez un extrait ou un identifiant contrôlable puis vérifiez qu’il existe réellement dans le contexte fourni.

Gérer les échecs dans l’application

La validation peut encore échouer après les reprises. Prévoyez un chemin explicite : placer la tâche en revue, demander une information manquante, appliquer une valeur sûre ou renvoyer une erreur contrôlée.

Ne convertissez pas silencieusement toute erreur en objet par défaut. Cela masquerait les dégradations du modèle et contaminerait les données métier.

Tester la fiabilité

Créez un jeu de tickets normaux, ambigus, contradictoires et malveillants. Mesurez :

Testez également le schéma sans modèle avec des objets invalides. Les validateurs déterministes méritent leurs propres tests unitaires.

À retenir

Instructor et Pydantic transforment une sortie probabiliste en contrat logiciel mieux contrôlé. Ils réduisent les erreurs de format ; ils ne remplacent ni la vérification factuelle ni les règles d’autorisation. Un petit schéma, des reprises bornées et un chemin d’échec visible donnent de meilleurs résultats qu’une validation excessivement complexe.

Sources utilisées