Aller au contenu
English

Extraire des rappels de produits en données structurées

  • Étude de cas 1
  • 180 min
  • Facultative · 1 étude de cas requise pour le certificat

Ce que vous saurez faire

Transformez de vrais avis de rappel de produits en fiches structurées qu’une équipe de sécurité peut consulter. Mesurez la fréquence des valeurs correctes pour chaque champ. Vous créez les vérifications qui bloquent une mauvaise fiche. Vous comparez du code sans modèle à trois modèles sur 40 avis vérifiés à la main. Vous trouvez les erreurs qui passent toutes les vérifications. Les rappels touchent la sécurité. Une personne vérifie donc chaque fiche avant son utilisation.

Étude de casPièce de portfolio

Durée
Environ 3 heures
S’exécute dans
VS Code, Python 3.12+
Compétences utilisées
  • Extraction d'information
  • Schéma Pydantic
  • Sortie structurée
  • Vérifications des règles d'affaires
  • Référence vérifiée à la main
  • Exactitude par champ
  • Coût pour 1 000 avis
  • Fournisseur simulé

Décompressez le projet de départ, ouvrez le dossier dans VS Code et suivez les étapes ci-dessous. Elles commencent par un nouvel environnement virtuel.

Le projet de départ est un petit projet Python, recall-extractor. Il reprend des éléments du projet du cours : l’adaptateur, le fournisseur simulé et les deux barrières. Il contient les 41 avis, la référence vérifiée à la main et de vraies réponses de modèles. Vous écrivez les vérifications des règles d’affaires et le calcul des scores. Le projet terminé présente le résultat, pour vous aider si vous bloquez ou souhaitez comparer. Le code est sous licence MIT. Vous pouvez donc publier votre version.

Avant de commencerCe qu’il faut savoir et avoir sous la mainEnviron 180 minutes

Ce que vous devez savoir

Cette étude de cas utilise surtout les modules 2 et 3 :

Cette page enseigne une nouvelle idée : l’extraction d’information et sa mesure champ par champ.

Ce qu’il vous faut sur votre ordinateur

  • Python 3.12 ou plus récent et VS Code, comme dans le cours. Environ 60 Mo d’espace disque libre pour les paquets.
  • Aucun compte ni aucune clé. Le fournisseur simulé rejoue les réponses enregistrées. Un essai réel avec un modèle local est facultatif, à la fin.

Testé avec Python 3.12.13 et 3.14.6 sur macOS (puce Apple). Versions : openai 3.26.1, pydantic 2.14.0, httpx 0.28.1, pytest 9.1.1. Les commandes Windows suivent celles du cours, mais elles n’ont pas été testées.

TermeLarkfieldUne boutique en ligne d’articles pour la maison. Ce n’est pas une vraie entreprise. Tous les cours Nextia utilisent son service d’assistance et ses données comme exemple.En savoir plus L'IA dans les produits de tous les joursBases d'une carrière en IA : rôles, compétences et feuilles de route vend des produits pour la maison et le jardin. Beaucoup se vendent aussi aux États-Unis sous la même marque. Quand un produit est dangereux, la Consumer Product Safety Commission (CPSC) des États-Unis publie un avis de rappel. L’avis décrit le produit, le danger, les mesures à prendre et le nombre d’unités vendues.

Le service de soutien de TermeGraceLa responsable du service d’assistance de Larkfield. Elle écrit la politique de support et décide ce qu’est une bonne réponse à un client. reçoit des questions comme « Mon appareil de chauffage fait-il partie du rappel? » Aujourd’hui, Grace lit chaque nouvel avis à la main. La CPSC en a publié 471 de janvier au début d’octobre 2026, soit environ 12 par semaine.

Grace veut une liste de sécurité avec une ligne par avis. Chaque ligne contient le produit, le danger, les unités, la mesure corrective, les dates de vente, les magasins et les coordonnées. Son équipe peut ensuite filtrer la liste (« appareils de chauffage, risque d’incendie, vendus depuis 2024 »). Elle peut aussi la comparer aux produits de Larkfield. TermeAmiraLa développeuse de Larkfield. Elle écrit le code des outils du service d’assistance dans les cours. construit l’outil qui remplit la liste. TermeOmarLe gestionnaire de produit de Larkfield. Il pose les questions d’affaires : ce qu’un changement coûte et ce qu’il apporte à la boutique. demande combien il coûte. TermePriyaLa scientifique des données de Larkfield. Elle mesure la qualité de l’assistant sur des jeux de test, pas à l’intuition. mesure la fréquence des résultats corrects. TermeTomásL’ingénieur en IA de Larkfield. Il propose souvent un raccourci rapide, et la leçon montre pourquoi il échoue. propose des raccourcis.

Grace garde la décision : quels rappels exigent une action cette semaine? L’outil prépare les fiches. Il ne décide pas, et une personne vérifie chaque fiche avant son ajout à la liste.

Larkfield et l’équipe sont fictifs. Les avis sont réels.

Transformez chaque avis en fiche avec des champs fixes. Une personne pourra la vérifier en une minute au lieu de lire l’avis complet. Les mesures ont été fixées avant toute exécution d’un modèle :

  • Champs corrects, comparés à une référence vérifiée à la main : 10 champs pour chacun des 40 avis, donc 400 valeurs.
  • Avis dont tous les champs sont corrects : une fiche avec un seul champ incorrect exige encore une correction.
  • Échecs à la barrière 1 (aucune fiche utilisable) et signalements à la barrière 2 (valeur contraire à l’avis), comptés séparément.
  • Coût pour 1 000 avis et temps par avis.

Le seuil de Grace : au-delà d’environ 1 champ incorrect sur 50, vérifier les fiches provisoires prend plus longtemps que lire les avis. La cible est donc de 98 % de champs corrects. Chaque échec et chaque signalement doivent être visibles pour la personne.

Imaginez une personne qui copie des formulaires papier dans un tableur. Certaines cases sont faciles : la date est imprimée, et la personne change seulement son format. D’autres demandent de l’attention : « environ 5 600, et 516 de plus au Canada » doit devenir un seul nombre. D’autres demandent du jugement : un lit à baldaquin est-il un « meuble »? Une personne compétente suit des règles écrites et laisse une case vide quand le formulaire ne dit rien.

L’extraction d’information confie ce travail à un programme. L’entrée est un texte écrit pour des personnes. La sortie est une fiche : les mêmes champs pour chaque texte, avec des valeurs dans des formats fixes. Un modèle aide ici parce qu’il lit le texte comme une personne. Le schéma de Définir un schéma fixe la structure de la fiche. L’image montre un avis réel, ligne par ligne, et les champs tirés de chaque ligne :

