Extraction de métadonnées structurées
Extraire exactement ce dont vous avez besoin
L’annotation de document ne se limite pas à extraire du texte brut. Elle permet d’obtenir des données structurées, typées et validées, directement exploitables dans vos systèmes. Dans cette leçon, vous apprendrez à concevoir des schémas d’extraction avancés.
Schémas Pydantic avancés
Types complexes et optionnels
from pydantic import BaseModel, Field
from typing import Optional
from enum import Enum
class TypeDocument(str, Enum):
FACTURE = "facture"
CONTRAT = "contrat"
RAPPORT = "rapport"
FORMULAIRE = "formulaire"
AUTRE = "autre"
class Adresse(BaseModel):
rue: Optional[str] = Field(None, description="Numéro et rue")
code_postal: Optional[str] = Field(None, description="Code postal")
ville: Optional[str] = Field(None, description="Ville")
pays: str = Field(default="France", description="Pays")
class EntiteJuridique(BaseModel):
nom: str = Field(..., description="Raison sociale")
siret: Optional[str] = Field(None, description="Numéro SIRET")
adresse: Optional[Adresse] = Field(None, description="Adresse postale")
email: Optional[str] = Field(None, description="Adresse email")
class ExtractionDocument(BaseModel):
type_document: TypeDocument = Field(
..., description="Type du document"
)
date: Optional[str] = Field(
None, description="Date principale (YYYY-MM-DD)"
)
emetteur: EntiteJuridique = Field(
..., description="Entité qui émet le document"
)
destinataire: Optional[EntiteJuridique] = Field(
None, description="Entité destinataire"
)
resume: str = Field(
..., description="Résumé en 2-3 phrases du contenu"
)
langue: str = Field(
..., description="Langue du document (code ISO 639-1)"
)
Listes et données répétitives
Pour extraire des éléments multiples (lignes de facture, clauses, etc.) :
from pydantic import BaseModel, Field
class LigneFacture(BaseModel):
description: str = Field(..., description="Description du produit/service")
quantite: float = Field(..., description="Quantité")
prix_unitaire: float = Field(..., description="Prix unitaire HT")
montant: float = Field(..., description="Montant total HT de la ligne")
class FactureDetaillee(BaseModel):
fournisseur: str = Field(..., description="Nom du fournisseur")
numero: str = Field(..., description="Numéro de facture")
date: str = Field(..., description="Date (YYYY-MM-DD)")
lignes: list[LigneFacture] = Field(
..., description="Lignes de la facture"
)
sous_total_ht: float = Field(..., description="Sous-total HT")
tva: float = Field(..., description="Montant TVA")
total_ttc: float = Field(..., description="Total TTC")
conditions_paiement: str = Field(
..., description="Conditions de paiement mentionnées"
)
Champs booléens et cases à cocher
Le modèle excelle dans l’extraction de formulaires à cases à cocher :
from pydantic import BaseModel, Field
class ReponseFormulaire(BaseModel):
question: str = Field(..., description="Intitulé de la question")
reponse: bool = Field(..., description="True si coché, False sinon")
class FormulaireMedical(BaseModel):
nom_patient: str = Field(..., description="Nom complet du patient")
age: Optional[int] = Field(None, description="Âge du patient")
sexe: Optional[str] = Field(None, description="Sexe (M/F)")
numero_patient: Optional[str] = Field(None, description="ID patient")
telephone: Optional[str] = Field(
None, description="Numéro de téléphone (null si non fourni)"
)
reponses: list[ReponseFormulaire] = Field(
..., description="Réponses aux questions du formulaire"
)
Comme démontré par l’équipe Mistral, le modèle est capable de :
- Reconnaître si une case est cochée ou non
- Inférer qu’un champ est absent plutôt que d’inventer une valeur
- Extraire les questions associées à chaque case
Appel complet avec schéma avancé
import os
import json
from mistralai import Mistral
from mistralai.extra import response_format_from_pydantic_model
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
ocr_response = client.ocr.process(
model="mistral-ocr-latest",
document={
"type": "document_base64",
"document_base64": document_base64
},
document_annotation_format=response_format_from_pydantic_model(
FactureDetaillee
),
document_annotation_prompt=(
"Ce document est une facture. Extrais toutes les lignes "
"de facturation avec leurs montants."
)
)
# Extraction et validation
for page in ocr_response.pages:
if page.document_annotation:
facture = FactureDetaillee.model_validate_json(
page.document_annotation
)
print(f"Facture {facture.numero} - {facture.fournisseur}")
print(f"Date : {facture.date}")
print(f"\nLignes :")
for ligne in facture.lignes:
print(f" - {ligne.description}: {ligne.quantite} x "
f"{ligne.prix_unitaire}€ = {ligne.montant}€")
print(f"\nTotal TTC : {facture.total_ttc}€")
Bonnes pratiques pour les schémas
- Descriptions précises : chaque
Fielddoit avoir une description claire et sans ambiguïté - Types optionnels : utilisez
Optionalpour les champs qui peuvent être absents - Valeurs par défaut : fournissez des défauts sensés (
default="France"pour le pays) - Enums : utilisez des enums pour les champs à valeurs limitées
- Imbrication : structurez vos schémas en sous-modèles réutilisables
- Descriptions en français : le modèle comprend les descriptions dans la langue du document
Points clés à retenir
- Les schémas Pydantic permettent d’extraire des données typées et validées
- Utilisez des types complexes (listes, enums, modèles imbriqués) pour des extractions précises
- Le modèle gère les champs optionnels et les cases à cocher avec fiabilité
- Les descriptions des champs guident l’extraction : soyez précis et explicite
- Combinez le
document_annotation_promptavec le schéma pour un contexte maximal