Tous les articles
Petite entreprise 13 min de lecture

Quel contrôle rattrape vraiment une extraction fausse ? Quatre garde-fous, 288 extractions

Le contrôle arithmétique publié en août rattrape 59 % des erreurs et se déclenche sur 22 % des extractions justes. Nous avons posé quatre garde-fous différents sur les mêmes 288 extractions. Celui qui rattrape le plus est le pire à déployer, et l'accord entre modèles ne se déclenche jamais sur une facture propre.

Composition geometrique abstraite en deux tons, illustration de couverture
Publié le
04 septembre 2026
Rubrique
Petite entreprise

Un modèle lit une facture, rend du JSON propre, et se trompe sur un montant. Rien ne casse. Le test publié le 2026-08-13 a mesuré la fréquence de ces erreurs et laissé en suspens un chiffre que personne n'a repris : le contrôle arithmétique censé les rattraper se déclenchait aussi sur 25 % des extractions parfaitement justes.

Un contrôle qui crie au loup un quart du temps ne part pas en production. Nous avons donc repris les mêmes 288 extractions et posé dessus quatre garde-fous différents. Voici ce qui en sort, avant la méthode.

Le garde-fou qui rattrape le plus est le pire à déployer. Demander au modèle de vérifier son propre travail rattrape 41 des 42 extractions fausses, soit 97,6 %. Il signale aussi 39 % des justes. Sur mille factures, il faudrait en relire 476 à la main pour trouver 142 erreurs.

L'accord entre modèles rattrape presque autant et coûte un tiers de la lecture. Faire tourner trois modèles, signaler toute facture sur laquelle ils ne s'accordent pas tous : 92,9 % des erreurs rattrapées, 11 % de fausses alertes, 229 factures à relire pour mille au lieu de 476.

Sur les factures propres, l'accord entre modèles ne se déclenche jamais. Zéro fausse alerte aux niveaux de dégradation 1 et 2, sur 144 extractions justes. Le contrôle arithmétique se déclenche sur 25 % de ces mêmes factures. Cet écart est toute la trouvaille.

Quand l'auto-vérification signale une extraction juste, 30 % du temps elle réclame la valeur qui est déjà là. Pas une reformulation de cette affirmation, la chose littérale : subtotal should be 1581.38, but it is incorrectly extracted as 1581.38.

La méthode, en bref

Test conduit le 2026-09-04 par la chaîne de test automatisée de ce site : le corpus, les appels aux modèles et l'analyse sont des scripts, publiés plus bas pour que chacun puisse les rejouer et contester le résultat. Etienne signe cet article et répond de son contenu.

C'est le cinquième test mesuré publié ici, et le premier qui ne mesure pas un modèle. Il mesure les contrôles qu'on poserait autour d'un modèle.

Les 288 extractions n'ont pas été refaites. Ce sont exactement celles publiées le 2026-08-13 dans le jeu de données d'extraction de factures : 24 factures fournisseur générées par script, graine 20260810, quatre niveaux de dégradation du texte, trois modèles économiques. 42 de ces 288 extractions sont fausses, 246 sont justes, et le partage a été tranché à l'époque contre la vérité terrain générée.

Ce choix est délibéré et c'est lui qui donne un sens à la comparaison. Les quatre garde-fous jugent un jeu d'extractions identique. Refaire tourner les modèles aujourd'hui aurait mêlé l'effet des garde-fous à 25 jours de dérive des modèles, et aucun chiffre ci-dessous ne séparerait les deux.

Ce que cela coûte de le dire honnêtement : rien ici ne vous apprend si ces mêmes modèles commettent encore les mêmes erreurs aujourd'hui. Ce test porte sur les contrôles, pas sur les modèles. L'autre moitié de la question a été mesurée le 2026-09-06 : si un modèle haut de gamme commet moins d'erreurs, et à quel prix.

Les quatre garde-fous

Deux sont arithmétiques et ne coûtent rien. Un coûte un appel par facture. Un coûte des extractions supplémentaires.

python
def g1_arithmetique_bilaterale(r):
    # Le controle publie le 2026-08-13, repris tel quel comme temoin.
    return abs(r["total_due"] - (r["subtotal"] + r["tax"])) >= 0.011

