Atelier : Extraction Structurée
Mis à jour le 28 juillet 2026
Objectif de cet atelier
Cet atelier pousse plus loin une compétence entrevue dans le précédent : l’extraction structurée, c’est-à-dire transformer du texte libre en données exploitables par un programme. C’est le pont entre le langage naturel et vos systèmes d’information — la facture reçue en PDF devient une ligne dans votre logiciel comptable, l’article de veille devient une entrée de dashboard. Vous y pratiquerez trois exercices avec les modèles Mistral : l’extraction JSON, le résumé de document au format imposé et la traduction technique avec préservation du formatage. Vous y retrouverez aussi deux techniques vues dans la section sur les paramètres : le pré-remplissage assistant et les stop sequences.
Exercice 1 : Extraction JSON depuis un texte libre
Situation de départ : vous automatisez le traitement de factures reçues par email. Le texte varie d’un fournisseur à l’autre, mais vous devez toujours extraire les mêmes champs. Le system prompt verrouille tout ce qui peut l’être : JSON pur sans commentaire, null pour les champs absents (et pas « non renseigné » ni chaîne vide, car votre code testera is None), montants en nombres sans symbole monétaire, dates en ISO 8601, TVA séparée du HT. Chacune de ces règles évite un bug de parsing en aval.
messages = [
{
"role": "system",
"content": """Vous êtes un extracteur de données spécialisé dans les documents comptables.
Règles strictes :
- Retournez UNIQUEMENT du JSON valide, sans commentaire ni texte additionnel
- Si un champ n'est pas trouvé, mettez null (pas "non renseigné", pas "")
- Les montants doivent être des nombres (pas de symbole euro dans la valeur)
- Les dates au format ISO 8601 (YYYY-MM-DD)
- La TVA doit être extraite séparément du montant HT"""
},
{
"role": "user",
"content": """Extrayez les données de cette facture :
"FACTURE N° 2026-0847
Date : 15 mars 2026
De : CloudServ SAS
42 rue de la Paix, 75002 Paris
SIRET : 823 456 789 00012
À : TechCorp SARL
12 avenue des Champs, 69001 Lyon
Désignation : Hébergement cloud - Pack Premium
Période : 01/03/2026 au 31/03/2026
Montant HT : 1 250,00 EUR
TVA 20% : 250,00 EUR
Total TTC : 1 500,00 EUR
Conditions de paiement : 30 jours fin de mois
IBAN : FR76 3000 4000 0500 0001 2345 678"
Schéma JSON :
{
"numero_facture": "string",
"date_facture": "string (YYYY-MM-DD)",
"fournisseur": {
"nom": "string",
"adresse": "string",
"siret": "string"
},
"client": {
"nom": "string",
"adresse": "string"
},
"lignes": [
{
"designation": "string",
"periode": "string",
"montant_ht": "number"
}
],
"tva_taux": "number",
"tva_montant": "number",
"total_ttc": "number",
"conditions_paiement": "string",
"iban": "string"
}"""
},
{
"role": "assistant",
"content": "{"
}
]
response = client.chat.complete(
model="mistral-large-latest",
messages=messages,
temperature=0.0,
stop=["\n}"]
)
# Reconstruire le JSON : "{" + response + "\n}"
Le résultat attendu :
{
"numero_facture": "2026-0847",
"date_facture": "2026-03-15",
"fournisseur": {
"nom": "CloudServ SAS",
"adresse": "42 rue de la Paix, 75002 Paris",
"siret": "823 456 789 00012"
},
"client": {
"nom": "TechCorp SARL",
"adresse": "12 avenue des Champs, 69001 Lyon"
},
"lignes": [
{
"designation": "Hébergement cloud - Pack Premium",
"periode": "01/03/2026 au 31/03/2026",
"montant_ht": 1250.00
}
],
"tva_taux": 20,
"tva_montant": 250.00,
"total_ttc": 1500.00,
"conditions_paiement": "30 jours fin de mois",
"iban": "FR76 3000 4000 0500 0001 2345 678"
}
Remarquez la combinaison du pré-remplissage assistant (le message "{") et de la stop sequence : la première force le modèle à entrer directement dans le JSON sans préambule du type « Voici les données extraites : », la seconde l’empêche de continuer après la fermeture. À vous ensuite de reconstruire le JSON complet côté code.
Exercice 2 : Résumé structuré de document
Deuxième situation : vous alimentez un dashboard de veille interne avec des résumés de rapports longs. Pour que l’affichage soit uniforme, chaque résumé doit suivre exactement le même format — c’est le system prompt qui l’impose, champ par champ, avec des limites de longueur.
messages = [
{
"role": "system",
"content": """Vous produisez des résumés structurés pour un dashboard de veille.
Format obligatoire pour chaque résumé :
{
"titre_court": "max 60 caractères",
"resume": "max 3 phrases, factuel, sans opinion",
"impact_business": "faible | moyen | élevé",
"secteurs": ["liste des secteurs concernés"],
"action_requise": true/false,
"action_detail": "description si action requise, null sinon"
}"""
},
{
"role": "user",
"content": """Résumez cet article pour notre dashboard de veille :
"L'Union européenne a adopté le 28 mars 2026 un nouveau règlement sur
l'intelligence artificielle (AI Act 2.0) qui renforce les obligations de
transparence pour les systèmes de génération de texte et d'images. Les
entreprises qui déploient des modèles de plus de 10 milliards de paramètres
devront désormais publier un rapport d'évaluation des risques trimestriel et
mettre en place un système de traçabilité des contenus générés. Les sanctions
pour non-conformité peuvent atteindre 6% du chiffre d'affaires mondial annuel.
Le règlement entre en vigueur le 1er janvier 2027, avec une période de
transition de 6 mois pour les entreprises déjà en activité. Les PME de moins
de 50 salariés bénéficient d'un régime allégé avec des obligations réduites
de reporting."
Retournez le JSON structuré."""
}
]
response = client.chat.complete(
model="mistral-large-latest",
messages=messages,
temperature=0.1
)
Voici ce que vous devez obtenir — un résumé factuel qui condense sans déformer, et un champ d’action qui traduit la veille en décision :
{
"titre_court": "AI Act 2.0 : nouvelles obligations de transparence IA",
"resume": "L'UE adopte un renforcement de l'AI Act imposant des rapports trimestriels pour les grands modèles. Les sanctions atteignent 6% du CA mondial. Entrée en vigueur le 1er janvier 2027 avec régime allégé pour les PME.",
"impact_business": "élevé",
"secteurs": ["intelligence artificielle", "technologie", "réglementation"],
"action_requise": true,
"action_detail": "Évaluer la conformité de nos modèles et planifier la mise en place du reporting trimestriel avant janvier 2027."
}
La température passe ici à 0.1 et non 0.0 : un résumé demande une légère latitude de formulation, contrairement à une extraction pure où chaque valeur vient du texte source.
Exercice 3 : Traduction technique avec préservation du format
Troisième situation : traduire de la documentation technique du français vers l’anglais en conservant exactement le formatage Markdown et les termes techniques qui ne doivent pas être traduits. Le piège de la traduction technique est là : un traducteur trop zélé traduira temperature en « température » dans un exemple de code, et la documentation cessera de correspondre à l’API réelle. La parade consiste à lister explicitement ce qui est intouchable.
messages = [
{
"role": "system",
"content": """Vous êtes un traducteur technique français vers anglais.
Règles :
- Conservez EXACTEMENT le formatage Markdown (titres, listes, code blocks)
- Ne traduisez PAS les termes entre backticks
- Ne traduisez PAS les noms de variables, fonctions ou paramètres
- Les blocs de code restent identiques (ne traduisez que les commentaires)
- Adaptez les expressions idiomatiques au contexte technique anglophone
- Utilisez l'anglais américain"""
},
{
"role": "user",
"content": """Traduisez ce passage de documentation :
## Configuration de l'API
Pour commencer, installez le package `mistralai` :
```bash
pip install mistralai
```
### Authentification
Vous devez configurer votre clé API avant tout appel :
```python
# Initialisation du client Mistral
client = Mistral(api_key="votre-clé")
```
**Important** : ne stockez jamais votre clé API en dur dans le code.
Utilisez plutôt des variables d'environnement ou un gestionnaire de secrets.
### Paramètres disponibles
- `temperature` : contrôle la créativité (défaut : 0.7)
- `top_p` : filtrage par probabilité cumulée (défaut : 1.0)
- `max_tokens` : limite de tokens en sortie"""
}
]
response = client.chat.complete(
model="mistral-large-latest",
messages=messages,
temperature=0.2
)
Pour valider le résultat, vérifiez point par point : les titres Markdown (##, ###) sont conservés, les termes entre backticks (mistralai, temperature, top_p, max_tokens) restent en anglais, les blocs de code sont identiques à l’exception du commentaire traduit, le gras (**Important**) est préservé et les listes gardent leur structure. Toute déviation sur l’un de ces points signale une règle à renforcer dans le system prompt.
Techniques avancées pour l’extraction
Une règle d’or traverse tout cet atelier : ne faites jamais confiance aveuglément à la sortie du modèle. Après extraction, validez toujours le JSON côté code :
import json
try:
data = json.loads(response.choices[0].message.content)
# Validation des champs obligatoires
required_fields = ["numero_facture", "date_facture", "total_ttc"]
for field in required_fields:
if field not in data or data[field] is None:
print(f"Champ manquant : {field}")
except json.JSONDecodeError:
print("Réponse invalide, relancer avec temperature=0")
Et si malgré tout le modèle ne retourne pas du JSON valide, procédez par escalade :
- Réessayez avec
temperature=0.0 - Utilisez le pré-remplissage assistant pour forcer le format
- Ajoutez un exemple (one-shot) de la sortie attendue
- En dernier recours, parsez la réponse avec une regex pour extraire le JSON
Points clés à retenir
- Le pré-remplissage assistant et les stop sequences garantissent un JSON valide
- Fournissez toujours le schéma JSON exact dans le prompt
- Température 0 pour l’extraction, 0.1-0.2 pour le résumé
- Validez systématiquement la sortie côté code
- Pour la traduction technique, listez explicitement ce qui ne doit pas être traduit