Sept lignes de l'avis 26382 de la CPSC à gauche, chacune avec une flèche vers les champs à droite. Nom du produit, cadres de lits à baldaquin Universal Broadmoore : choisir dans une liste, catégorie meubles. Danger, risques d'impact et de blessure : choisir dans une liste, dangers impact. Mesure corrective, réparation : choisir dans une liste, mesures correctives réparation. Date du rappel, 2 avril 2026 : changer le format, 2026-04-02. Unités, environ 5 600, plus environ 516 vendues au Canada : un nombre, États-Unis seulement, unités 5600. Coordonnées pour les consommateurs : copier, téléphone 800-357-0701 et courriel samson@rsvpcomm.com. Lieux de vente, en ligne sur Costco.com d'octobre 2024 à février 2026 : séparer les éléments, détaillants Costco.com, début de vente 2024-10, fin de vente 2026-02.
Un avis devient une fiche. Chaque champ demande un travail différent : copier, changer le format, additionner, séparer ou choisir dans une liste.

Chaque flèche nomme le type de travail, car chacun peut échouer différemment. Une copie peut venir du mauvais endroit. Une somme peut additionner les mauvais nombres. Un choix dans une liste peut être une supposition qui semble pourtant correcte. Le schéma vérifie seulement le format d’une valeur. Il ne peut pas vérifier si elle est vraie.

Les avis viennent de l’API des rappels de la CPSC. Elle fournit chaque avis en JSON, avec les mêmes sections que la page de l’avis sur cpsc.gov.

L’échantillon a été fixé une seule fois, le 8 octobre 2026 :

  1. Téléchargez tous les rappels du 1er janvier au 7 octobre 2026 : 471 avis.
  2. Gardez les rappels datés d’avril à juin 2026 : 160 avis.
  3. Gardez les 49 dont le produit pourrait se vendre dans un magasin pour la maison et le jardin. Excluez les jouets, les vêtements, les médicaments, les véhicules et l’équipement sportif.
  4. Tirez-en 40 avec une graine aléatoire fixe. Gardez un avis ultérieur, 26773 (septembre 2026), à part pour l’exécution de bout en bout.

Les 41 avis sont dans data/notices.json. Le projet vérifie leur somme de contrôle SHA-256 au chargement. Deux autres sources ont été comparées. Les données ouvertes de rappel de Santé Canada contiennent seulement de courtes étiquettes, sans unités, magasins ni dates. openFDA ne couvre pas les produits pour la maison. Le fichier DATASET.md du projet donne les détails.

La lecture des 40 avis a révélé quatre problèmes dans la source. Ils sont réels, et le projet les conserve :

Avis Problème
26554 Le titre parle de glacières Arctic Zone. Tous les autres champs parlent de pyjamas pour enfants. L’API a associé un titre au mauvais avis.
26444 Le titre indique que Thermos rappelle 8,2 millions d’unités. La ligne des unités indique 5,8 millions et 2,3 millions : 8,1 millions.
26406 La marque est BAYOTAK sur une ligne et BATOYAK sur une autre.
26423 Le courriel est collé au mot suivant : LR023784@outlook.comor.

La référence suit donc des règles écrites. Pour 26554, la fiche suit le corps du texte, car il contient le danger et les coordonnées. Pour 26444, la fiche suit la ligne des unités.

L’échantillon est aussi plus facile que la réalité. Les avis ont des sections nommées, et plusieurs sont presque identiques : 9 couvercles de drain de piscine ou de spa, 5 commodes, 4 nettoyeurs à pression. Gardez cela en tête quand vous lisez les résultats.

Un score exige une bonne réponse comme point de comparaison. L’auteur de l’étude de cas a fait la vérification. Il a lu chaque avis et rédigé sa fiche à la main, avec les règles fournies au modèle (recalls/prompts/extract.md). Cela s’est fait avant toute exécution d’un modèle, comme le montre l’historique du projet. Après les exécutions, l’auteur a relu les 3 champs où un TermeModèle hébergéUn modèle qui fonctionne sur les ordinateurs d’un fournisseur. Votre code lui envoie des requêtes par Internet, et vous payez chaque appel.En savoir plus Modèle hébergé ou autohébergéLes LLM : comment ils fonctionnent et comment en choisir un donnait une réponse différente. Aucune valeur n’a changé.

La référence est donc une lecture attentive de règles écrites, pas la vérité. Une personne a vérifié chaque avis une fois. Une deuxième personne rendrait la référence plus solide.

Les étapes utilisent VS Code et son terminal. Chaque commande s’exécute dans le dossier du projet.

  1. Téléchargez le projet de départ dans l’encadré en haut de cette page. Décompressez-le dans votre dossier de projets. Vous obtenez le dossier recall-extractor.

  2. Dans VS Code, choisissez File > Open Folder (fichier, ouvrir un dossier), puis ouvrez recall-extractor. Ouvrez ensuite un terminal : Terminal > New Terminal (terminal, nouveau terminal).

  3. Créez et activez un TermeEnvironnement virtuelUn dossier avec son propre Python et ses propres paquets, pour un seul projet. Les paquets installés là ne changent pas les autres projets.En savoir plus Isoler les dépendancesPython pour l'ingénierie de l'IA en pratique, puis installez les paquets :

    Fenêtre de terminal
    python3 -m venv .venv
    source .venv/bin/activate
    python -m pip install -r requirements.txt
  4. Exécutez les tests :

    Fenêtre de terminal
    python -m pytest

    La dernière ligne indique 12 failed, 20 passed (12 échecs, 20 réussites), puis le temps écoulé. Les 12 échecs correspondent à votre travail : les vérifications des règles d’affaires (partie 3) et le calcul des scores (partie 4). Quand ces tests réussissent, le projet est terminé.

  5. Regardez un avis tel que le modèle le voit :

    Fenêtre de terminal
    python -m recalls show 26382

    La sortie commence par :

    Recall number: 26382
    Title: Samson International Recalls Bellevue and Oaklynn Canopy Bed Frames Due to Impact and Injury Hazards
    Name of product: Universal Broadmoore brand Bellevue and Oaklynn model canopy bed frames
    Hazard: The canopy beams of the bed frames can collapse primarily when the bed is moved, posing impact and injury hazards to consumers.
    Remedy: Repair
    Recall date: April 2, 2026
    Units: About 5,600 (In addition, about 516 units were sold in Canada)

Les fichiers du projet, par rôle :