def g2_arithmetique_unilaterale(r):
    # Ne signale que si on reclame PLUS que ce que l'arithmetique porte.
    # Un acompte deja verse fait legitimement baisser le total, jamais monter.
    return r["total_due"] - (r["subtotal"] + r["tax"]) >= 0.011

def g3_auto_verification(facture, r):
    # Un appel de plus, au MEME modele, avec la facture et sa propre sortie.
    # La consigne ne dit jamais qu'une erreur a ete trouvee.
    return not appeler(modele, CONSIGNE % (facture, r))["correct"]

def g4_accord_entre_modeles(r, autres):
    # Unanimite exigee sur les 7 champs. Un desaccord, on releve la facture.
    return any(r[c] != autre[c] for autre in autres for c in CHAMPS)

G2 est là à cause d'une hypothèse que nous avions avant de lancer quoi que ce soit : les 25 % de fausses alertes de G1 seraient du bruit d'arrondi, et un contrôle unilatéral les supprimerait. Cette hypothèse est fausse, et la section plus bas dit pourquoi.

Les chiffres bruts

288 extractions jugées, dont 42 fausses. Le taux de rattrapage est la part des 42 qu'un garde-fou signale. La fausse alerte est la part des 246 justes qu'il signale. Les deux nombres, toujours, parce que l'un ou l'autre pris seul peut être rendu parfait par un garde-fou inutile.

Garde-fou Rattrapage Fausses alertes Précision Erreurs manquées
G0 note spontanée du modèle 69,0 % 24,4 % 32,6 % 13
G1 arithmétique, deux sens 59,5 % 22,0 % 31,6 % 17
G2 arithmétique, un seul sens 0,0 % 0,0 % sans objet 42
G3 auto-vérification 97,6 % 39,0 % 29,9 % 1
G4 accord de trois modèles 92,9 % 11,0 % 59,1 % 3
G3 et G4 ensemble 97,6 % 41,1 % 28,9 % 1

Ce que chacun vous coûte en lecture

Le chiffre qui décide si un contrôle part en production n'est pas son taux de rattrapage. C'est le nombre de documents qu'une personne doit ouvrir.

Garde-fou Factures à relire pour 1000 Erreurs trouvées Erreurs manquées Lectures par erreur trouvée
G1 arithmétique, deux sens 274 87 59 3,2
G3 auto-vérification 476 142 3,5 3,3
G4 accord de trois modèles 229 135 10 1,7
G5 accord avec un seul modèle de plus 132 87 59 1,5

G4 trouve 135 des 146 erreurs contenues dans mille factures et envoie 229 factures à un humain. G3 en trouve 142, sept de plus, et en envoie 476. Sept erreurs de plus pour 247 documents de plus à lire n'est pas un échange que fait une équipe comptable.

Par niveau de dégradation, là où cela devient intéressant

Niveau Fausses G1 rattrapage / fausse alerte G3 rattrapage / fausse alerte G4 rattrapage / fausse alerte
N1 propre 0 sans objet / 25,0 % sans objet / 30,6 % sans objet / 0,0 %
N2 colonnes perdues 0 sans objet / 25,0 % sans objet / 37,5 % sans objet / 0,0 %
N3 totaux mélangés 21 47,6 % / 11,8 % 95,2 % / 47,1 % 85,7 % / 29,4 %
N4 libellés perdus 21 71,4 % / 23,5 % 100 % / 45,1 % 100 % / 23,5 %

Lisez les deux premières lignes. Il n'y a aucune erreur à rattraper aux niveaux 1 et 2 : les 144 extractions y sont toutes justes. Le contrôle arithmétique en signale 36. L'auto-vérification en signale 49. L'accord entre modèles n'en signale aucune.

Un flux de factures réel est fait surtout de documents propres. Sur ceux-là, G1 et G3 produisent du bruit pur et G4 produit du silence. C'est ce qui sépare un contrôle qu'on garde d'un contrôle que l'équipe désactive la deuxième semaine.

Pourquoi le contrôle arithmétique unilatéral ne rattrape rien

L'hypothèse était qu'un acompte légitime rend total_due plus petit que subtotal + tax, tandis qu'une erreur d'extraction pourrait aller dans les deux sens : ignorer le côté négatif supprimerait donc les fausses alertes en gardant les rattrapages.

Voici la direction de chaque écart arithmétique parmi les 288 extractions.

Écart négatif Exact Écart positif
Extractions fausses (42) 25 17 0
Extractions justes (246) 54 192 0

