Brief IA : Pydantic et OpenAI : Révolutionner les sorties structurées des LLM

Pydantic et OpenAI : Révolutionner les sorties structurées des LLM

Brief IA
Tom Levy·6 min·0 vues

L'intégration de Pydantic avec OpenAI améliore la gestion des sorties structurées des modèles de langage. Pydantic permet une validation automatique des données, garantissant des réponses conformes aux schémas définis. L'utilisation de Pydantic simplifie la manipulation des données imbriquées et renforce la sécurité des applications.

En bref
1L'intégration de Pydantic avec OpenAI améliore la gestion des sorties structurées des modèles de langage.
2Pydantic permet une validation automatique des données, garantissant des réponses conformes aux schémas définis.
3L'utilisation de Pydantic simplifie la manipulation des données imbriquées et renforce la sécurité des applications.
💡Pourquoi c'est importantCette combinaison offre une solution robuste pour développer des applications IA fiables et maintenables, cruciales pour les entreprises utilisant des LLM.
Le brief IA que lisent les pros

La recherche en IA te passionne ?

Les papers et avancées qui comptent, expliqués simplement, chaque soir. Gratuit.

Inclus dès l'inscription : notre sélection des meilleurs guides & comparatifs IA.

Choisis ton rythme

Gratuit · Pas de spam · Désabonnement en 1 clic

📄
L'analyse en français

Applications des LLM

Dans le domaine des modèles de langage, obtenir des réponses structurées et lisibles par machine est essentiel pour de nombreuses applications. Trois approches principales se distinguent pour atteindre cet objectif : le JSON Mode, le Function Calling, et les Structured Outputs d'OpenAI. Ces méthodes permettent de structurer les données renvoyées par les modèles de langage, facilitant ainsi leur intégration dans des systèmes automatisés.

Cependant, une nouvelle dimension est ajoutée avec l'introduction de Pydantic. Cette bibliothèque Python, bien que distincte des fonctionnalités d'OpenAI, s'avère être un complément puissant. Elle permet de traiter le JSON renvoyé par les modèles, en assurant la validation des types de données, l'accès aux champs, et la gestion des valeurs inattendues. Ainsi, Pydantic se positionne comme un outil indispensable pour ceux qui cherchent à construire des applications fiables et robustes basées sur des LLM.

À mon avis, la combinaison de Pydantic et des Structured Outputs d'OpenAI constitue la configuration la plus propre actuellement disponible pour construire des applications fiables alimentées par des LLM en Python. À la fin de cet article, vous comprendrez exactement pourquoi.

Qu'est-ce que Pydantic ?

Pydantic est une bibliothèque qui se concentre sur la validation des données à l'aide d'annotations de type en Python. Elle permet de définir la structure et les types des données sous forme de classes Python, et de vérifier que les données fournies respectent ces définitions. En cas de non-conformité, Pydantic génère des erreurs claires, évitant ainsi la propagation de données incorrectes dans le système.

Prenons un exemple simple :

from pydantic import BaseModel

class PersonInfo(BaseModel):
    name: str
    age: int
    city: str

Ce modèle impose que name et city soient des chaînes de caractères, tandis que age doit être un entier. Si une tentative est faite pour créer un PersonInfo avec un age sous forme de chaîne, Pydantic le détectera immédiatement et signalera l'erreur.

Contrairement aux méthodes précédentes comme le JSON Mode ou le Function Calling, qui peuvent renvoyer des réponses non conformes au schéma, Pydantic assure que les données sont toujours conformes et valides. Cela est particulièrement utile lorsque l'on travaille avec les Structured Outputs d'OpenAI, car cela garantit que le JSON renvoyé est conforme au schéma défini, tout en étant traité de manière plus efficace et sécurisée en Python.

Avec Pydantic, nous définissons notre schéma sous forme de classe Python, et l'intégration avec l'API d'OpenAI signifie que nous obtenons un véritable objet Python, et non un dictionnaire, avec tous les champs typés et validés automatiquement. Le JSON Schema dont l'API a besoin est généré à partir de notre modèle Pydantic en arrière-plan. Nous n'avons jamais à l'écrire nous-mêmes. En d'autres termes, Pydantic est la couche de définition de schéma qui se trouve entre notre code Python et l'API d'OpenAI, rendant l'ensemble de l'expérience de sortie structurée plus propre, plus sûre et plus maintenable.

Comparaison pratique de Pydantic avec les Structured Outputs

Voyons comment l'intégration de Pydantic améliore l'utilisation des Structured Outputs. Avant Pydantic, obtenir une sortie structurée impliquait de définir le schéma comme un dictionnaire brut et de parser manuellement les résultats.

from openai import OpenAI

client = OpenAI(api_key="your_api_key")

