Aller au contenu principal

Définir des schémas avec Pydantic

Pydantic : le socle des Custom Structured Outputs en Python

Pydantic est la bibliothèque de validation de données la plus populaire en Python. Elle permet de définir des modèles de données avec des types stricts, et c’est exactement ce que l’API Mistral utilise pour les Custom Structured Outputs.

Si vous travaillez en Python, Pydantic est votre outil principal pour définir les schémas de sortie.

Installer Pydantic

Pydantic est inclus comme dépendance du SDK Mistral. Si vous avez déjà installé mistralai, Pydantic est disponible :

pip install mistralai
# Pydantic v2 est inclus automatiquement

Pour vérifier la version :

import pydantic
print(pydantic.__version__)  # 2.x requis

Définir un modèle simple

Un modèle Pydantic est une classe qui hérite de BaseModel. Chaque attribut est un champ avec un type explicite :

from pydantic import BaseModel

class Contact(BaseModel):
    name: str
    email: str
    phone: str
    company: str

Ce modèle dit à Mistral : “ta sortie doit être un objet JSON avec exactement ces 4 champs, tous de type string.”

Types supportés

Pydantic supporte tous les types Python standards, et Mistral les comprend tous :

from pydantic import BaseModel
from typing import Optional
from enum import Enum

class Priority(str, Enum):
    low = "low"
    medium = "medium"
    high = "high"
    critical = "critical"

class TicketAnalysis(BaseModel):
    # Types de base
    title: str
    description: str
    ticket_id: int
    confidence: float
    is_urgent: bool

    # Types optionnels
    assignee: Optional[str] = None

    # Enums (valeurs contraintes)
    priority: Priority

    # Listes
    tags: list[str]
    related_ids: list[int]

Résumé des types

  • str — chaîne de caractères
  • int — nombre entier
  • float — nombre décimal
  • bool — booléen (true/false)
  • list[T] — liste d’éléments de type T
  • Optional[T] — champ pouvant être null
  • Enum — valeur parmi un ensemble fini

Modèles imbriqués (nested models)

Pour des structures complexes, vous pouvez imbriquer des modèles :

from pydantic import BaseModel
from typing import Optional

class Address(BaseModel):
    street: str
    city: str
    postal_code: str
    country: str

class Company(BaseModel):
    name: str
    industry: str
    address: Address  # Modèle imbriqué

class Person(BaseModel):
    first_name: str
    last_name: str
    email: str
    role: str
    company: Company  # Imbrication à deux niveaux

Le JSON correspondant sera :

{
  "first_name": "Marie",
  "last_name": "Dupont",
  "email": "[email protected]",
  "role": "Directrice commerciale",
  "company": {
    "name": "TechVision SAS",
    "industry": "Technologie",
    "address": {
      "street": "42 rue de la Paix",
      "city": "Paris",
      "postal_code": "75002",
      "country": "France"
    }
  }
}

Listes de modèles

Pour extraire plusieurs éléments structurés :

from pydantic import BaseModel

class Product(BaseModel):
    name: str
    price: float
    category: str
    in_stock: bool

class Catalog(BaseModel):
    products: list[Product]
    total_count: int

Descriptions de champs

Ajoutez des descriptions pour guider le modèle. Elles sont incluses dans le schéma JSON envoyé à Mistral :

from pydantic import BaseModel, Field

class SentimentAnalysis(BaseModel):
    sentiment: str = Field(
        description="Le sentiment global : 'positif', 'négatif' ou 'neutre'"
    )
    score: float = Field(
        description="Score de confiance entre 0.0 et 1.0"
    )
    keywords: list[str] = Field(
        description="Les 3-5 mots-clés principaux du texte"
    )
    summary: str = Field(
        description="Résumé en une phrase maximum"
    )

Les descriptions agissent comme des instructions supplémentaires pour le modèle. Plus elles sont précises, meilleure sera la qualité de la sortie.

Valeurs par défaut et champs optionnels

from pydantic import BaseModel, Field
from typing import Optional

class ArticleMetadata(BaseModel):
    title: str
    author: str
    language: str = Field(default="fr", description="Code langue ISO 639-1")
    word_count: Optional[int] = None
    tags: list[str] = Field(default_factory=list)

Les champs avec des valeurs par défaut seront remplis par le modèle s’il trouve l’information, ou laisseront la valeur par défaut sinon.

Validation automatique

Un avantage majeur de Pydantic : la validation est automatique. Si le modèle retourne un type incorrect, Pydantic lèvera une erreur immédiate :

from pydantic import ValidationError

try:
    analysis = SentimentAnalysis(
        sentiment="positif",
        score="pas un nombre",  # Erreur de type
        keywords=["test"],
        summary="Résumé"
    )
except ValidationError as e:
    print(e)
    # 1 validation error for SentimentAnalysis
    # score
    #   Input should be a valid number [type=float_parsing, ...]

Points clés à retenir

  • Pydantic BaseModel est la base de tous les schémas Custom en Python
  • Utilisez des types explicites : str, int, float, bool, list[T], Optional[T]
  • Les modèles imbriqués permettent des structures JSON complexes
  • Field(description=...) améliore la qualité de la sortie en guidant le modèle
  • La validation est automatique — les erreurs de type sont détectées immédiatement