Pas un seul écart sur 288 n'est positif. Les erreurs rendent le total trop bas, ce que fait légitimement un acompte déjà versé. La direction de l'écart ne porte donc aucune information, et le contrôle unilatéral n'a rien sur quoi se déclencher : il rattrape 0 des 42.

Cela explique aussi les 25 % sur factures propres : ces 54 écarts négatifs sur des extractions justes ne sont pas des arrondis, ce sont des acomptes. L'identité arithmétique est simplement fausse pour ce type de facture, et aucune tolérance ne la répare. C'est le mauvais contrôle, pas un contrôle mal réglé.

L'auto-vérification se contredit elle-même

G3 a le meilleur taux de rattrapage du tableau, et c'est en lisant ce qu'il produit qu'on renonce à le déployer.

Quand un modèle signale une extraction, il rend aussi une chaîne problems. Sur les extractions justes qu'il a signalées, 40 de ces chaînes nomment un champ et une valeur. 12 de ces 40, exactement 30 %, réclament le nombre qui figure déjà dans l'extraction.

texte
extraction : subtotal 1581.38, tax 79.07, total_due 1660.45   (toutes justes)
verdict    : correct = false
motif      : subtotal should be 1581.38, but it is incorrectly
             extracted as 1581.38; tax should be 79.07, but it is
             incorrectly extracted as 79.07; total_due should be
             1660.45, but it is incorrectly extracted as 1660.45

C'est openai/gpt-4o-mini sur la facture F01, niveau 2, en train de vérifier sa propre sortie. Il a relu la facture, dérivé les bonnes valeurs, les a trouvées identiques à celles qu'on lui donnait, et a quand même rendu correct: false.

Un taux de rattrapage de 97,6 % bâti en partie là-dessus n'est pas de la détection. C'est un modèle qui penche vers le non quand on lui demande si quelque chose ne va pas, et qui a souvent raison parce qu'il y a des erreurs à trouver. Le chiffre de précision le dit sans détour : sur tout ce que G3 signale, 29,9 % est réellement faux.

Nous n'avons pas ajusté la consigne pour corriger cela. C'est la consigne simple qu'écrirait une PME, elle ne laisse jamais entendre qu'une erreur existe, et elle est publiée plus bas. La durcir mesurerait notre habileté à écrire des consignes, pas le garde-fou.

Un seul modèle de plus suffit, et c'est la ligne la moins chère du tableau

G4 exige trois modèles. La plupart des équipes en feront tourner deux. Nous avons donc mesuré chaque paire séparément : gardez votre modèle actuel, ajoutez-en un, signalez toute facture sur laquelle les deux divergent sur un champ.

Deuxième modèle Rattrapage Fausses alertes Précision Lectures par erreur
openai/gpt-4o-mini 59,5 % 5,3 % 65,8 % 1,5
google/gemini-2.5-flash-lite 47,6 % 2,8 % 74,1 % 1,4
anthropic/claude-haiku-4.5 26,2 % 7,3 % 37,9 % 2,6

Un deuxième avis de gpt-4o-mini rattrape autant d'erreurs que le contrôle arithmétique, 59,5 % contre 59,5 %, avec 5,3 % de fausses alertes au lieu de 22,0 %. Même rattrapage, un quart du bruit, pour le prix d'un appel économique de plus.

La troisième ligne est la ligne honnête. Ajouter claude-haiku-4.5 comme deuxième lecteur rattrape 26,2 %. La valeur d'un deuxième modèle dépend duquel, et ce test ne peut pas dire pourquoi. Ce qu'il peut dire, c'est que le choix compte davantage que l'idée.

Les coûts, mesurés et non estimés

Pour mille factures, aux prix facturés pendant ce test.

USD pour 1000 factures
Une extraction, moyenne des trois modèles 0,415
G0, G1, G2 0
G3 auto-vérification 0,300
G4, deux extractions de plus 0,830
G5, une extraction de plus 0,415

La passe d'auto-vérification, 288 appels, a coûté 0,086 USD au total. Aucun de ces garde-fous n'est cher. La ressource chère est la personne qui relit les factures signalées, et c'est pourquoi la colonne de lecture ci-dessus est celle qui décide.

Ce que nous ferions de cela