Fichier Son rôle
recalls/notices.py Charge les avis, vérifie le SHA-256 et présente chaque fiche en texte
recalls/schema.py La fiche, sous forme de modèle Pydantic et de schéma JSON strict
recalls/prompts/extract.md Les règles de chaque champ : le même texte avec et sans schéma
recalls/providers.py, recalls/config.py L’adaptateur du cours : le fournisseur simulé (par défaut) ou tout serveur compatible avec OpenAI
recalls/checks.py La barrière 1, parse(), et la barrière 2, check_rules()
recalls/score.py La comparaison avec data/reference.json
recalls/baseline.py La référence de base sans modèle
recordings/*.jsonl Les réponses que le fournisseur simulé rejoue

Ouvrez recalls/schema.py. La fiche compte 13 champs. Ces lignes font l’essentiel du travail :

recalls/schema.py (part)
Hazard = Literal["fire", "burn", "electric_shock", "fall", "tip_over", "entrapment", "drowning", "impact",
"laceration", "amputation", "chemical", "poisoning", "choking", "carbon_monoxide", "other"]
class RecallRecord(BaseModel):
model_config = ConfigDict(extra="forbid")
...
hazards: list[Hazard] = Field(min_length=1, max_length=4,
description="Every hazard type that the notice names. Use other if none fits.")
hazard_quote: str = Field(min_length=1, max_length=600,
description="The sentence of the notice that states the hazard, copied word for word.")
units: int | None = Field(description="Units sold in the United States, as a whole number. ...")
sold_from: str | None = Field(pattern=r"^\d{4}-\d{2}$",
description="The first month of sale, YYYY-MM. Null if the notice does not say.")
  • Énumérations avec « other » (autre). Des listes courtes permettent le filtrage : « tous les risques d’incendie » devient une seule requête. other (autre) donne au modèle une réponse honnête quand rien ne convient.
  • Une valeur nulle plutôt qu’une supposition. En mode strict, chaque champ est obligatoire. « Inconnu » doit donc être une valeur que le modèle peut écrire : null (valeur nulle).
  • Une citation comme preuve. hazard_quote montre d’où vient le danger. La barrière 2 vérifie que la citation se trouve vraiment dans l’avis.
  • Un format fixe pour chaque valeur. Les dates sont au format YYYY-MM-DD, les mois au format YYYY-MM et les unités sont un nombre entier. Le code peut ainsi les trier et les comparer.

Les règles de chaque champ se trouvent dans recalls/prompts/extract.md. Par exemple : « N’ajoutez pas les unités vendues au Canada, au Mexique ou dans un rappel antérieur. » Les mêmes règles ont guidé la référence vérifiée à la main. Chaque modèle est donc évalué selon les règles reçues, et non selon un corrigé secret.

recalls/request.py construit la requête de deux façons. Avec le schéma, il ajoute response_format avec strict: true, comme dans Définir un schéma. Avec --plain, il envoie les mêmes messages sans cet ajout. Seul le schéma change. La comparaison est donc équitable.

  1. Extrayez l’avis 26382 avec Termechat-smallLe nom que le code de Larkfield donne à un petit modèle hébergé peu coûteux : gpt-6-luna sur Azure. Le code utilise ce nom, donc le modèle peut changer sans modifier le code.En savoir plus Ce qu'est une API de LLMCréer des applications fiables avec les API de LLM et le schéma (les valeurs par défaut) :

    Fenêtre de terminal
    python -m recalls extract 26382

    La sortie (gpt-6-luna sur Azure, rejouée par le fournisseur simulé) :

    {
    "recall_number": "26382",
    "product_name": "Universal Broadmoore brand Bellevue and Oaklynn model canopy bed frames",
    "category": "furniture",
    "hazards": [
    "impact"
    ],
    "hazard_quote": "The canopy beams of the bed frames can collapse primarily when the bed is moved, posing impact and injury hazards to consumers.",
    "units": 5600,
    "remedies": [
    "repair"
    ],
    "recall_date": "2026-04-02",
    "sold_from": "2024-10",
    "sold_to": "2026-02",
    "retailers": [
    "Costco.com"
    ],
    "contact_phone": "800-357-0701",
    "contact_email": "samson@rsvpcomm.com"
    }
    valid | chat-small | schema | 1791 tokens in, 274 out (127 reasoning) | 2.26 s | US$0.00032
  2. Comparez la fiche à l’image ci-dessus. Le modèle a exclu les 516 unités vendues au Canada. Il n’a pas ajouté « blessure » comme type de danger. Les deux choix suivent les règles.

  3. Notez l’état : valid (valide). Dans le projet de départ, la barrière 2 est encore vide. Toute fiche qui respecte le schéma est donc valid. Vous écrivez la barrière 2 ensuite.

Partie 3 : la barrière 2, vérifiée contre l’avis

Section intitulée « Partie 3 : la barrière 2, vérifiée contre l’avis »

La barrière 1, parse(), est déjà dans recalls/checks.py. Dans Valider le sens, la barrière 2 utilisait la politique et les commandes de Larkfield. Ici, il existe une seule source de vérité : l’avis lui-même. Chaque valeur doit être visible dans l’avis, et les dates doivent être cohérentes.

Code de problème Vérification Problème détecté
wrong_notice Le numéro de rappel correspond au numéro de l’avis une réponse sur un autre avis
date_in_future La date du rappel n’est pas après aujourd’hui une année inventée
date_not_in_notice La date du rappel, écrite comme « April 2, 2026 » (2 avril 2026), se trouve dans l’avis un jour incorrect
dates_out_of_order sold_from n’est pas après sold_to des dates inversées
sold_after_recall sold_to n’est pas après le mois du rappel une fin de vente inventée
units_not_positive Le nombre d’unités, s’il est fourni, est supérieur à 0 un nombre négatif ou nul
units_not_in_notice Le nombre est écrit dans l’avis (5600, 5,600 ou « 1.7 million », soit 1,7 million) un nombre inventé ou obtenu par addition
quote_not_in_notice La citation du danger se trouve dans l’avis, mot pour mot une citation rédigée par le modèle
hazard_not_in_notice Chaque type de danger a son mot dans la ligne Hazard (danger) ou le titre (« drown », se noyer, pour la noyade) un danger que l’avis ne nomme pas
retailer_not_in_notice Chaque magasin est nommé sous Sold at (lieux de vente) un magasin inventé
phone_not_in_notice, email_not_in_notice Le téléphone et le courriel figurent dans les coordonnées pour les consommateurs des coordonnées inventées

Les vérifications comparent le texte après de petits changements : minuscules, un espace entre les mots, guillemets droits. checks.py contient déjà ces fonctions utilitaires (_flat, _long_date, _month, _units_forms) et les listes de mots dans HAZARD_WORDS. « Aujourd’hui » est fixé au 8 octobre 2026, le jour du téléchargement. Les résultats ne changent donc pas avec le calendrier.

  1. Dans recalls/checks.py, remplacez la fonction check_rules par celle-ci :

    recalls/checks.py
    def check_rules(record: RecallRecord, notice: Notice, today: date) -> list[Problem]:
    """Gate 2: valid JSON can still be wrong. Check it against the notice and the calendar."""
    problems = []
    text = _flat(notice.text)
    hazard_text = _flat(section(notice.text, "Hazard") + " " + section(notice.text, "Title"))
    sold_at = _flat(section(notice.text, "Sold at"))
    contact = _flat(section(notice.text, "Consumer contact"))
    if record.recall_number != notice.number:
    problems.append(Problem("wrong_notice", f"Recall number {record.recall_number} is not {notice.number}."))
    recalled = date.fromisoformat(record.recall_date)
    if recalled > today:
    problems.append(Problem("date_in_future", f"The recall date {recalled} is after today ({today})."))
    if _flat(_long_date(recalled)) not in text:
    problems.append(Problem("date_not_in_notice", f"The notice does not give {_long_date(recalled)}."))
    if record.sold_from and record.sold_to and _month(record.sold_from) > _month(record.sold_to):
    problems.append(Problem("dates_out_of_order", f"Sold from {record.sold_from} is after {record.sold_to}."))
    if record.sold_to and _month(record.sold_to) > (recalled.year, recalled.month):
    problems.append(Problem("sold_after_recall", f"Sold to {record.sold_to} is after the recall date."))
    if record.units is not None:
    if record.units <= 0:
    problems.append(Problem("units_not_positive", f"Units must be a positive number, not {record.units}."))
    elif not any(_flat(form) in text for form in _units_forms(record.units)):
    problems.append(Problem("units_not_in_notice",
    f"{record.units:,} units is not written in the notice: a person checks the sum."))
    if _flat(record.hazard_quote) not in text:
    problems.append(Problem("quote_not_in_notice", "The hazard quote is not in the notice word for word."))
    for hazard in record.hazards:
    if not re.search(HAZARD_WORDS[hazard], hazard_text, re.IGNORECASE):
    problems.append(Problem("hazard_not_in_notice", f"The notice's hazard text does not mention {hazard}."))
    for name in record.retailers:
    if _flat(name) not in sold_at:
    problems.append(Problem("retailer_not_in_notice", f"{name!r} is not named under Sold at."))
    if record.contact_phone and _flat(record.contact_phone) not in contact:
    problems.append(Problem("phone_not_in_notice", f"{record.contact_phone} is not in the consumer contact."))
    if record.contact_email and _flat(record.contact_email) not in contact:
    problems.append(Problem("email_not_in_notice", f"{record.contact_email} is not in the consumer contact."))
    return problems
  2. Exécutez les tests de la barrière 2 :

    Fenêtre de terminal
    python -m pytest tests/test_checks.py

    La dernière ligne indique 5 passed (5 réussites). Un test donne à l’avis 26406 une fiche avec six valeurs incorrectes et attend six codes de problème. Un autre donne à l’avis 26382 la somme des unités américaines et canadiennes (6 116) et attend units_not_in_notice.

  3. Extrayez l’avis Thermos :

    Fenêtre de terminal
    python -m recalls extract 26444

    La fiche contient "units": 8100000, et les dernières lignes sont :

    units_not_in_notice: 8,100,000 units is not written in the notice: a person checks the sum.
    flagged | chat-small | schema | 1944 tokens in, 355 out (162 reasoning) | 3.63 s | US$0.00037

La fiche Thermos est correcte : 5,8 millions et 2,3 millions font 8,1 millions. La barrière 2 la signale quand même, car la somme n’est écrite nulle part. C’est le rôle d’un signalement. Il ne dit pas « incorrect ». Il dit « une personne doit d’abord examiner cette valeur ». Vérifier qu’une valeur apparaît dans le texte ne permet pas de vérifier un calcul. La vérification confie donc le calcul à une personne.

Un enregistrement peut être partiellement correct : neuf champs corrects et un champ erroné. Le score compare donc chacun des 10 champs à la référence. Deux champs de texte libre ne sont pas notés : le nom du produit, qu’une personne lit de toute façon, et la citation du danger, que la barrière 2 vérifie.

Certaines valeurs doivent prendre une forme comparable avant la comparaison. « Walmart » et « Walmart.com » désignent le même magasin pour l’équipe de Grace. Deux listes contenant les mêmes éléments dans un ordre différent sont égales. Un numéro de téléphone se résume à ses chiffres.

  1. Dans recalls/score.py, remplacez les trois fonctions retailer_key, normalise et compare par celles-ci :

    recalls/score.py
    def retailer_key(name: str) -> str:
    """'www.Walmart.com' and 'Walmart' are the same shop for the safety team: 'walmart'."""
    name = name.lower().strip()
    name = re.sub(r"^www\.", "", name)
    name = re.sub(r"\.com$", "", name)
    return re.sub(r"[^a-z0-9]", "", name)
    def normalise(field: str, value):
    """Put a value in the form we compare: sets for lists, digits for phones, lower case for emails."""
    if value is None:
    return None
    if field in ("hazards", "remedies"):
    return frozenset(value)
    if field == "retailers":
    return frozenset(retailer_key(v) for v in value)
    if field == "contact_phone":
    return re.sub(r"\D", "", value)
    if field == "contact_email":
    return value.lower()
    return value
    def compare(record: RecallRecord | None, reference: dict) -> dict[str, bool]:
    """True for each field that matches the reference."""
    if record is None:
    return {f: False for f in FIELDS}
    data = record.model_dump()
    return {f: normalise(f, data[f]) == normalise(f, reference[f]) for f in FIELDS}
  2. Ajoutez import re sous import json au début du fichier.

  3. Exécutez tous les tests :

    Fenêtre de terminal
    python -m pytest

    La dernière ligne indique 32 passed (32 tests réussis).

Un avis sans enregistrement reçoit un score de 0 pour chaque champ. Un enregistrement signalé est quand même noté. Les signalements sont comptés séparément : un signalement n’est pas une mauvaise réponse.

Avant d’utiliser un modèle, demandez-vous ce que du code simple peut faire. Les avis ont des lignes étiquetées. recalls/baseline.py les lit donc avec des motifs : la date avec strptime, le premier nombre de la ligne Units (unités), les options de la ligne Remedy (mesure corrective), le premier téléphone et le premier courriel, puis des mots-clés pour le danger et la catégorie.

Fenêtre de terminal
python -m recalls eval --baseline

La sortie :

baseline (no model) | 40 notices
gate 1 (schema): 40 passed
gate 2 (business checks): 0 flagged
category 33/40
hazards 36/40
units 39/40
remedies 39/40
recall_date 40/40
sold_from 40/40
sold_to 40/40
retailers 31/40
contact_phone 40/40
contact_email 39/40
fields right: 377/400 (94.2%) | notices with every field right: 21/40

94,2 % ne coûte rien, et les dates et le téléphone sont parfaits : utilisez du code simple pour les champs déjà structurés. La référence de base échoue là où il faut lire : la catégorie, les dangers et les magasins.

Les motifs de la référence de base ont été écrits en lisant ces mêmes 40 avis. Le score de 94,2 % l’avantage donc. Exécutez python -m recalls errors --baseline pour voir ses 23 champs erronés. Chacun a franchi les deux barrières. En voici deux :

26423 contact_email got "LR023784@outlook.comor" | reference "LR023784@outlook.com" | passed both gates
26444 units got 5800000 | reference 8100000 | passed both gates

L’avis indique 5,8 millions. La barrière 2 ne peut donc pas s’y opposer, mais ce n’est que la première partie de la somme. Le courriel incorrect figure aussi dans l’avis, erreur de frappe comprise. La barrière 2 vérifie qu’une valeur vient de l’avis. Elle ne peut pas vérifier que la valeur est complète, ni que c’est la bonne.

Trois modèles ont répondu aux 40 avis, chacun avec le schéma et avec la requête (prompt) simple. Il s’agit de gpt-6-luna (chat-small) et de gpt-6.1-sol (chat-strong) sur Azure, et de TermeGemma 3 4BUn petit modèle ouvert de Google, avec 4 milliards de paramètres. Il peut fonctionner sur un portable avec Ollama, sans compte ni coût par appel.En savoir plus Modèle hébergé ou autohébergéLes LLM : comment ils fonctionnent et comment en choisir un avec TermeOllamaUn programme gratuit qui télécharge des modèles ouverts et les fait fonctionner sur votre ordinateur. Votre code l’appelle à une adresse locale, comme une API hébergée.En savoir plus Modèle hébergé ou autohébergéLes LLM : comment ils fonctionnent et comment en choisir un 0.40.1 sur un Mac mini. Les requêtes sont identiques, sauf pour le modèle et le schéma. Le simulateur rejoue chaque réponse.

Fenêtre de terminal
python -m recalls eval
python -m recalls eval --model chat-strong
python -m recalls eval --model gemma3:4b

La sortie de la première commande :

chat-small | schema | 40 notices
gate 1 (schema): 40 passed
gate 2 (business checks): 1 flagged {'units_not_in_notice': 1}
category 40/40
hazards 39/40
units 40/40
remedies 40/40
recall_date 40/40
sold_from 40/40
sold_to 40/40
retailers 38/40
contact_phone 40/40
contact_email 40/40
fields right: 397/400 (99.2%) | notices with every field right: 37/40
median tokens in / out: 1796 / 270 | latency median 2.40 s, p95 3.46 s
cost per 1,000 notices: US$0.33 (prices in usage.py)

Exécutez les autres commandes, puis chacune de nouveau avec --plain. Résultats regroupés :

Approche Barrière 1 franchie Signalement à la barrière 2 Champs corrects (sur 400) Tous les champs corrects (sur 40) Jetons entrants / sortants (médiane) Secondes (médiane / p95) $ US par 1 000 avis
Code simple (référence de base) 40 0 377 (94,2 %) 21 aucun aucune 0
Gemma 3 4B, requête simple 0 0 0 0 1 301 / 250 9,04 / 11,44 0 (local)
Gemma 3 4B, schéma 9 6 77 (19,2 %) 1 1 303 / 251 8,87 / 12,13 0 (local)
chat-small, requête simple 40 1 397 (99,2 %) 37 1 214 / 285 2,71 / 3,90 0,28
chat-small, schéma 40 1 397 (99,2 %) 37 1 796 / 270 2,40 / 3,46 0,33
chat-strong, requête simple 40 1 398 (99,5 %) 38 1 214 / 184 2,72 / 4,14 4,45
chat-strong, schéma 40 1 398 (99,5 %) 38 1 796 / 151 2,76 / 4,35 5,34
Champs qui correspondent à la référence vérifiée à la main : 40 avis × 10 champs, modèles avec le schéma (la référence de base n'en a pas besoin). Un avis sans enregistrement reçoit un score de 0 pour chaque champ.
Description textuelle du graphique

Un graphique à quatre colonnes. Code (la référence de base en code simple) : 377 sur 400. Gemma (Gemma 3 4B avec le schéma) : 77. gpt-6-luna (chat-small) : 397. gpt-6.1-sol (Termechat-strongLe nom que le code de Larkfield donne à un modèle hébergé plus grand : gpt-6.1-sol sur Azure. Il est souvent plus exact que chat-small et coûte environ 14 à 18 fois plus par appel.En savoir plus Les éléments d'une requêteCréer des applications fiables avec les API de LLM) : 398. Les deux modèles hébergés sont près du sommet. Le petit modèle local est loin sous le code simple.

Ce que dit le tableau, du plus important au moins important :

  • Les modèles hébergés atteignent la cible. chat-small a 397 champs corrects sur 400 (99,2 %), et chat-strong, 398. Un champ sur 40 avis ne prouve pas une différence : voyez Quelle certitude peut-on avoir avec 24 billets? dans le cours sur les modèles de langage.
  • chat-strong coûte environ 16 fois plus cher. Pour environ 600 avis par année, cela représente environ 3,30 $ US contre 0,20 $ US par année. Ces deux montants sont faibles comparés au temps de la personne qui vérifie. Mais rien ne justifie de payer 16 fois plus.
  • Pour les modèles hébergés, le schéma n’a changé aucun champ. Chaque réponse simple était du JSON valide, sans ajout. Le schéma ajoute 582 jetons d’entrée par avis : environ 0,05 $ US de plus par 1 000 avis avec chat-small.
  • Pour le petit modèle local, le schéma a tout changé. Sans lui, les 40 réponses étaient entourées de délimiteurs de bloc de code TermeMarkdownUne façon de noter la mise en forme en texte simple, par exemple **gras** ou # pour un titre. Les modèles l’ajoutent souvent : un programme qui attend du JSON simple doit l’enlever ou refuser la réponse. (trois accents graves et le mot json). json.loads a donc échoué. Avec lui, chaque réponse était du JSON. Mais 30 ne respectaient toujours pas le schéma, et une requête a échoué sur le serveur (HTTP 500, « token repeat limit reached », soit « limite de répétition de jetons atteinte »).
  • Le code simple dépasse largement le petit modèle, mais il compte 20 champs corrects de moins que les modèles hébergés.

Ce que le schéma a bloqué et ce qu’il a laissé passer

Section intitulée « Ce que le schéma a bloqué et ce qu’il a laissé passer »

Regardez la réponse de Gemma à l’avis Thermos, avec le schéma :

Fenêtre de terminal
python -m recalls extract 26444 --model gemma3:4b

La sortie :

The answer starts with:
{
"recall_number": "26444",
"product_name": "Thermos Stainless King 3000 and 3020 Food Jars and Thermos Sportsman 3010 Food & Beverage Bottles",
"category": "home_appliance",
schema: sold_from: String should match pattern '^\d{4}-\d{2}$'; sold_to: String should match pattern '^\d{4}-\d{2}$'
rejected | gemma3:4b | schema | 1457 tokens in, 317 out (0 reasoning) | 12.13 s | US$0.00000

L’enregistrement de la réponse montre le reste. Gemma a écrit "sold_from": "2008-03-01" et "sold_to": "2024-12-31" : des jours, alors que le schéma demande des mois. Ollama a envoyé le schéma au modèle, mais n’a pas fait respecter pattern (motif). Le cours l’a montré dans Définir un schéma. La barrière 1 dans notre code l’a fait respecter et a bloqué l’enregistrement.

Cette erreur de format cachait des erreurs factuelles. La fin de la vente est décembre 2024, un mois que l’avis ne mentionne jamais. Le nombre d’unités est 8 200 000, tiré du titre. Les dangers comprennent fall (chute) et tip_over (basculement), que l’avis ne mentionne jamais. Avec des mois au bon format, la barrière 2 signalerait les deux dangers. Elle accepterait le nombre d’unités, car le titre indique bien « 8.2 Million » (8,2 millions). Elle accepterait aussi la catégorie home_appliance (appareil électroménager) pour un contenant alimentaire.

Listez maintenant chaque champ erroné qui a passé la validation du schéma :

Fenêtre de terminal
python -m recalls errors
python -m recalls errors --model chat-strong
python -m recalls errors --model gemma3:4b

Pour les modèles hébergés, les listes sont courtes. Chacun de ces enregistrements a franchi les deux barrières :

Modèle Avis Champ L’enregistrement La référence
chat-small 26485 retailers « Costco retail stores », « Costco.com » « Costco », « Costco.com »
chat-small, chat-strong 26537 retailers « HSN.com », « HSN televised shows », « HSN digital shopping platforms » « HSN.com », « HSN »
chat-small, chat-strong 26582 hazards fire, burn, other burn, other

Ces trois cas sont à la limite de ce que les règles permettent. L’avis 26582 concerne un détecteur de fumée et de monoxyde de carbone. Il indique que l’appareil « peut ne pas avertir les consommateurs d’un incendie, ce qui pose un risque de blessure grave ou de décès par inhalation de fumée ou brûlures ». La règle liste les dangers que l’avis « nomme comme risques » : l’inhalation de fumée et les brûlures. Les quatre exécutions hébergées ont ajouté l’incendie, et une personne attentive pourrait être d’accord. Quand deux personnes attentives ne sont pas d’accord, la règle a besoin d’une phrase de plus.

Les 9 enregistrements de Gemma ont 13 champs erronés. Ce sont des erreurs d’un autre type :

Avis Champ L’enregistrement La référence Barrières
26512 sold_to 2025-12 2025-10 les deux franchies
26423 hazards electric_shock, other electric_shock les deux franchies
26377, 26445, 26504, 26532 sold_to 2026-12 2026-02 à 2026-05 signalé : sold_after_recall (vente après le rappel)
26394, 26537 hazards fire ajouté à burn (26394), chemical ajouté à fire (26537) burn; fire signalé : hazard_not_in_notice (danger absent de l’avis)
26445, 26504, 26532, 26537 hazards, category, retailers chemical ajouté (26445), other ajouté (26504, 26532), home_appliance pour un appareil de chauffage (26532), « HSN televised shows » (26537) les valeurs des règles dans un enregistrement signalé, mais ce champ n’est pas signalé

L’avis 26512 indique « jusqu’en octobre 2025 », et l’enregistrement indique décembre. La valeur est inventée, mais son format et sa plage sont valides. Elle a franchi les deux barrières. Quatre autres valeurs « décembre » inventées ont été détectées seulement parce qu’elles étaient après la date du rappel. La valeur chemical (produit chimique) de Gemma pour l’avis sur le kérosène n’a pas été signalée. Le nom de l’entreprise, Alliance Chemical, figure dans le titre. Les vérifications de mots sont un filet de sécurité, pas un juge, comme dans Valider le sens.

Erreur courante

Le schéma l'a accepté, donc c'est correct

Symptôme : Tomás regarde l’exécution de Gemma avec le schéma. « Toutes les réponses reçues sont du JSON avec les bons types. Mettons les 9 qui ont passé directement sur la liste de sécurité. » Parmi ces 9 enregistrements, 6 ont un signalement. Deux des 3 autres ont un champ erroné. L’un ajoute un type de danger absent de l’avis. L’autre termine la vente deux mois trop tard.

Cause : le schéma vérifie la forme de chaque valeur : un mois est YYYY-MM, un danger est l’un de 15 mots. Il ne peut pas savoir si l’avis indique octobre ou décembre. La TermeSortie structuréeUne requête qui envoie au fournisseur le schéma de la réponse, pour que le modèle ne puisse écrire qu’une réponse de cette forme. Elle contrôle la forme, pas la vérité : l’application vérifie toujours chaque réponse.En savoir plus Définir un schémaCréer des applications fiables avec les API de LLM stricte rend même plus probable une valeur présentée avec assurance dans la bonne forme, vraie ou non.

Solution : gardez les deux barrières et traitez un enregistrement qui les franchit comme un brouillon, pas comme un fait. Une personne lit chaque enregistrement à côté de son avis, en commençant par les valeurs signalées. Mesurez les résultats sur un jeu de référence pour savoir à quelle fréquence les brouillons sont erronés. Dans Valider le sens, la même erreur était un identifiant de commande inventé. Ici, c’est un mois inventé.

L’équipe choisit chat-small avec le schéma, les deux barrières et une personne qui approuve chaque enregistrement :

Un avis de rappel passe à l'extraction, où le modèle remplit l'enregistrement. La barrière 1, celle de la forme, vérifie que la réponse est du JSON complet qui respecte le schéma. Sinon, il n'y a pas d'enregistrement. Un code comme malformed_json, schema ou truncated indique le problème, et la personne lit l'avis. La barrière 2 vérifie que chaque valeur figure dans l'avis et que les dates sont dans l'ordre. Sinon, l'enregistrement est signalé avec un code comme units_not_in_notice, et la personne vérifie d'abord le signalement. Les enregistrements qui franchissent les barrières vont aussi à la personne. Seul un enregistrement qu'elle approuve rejoint la liste de sécurité, avec son lien vers l'avis.
Chaque parcours se termine par une personne. Les barrières décident seulement de ce qu'elle examine en premier.
  • chat-small, parce que chat-strong n’était pas meilleur de façon mesurable sur 40 avis et coûte 16 fois plus.
  • Le schéma, même s’il n’a pas aidé chat-small ici. Pour environ 0,05 $ US par 1 000 avis, il garantit la forme si l’équipe change ensuite de fournisseur, de modèle ou de requête.
  • Les deux barrières. La barrière 1 a bloqué 30 des 40 réponses de Gemma avec le schéma, et les 40 sans lui. La barrière 2 a signalé des mois inventés et une somme qu’une personne doit vérifier.
  • Une personne, parce que des enregistrements ayant franchi les deux barrières contenaient encore des champs erronés, avec chaque modèle.

L’avis 26773 date de septembre 2026. Il ne faisait pas partie de l’échantillon et n’a aucun enregistrement de référence. Cette exécution ressemble donc au vrai travail de la semaine prochaine.

Fenêtre de terminal
python -m recalls extract 26773

La sortie :

{
"recall_number": "26773",
"product_name": "Charbroil Bistro Pro Electric Grills",
"category": "outdoor_living",
"hazards": [
"electric_shock"
],
"hazard_quote": "The grounding wire for the grill's heating element can disconnect and lose fault protection, posing an electric shock hazard.",
"units": 10605,
"remedies": [
"repair",
"other"
],
"recall_date": "2026-09-17",
"sold_from": "2025-10",
"sold_to": "2026-06",
"retailers": [
"Ace Hardware",
"Lowe's",
"Walmart",
"Wayfair",
"QVC",
"Amazon.com",
"Charbroil.com",
"Ace Hardware.com",
"Lowes.com",
"Walmart.com",
"Wayfair.com",
"QVC.com"
],
"contact_phone": "866-671-7988",
"contact_email": "recall@charbroil.com"
}
valid | chat-small | schema | 2066 tokens in, 324 out (139 reasoning) | 2.79 s | US$0.00037

Grace vérifie l’enregistrement à côté de l’avis. Le nombre d’unités exclut les 342 vendues au Canada, comme le demande la règle. other (autre) correspond à la carte-cadeau de 25 $ US que Char-Broil offre après la réparation. Puis une personne responsable des achats cherche « Bistro Pro » dans le catalogue de Larkfield. Si Larkfield le vend, l’équipe lit l’avis de Santé Canada avant de répondre à un client.

  • Mesurez avant de choisir un modèle. Le code simple a atteint 94,2 % gratuitement. Les modèles hébergés ont ajouté 20 champs corrects, là où il faut lire et choisir.
  • Le schéma garantit la forme, pas la vérité. Il n’a rien changé pour les modèles hébergés. Les enregistrements du modèle local contenaient encore des erreurs.
  • « La valeur figure-t-elle dans le texte? » est une vérification peu coûteuse et partielle. Elle a détecté des mois inventés, mais pas une somme incomplète, un courriel incorrect ni une mauvaise catégorie.
  • La référence vient d’une seule personne, et l’échantillon est facile. Sections étiquetées, textes presque identiques, une source, un trimestre. D’autres avis ont besoin de leur propre référence.
  • Les modèles et les API changent vite. Ces nombres donnent un portrait ponctuel. La méthode reste : règles écrites, référence vérifiée à la main, deux barrières, scores par champ et une personne à la fin.
  1. Une vérification des mois. Le mois inventé « 2025-12 » de Gemma pour l’avis 26512 a franchi les deux barrières. Ajoutez une vérification, sold_month_not_in_notice (mois de vente absent de l’avis) : le mois et l’année de sold_from et de sold_to (par exemple « October 2025 », soit octobre 2025) doivent figurer dans la ligne Sold at (vendu chez). Exécutez python -m recalls eval --model gemma3:4b avant et après. Combien d’enregistrements supplémentaires de Gemma sont signalés? Un enregistrement hébergé reçoit-il un faux signalement? Pensez aux avis qui donnent seulement une année.
  2. Précisez une règle. Ajoutez une phrase à la règle des dangers pour trancher le cas de l’avis 26582. Décidez ce que la référence doit indiquer. Expliquez ensuite pourquoi les réponses enregistrées ne peuvent pas mesurer la nouvelle règle. Indice : la clé qu’utilise le simulateur pour trouver une réponse enregistrée comprend la requête.
  3. Facultatif, en direct et gratuit : un modèle local. Installez Ollama, exécutez ollama pull gemma3:4b, copiez .env.example vers .env, puis définissez RECALLS_PROVIDER=openai_compatible et RECALLS_BASE_URL=http://localhost:11434/v1. Exécutez ensuite python -m recalls extract 26382 --model gemma3:4b. Votre réponse peut différer de la réponse enregistrée. Un avis prenait environ 9 secondes sur le Mac mini utilisé pour l’enregistrement. Une exécution réelle de eval sur 40 avis prend donc plusieurs minutes. Remettez RECALLS_PROVIDER=mock quand vous avez terminé.
Afficher un exemple de réponse à la tâche 1
recalls/checks.py (in check_rules, before return problems)
for label, value in (("sold_from", record.sold_from), ("sold_to", record.sold_to)):
if value:
year, month = _month(value)
words = _flat(f"{date(year, month, 1):%B} {year}")
if words not in sold_at and _flat(f"{date(year, month, 1):%B} of {year}") not in sold_at:
problems.append(Problem("sold_month_not_in_notice", f"{label} {value} is not in the Sold at line."))

La deuxième forme (« January of 2026 », soit janvier 2026) figure dans l’avis 26406. Avec les réponses enregistrées, les enregistrements signalés de Gemma passent de 6 à 7 : 26512 est maintenant signalé. Les exécutions hébergées et la référence de base ne reçoivent aucun nouveau signalement. Un avis qui donne seulement une année recevrait un faux signalement. Une personne le vérifierait ensuite, ce qui est sûr. Cette vérification a été écrite après l’examen des erreurs. Testez-la donc sur de nouveaux avis avant de vous y fier.

Cette étude de cas peut compter pour votre certificat. Pour la publier :

  1. Créez un dépôt Git à partir du dossier de votre projet et poussez-le vers GitHub. .gitignore exclut l’environnement virtuel et .env.
  2. Gardez LICENSE (MIT, pour le code) et DATASET.md (la source, la licence et l’échantillon).
  3. Assurez-vous que python -m pytest réussit à partir d’un nouveau clone.
  4. Écrivez le README pour une personne qui ne connaît pas le projet. Un modèle de README :
README.md (outline)
# recall-extractor
## What it is
Extraction of 13 fields from US CPSC recall notices into checked records,
for a shop's safety team. Drafts only: a person approves every record.
## Results (40 hand-checked notices, 400 fields, recorded 2026-10-08)
- Plain code 94.2%, gpt-6-luna 99.2% (US$0.33 per 1,000 notices),
gpt-6.1-sol 99.5% (US$5.34), Gemma 3 4B 19.2% (local).
- The errors that passed every check, and why.
## Design
- Pydantic schema with enums and null; strict structured output.
- Gate 2: every value must be visible in the notice; dates in order.
- Field-level scoring against a reference written before any model ran.
## Limits and responsible use
(easy sample, one reader, not official data, a person checks)

Comment le décrire en entrevue, en trois phrases : « J’ai créé un extracteur qui transforme les avis américains de rappel de produits en enregistrements vérifiés, avec un schéma strict et des vérifications par rapport au texte source. Sur 40 avis vérifiés à la main, le code simple avait 94 % des champs corrects, et un petit modèle hébergé, 99 %, pour 33 cents par 1 000 avis. J’ai aussi montré quelles valeurs erronées passaient encore toutes les vérifications, donc une personne approuve chaque enregistrement. »

Allez plus loin :

  • Unités canadiennes. Ajoutez units_canada pour Larkfield, avec sa propre règle et ses valeurs de référence.
  • Une deuxième source. Extrayez les mêmes champs des avis de Santé Canada (Licence du gouvernement ouvert – Canada), avec leur propre référence.
  • Correspondance avec le catalogue. Faites correspondre product_name à un petit catalogue fictif et mesurez les fausses correspondances.

Vérifiez votre compréhension

Avec le schéma comme avec la requête simple, chat-small a correctement rempli 397 champs sur 400. Tomás dit : « Alors, retirons le schéma : il coûte 582 jetons par avis. » Que répondez-vous?

Afficher la réponse

Pour cet échantillon et ce modèle, le schéma n’a changé aucun champ. Il coûte environ 0,05 $ US de plus par 1 000 avis. Mais son rôle n’est pas d’améliorer l’exactitude. Il garantit la structure de chaque réponse, quels que soient le modèle, le fournisseur ou la version de la requête. Le modèle local a montré le risque : sans schéma, les 40 réponses étaient entourées de délimiteurs de bloc Markdown. Aucune ne pouvait être analysée. Le coût est faible, un changement de modèle est probable, et la barrière 1 dans notre code vérifie déjà la structure. Gardez donc le schéma et continuez à mesurer.

Vérifiez votre compréhension

La barrière 2 a signalé la fiche de chat-small pour l'avis Thermos (units_not_in_notice), mais la fiche est correcte. Cette vérification fonctionne-t-elle mal? Expliquez ce que signifie un signalement ici.

Afficher la réponse

Elle fonctionne bien. La vérification demande si le nombre figure dans l’avis. 8 100 000 est la bonne somme de 5,8 millions et de 2,3 millions. Mais ce nombre n’apparaît nulle part, donc la vérification ne peut pas le confirmer. Un signalement signifie « une personne doit d’abord examiner cette valeur », et non « cette valeur est fausse ». Pour cette raison, les signalements sont comptés séparément du score des champs. Le cas inverse est plus grave : les 5 800 000 de la référence de base figurent dans l’avis. Cette valeur a donc passé la vérification, même si elle ne représente qu’une partie des unités.

Vérifiez votre compréhension

Un collègue propose : « Le modèle hébergé a raison dans 99,2 % des cas. Publions donc les fiches sur notre site comme liste officielle des rappels pour faire gagner du temps à Grace. » Donnez deux raisons tirées de cette étude de cas de ne pas le faire.

Afficher la réponse

D’abord, 99,2 % signifie encore environ un champ erroné sur 130, et certaines valeurs erronées ont passé les deux barrières. Pour des renseignements de sécurité, une valeur erronée peut masquer un danger. Un client pourrait alors conclure qu’un produit est sûr. Ensuite, les fiches ne sont pas officielles. CPSC interdit les utilisations qui laissent entendre son approbation, et l’avis sur cpsc.gov est la source. De plus, le résultat de 99,2 % a été mesuré sur 40 avis faciles, avec des sections étiquetées. La référence venait d’une seule personne. Ce résultat ne garantit rien pour les avis du mois prochain. Une personne vérifie chaque fiche, et la liste relie chaque fiche à son avis.

Récapitulatif

  • L’extraction d’information transforme un texte en fiche aux champs fixes. Chaque champ exige un travail particulier : copier, changer le format, additionner, séparer ou choisir.
  • Des règles écrites assurent la cohérence entre la tâche, la référence et le score. Écrivez-les avant d’exécuter un modèle.
  • Un schéma garantit la structure. La barrière 2 vérifie les valeurs par rapport au texte source. Ni l’un ni l’autre ne prouve qu’une valeur est vraie.
  • Calculez le score champ par champ avec une référence vérifiée manuellement, et comptez séparément les échecs et les signalements.
  • Commencez par une référence de base : ici, du code simple a atteint 94,2 % et n’a fait aucune erreur sur les champs structurés.
  • Choisissez le modèle le moins cher qui atteint la cible. chat-strong n’était pas meilleur de façon mesurable et coûtait 16 fois plus.
  • Pour des renseignements de sécurité, une personne vérifie chaque fiche, et aucune fiche n’est présentée comme officielle.

La prochaine étude de cas répond à des questions sur des données ouvertes avec des outils en lecture seule. Elle vérifie que chaque nombre dans une réponse provient d’un résultat d’outil.

Leçon suivante : Répondre à des questions avec des outils sur des données ouvertes