schema = {
    "type": "function",
    "name": "extract_person_info",
    "properties": {
        "name": {"type": "string"},
        "age": {"type": "integer"},
        "city": {"type": "string"}
    },
    "required": ["name", "age", "city"],
    "additionalProperties": False
}

response = client.chat.completions.create(
    model="[gpt](/glossaire/gpt)-4o-mini",
    tool_choice={"type": "function", "function": {"name": "extract_person_info"}},
    messages=[{"role": "user", "content": "Extract info from: 'Maria is 32 years old and lives in Athens.'"}]
)

result = json.loads(response.choices[0].message.tool_calls[0].function.arguments) print(result["name"]) # "Maria" print(result["age"]) # pourrait être "32" au lieu de 32


Avec Pydantic, ce processus est simplifié et sécurisé :

```python
from openai import OpenAI
from pydantic import BaseModel

client = OpenAI(api_key="your_api_key")

class PersonInfo(BaseModel):
    name: str
    age: int
    city: str

response = client.beta.chat.completions.parse(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Extract info from: 'Maria is 32 years old and lives in Athens.'"}],
    response_format=PersonInfo
)

result = response.choices[0].message.parsed
print(result.name)   # "Maria"
print(result.age)    # 32
print(result.city)   # "Athens"

La version utilisant Pydantic est non seulement plus concise, mais elle garantit également que les données sont correctement typées et validées. En passant notre modèle Pydantic à response_format, le SDK d'OpenAI génère automatiquement le JSON Schema et parse la réponse en un objet Python complet.

De plus, notez la méthode .parse(), au lieu de la méthode habituelle .create(). Cela est dû au fait que .parse() est une méthode du SDK d'OpenAI spécifiquement conçue pour fonctionner avec des modèles Pydantic, gérant l'ensemble du pipeline de sortie structurée de bout en bout.

Construire avec Pydantic

1. Modèles imbriqués et listes

Pydantic excelle dans la gestion des structures de données imbriquées. Définir des schémas JSON pour des objets imbriqués peut être fastidieux, mais avec Pydantic, il suffit de créer des classes Python :

from pydantic import BaseModel
from typing import List

class Address(BaseModel):
    city: str

class ContactInfo(BaseModel):
    address: Address
    phone_numbers: List[str]

response = client.beta.chat.completions.parse(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Extract contact info from: 'Maria Mouschoutzi, [email protected], Ermou 15, Athens, Greece. Phone: +30 210 1234567, +30 697 8901234'"}],
    response_format=ContactInfo
)

contact = response.choices[0].message.parsed
print(contact.name)                 # "Maria Mouschoutzi"
print(contact.address.city)        # "Athens"
print(contact.phone_numbers[0])    # "+30 210 1234567"

Avec Pydantic, les modèles imbriqués sont validés automatiquement, et l'accès aux champs se fait de manière intuitive. Cela réduit considérablement le risque d'erreurs comme les KeyError.

2. Validation avec les champs Pydantic

Pydantic offre également des fonctionnalités avancées de validation des données. En utilisant Field, il est possible d'ajouter des contraintes explicites sur les valeurs acceptables.

from pydantic import BaseModel, Field
from typing import Optional

class ProductReview(BaseModel):
    product_name: str = Field(description="Le nom du produit évalué")
    rating: int = Field(ge=1, le=5, description="Évaluation de 1 à 5 étoiles")
    sentiment: str = Field(description="Un des : positif, neutre, négatif")
    summary: str = Field(max_length=200, description="Un bref résumé de l'avis")
    verified_purchase: Optional[bool] = Field(default=None, description="S'il s'agit d'un achat vérifié")

response = client.beta.chat.completions.parse(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Extract a structured review from: 'Absolutely love this coffee machine! Makes perfect espresso every time. 5 stars, would recommend to anyone.'"}],
    response_format=ProductReview
)

review = response.choices[0].message.parsed
print(review.product_name)   # "coffee machine"
print(review.rating)         # 5
print(review.sentiment)      # "positive"
print(review.summary)        # "Makes perfect espresso every time."

Les contraintes sur le champ rating assurent que seules les évaluations entre 1 et 5 sont acceptées. De plus, les descriptions des champs servent de guide pour le modèle, améliorant ainsi la précision des données renvoyées.

Enfin, en cas de refus du modèle, le SDK d'OpenAI gère cela de manière élégante, en fournissant des informations sur la raison du refus. Cela est crucial pour les applications en production, où la transparence et la gestion des erreurs sont essentielles.

Ainsi, voici comment un refus du modèle avec Pydantic se déroulerait :

response = client.beta.chat.completions.parse(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Extract info from the job posting above."}],
    response_format=JobPosting
)

message = response.choices[0].message
if message.refusal:
    print(f"Model refused: {message.refusal}")
job = message.parsed
print(f"Extracted: {job.job_title} at {job.company_name}")

Suivez Brief IA

L'actu IA du jour, aussi dans votre fil.

Commentaires