Ne pas contrôler l'arithmétique sur des factures qui peuvent porter un acompte. L'identité subtotal + tax = total_due est fausse pour toute une catégorie légitime de documents, et aucune tolérance ne la répare. Sur ce corpus elle coûte 36 fausses alertes sur 144 factures propres et achète 25 rattrapages sur 42.

Ajouter un deuxième modèle économique et comparer les champs. C'est le meilleur rapport de ce test : 1,5 document lu par erreur trouvée, 5,3 % de fausses alertes, un appel de plus. Commencer par là avant toute chose plus élaborée.

Ne pas demander à un modèle de noter sa propre sortie et agir sur son verdict. Lire les motifs d'abord. Sur ce corpus, 30 % des motifs donnés pour signaler une extraction juste demandent de remplacer une valeur par elle-même. Le verdict paraissait utilisable ; le raisonnement ne l'était pas.

Mesurer les deux nombres, toujours. N'importe lequel de ces garde-fous peut paraître excellent si l'on ne cite que son taux de rattrapage ou que son taux de fausse alerte. G2 affiche un parfait 0 % de fausses alertes et ne rattrape rien.

Les limites, dites franchement

Cette section n'est pas une formalité. C'est la condition pour que le reste soit lisible.

  • Les extractions ont 25 jours. Elles ont été produites le 2026-08-10. Rien ici ne dit que les mêmes modèles commettent les mêmes erreurs aujourd'hui, et ce test n'a pas été conçu pour le savoir.
  • 42 erreurs. Chaque taux de rattrapage ci-dessus est calculé sur 42 extractions fausses. Un pourcentage sur 42 éléments a une marge large. Ce sont des ordres de grandeur, pas des constantes.
  • Un corpus, 24 factures construites, graine fixe, déclaré comme construit dans son propre protocole. Aucune facture fournisseur réelle. Le piège de l'acompte qui met en défaut le contrôle arithmétique est une propriété voulue de ce corpus, et sa fréquence là-bas n'est pas sa fréquence dans votre comptabilité.
  • Trois modèles, un fournisseur, un jour. La passe d'auto-vérification est passée par OpenRouter le 2026-09-04.
  • G4 mesuré avec trois modèles n'est pas ce que feront tourner la plupart des équipes. C'est pourquoi le tableau par paire existe, et ses chiffres sont plus bas.
  • La consigne d'auto-vérification est une consigne. Une autre donnerait d'autres chiffres. Nous rapportons celle que nous avons lancée et nous la publions, plutôt que d'en chercher une variante flatteuse.
  • Rien ici ne mesure le coût d'une erreur manquée. Tous les arbitrages ci-dessus pèsent du temps de lecture contre des rattrapages. Une facture payée deux fois ne coûte pas la même chose qu'une facture lue deux fois, et ce rapport vous appartient, pas à nous.

Rejouez-le

Tout est publié, pas résumé : les 288 extractions jugées, le script d'auto-vérification, les 288 réponses brutes de vérification telles que les modèles les ont rendues, et l'analyse qui produit chacun des chiffres ci-dessus.

bash
python3 auto-verifier.py --extractions extractions.json --corpus corpus.json \
    --sortie verifications.json
python3 analyser.py --extractions extractions.json \
    --verifications verifications.json --sortie chiffres.json

L'analyse n'appelle aucun modèle : elle se rejoue à coût nul, et une règle de garde-fou que vous contestez peut être changée et relancée sur les mêmes 288 réponses. La clé d'API est lue dans une variable d'environnement et n'apparaît dans aucun de ces fichiers.

Télécharger le jeu de données (zip, avec l'inventaire complet et la somme de contrôle). Les scripts et les commentaires qu'ils portent sont en français, langue de travail derrière ce site.

Si vous rejouez ce test et obtenez autre chose, nous voulons le savoir. Il y a un formulaire de contact, et les corrections sont publiées sur l'article lui-même, datées, comme le disent les règles éditoriales de ce site.

Ces garde-fous contrôlent une lecture. Il en faut d'un autre genre dès que le modèle doit comparer la facture au bon de commande, et là un écart sur sept passe à chaque fois : celui que la consigne elle-même a appris au modèle à pardonner.

A lire dans la même rubrique

Recevoir le prochain article par e-mail

Un e-mail quand un article paraît. Pas d'outil de la semaine, pas de liste d'affiliation, aucune transmission de votre adresse à qui que ce soit.