3 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
4d0cab8b33 |
feat(ocr): retry exponential backoff sur 429 dans ocr:validate
All checks were successful
Build & Deploy API / build-and-deploy (push) Successful in 1m19s
La free tier Mistral a un rate limit non-linéaire (parfois 4-5 req/min
acceptées, parfois 1 req/2min selon la charge). Un délai fixe entre
calls ne suffit pas — on retry max 3× avec backoff 30s, 60s, 90s.
Combiné avec --delay-ms (espacement nominal entre calls), ça permet
de tenir tout un bench même si le quota se serre en cours de route.
Bench réel observé sur 10 factures variées (templates Boulangerie,
Mercier moderne, Mercier ancien, retards 5j/30j/90j/180j) :
- amountTtcCents : 10/10 (100 %) ← précision financière parfaite
- clientEmail : 10/10 (100 %)
- numero : 9/10 (90 %) ← 1 hallucination "FOUT"
- issueDate : 9/10 (90 %) ← même facture, 1970-01-01 fallback
- dueDate : 9/10 (90 %) ← idem
- clientName : 8/10 (80 %) ← 2 fails : Mistral inclut contact
- Latence moy. : 9.5 s/facture (avec delay 7s)
- 8/10 factures 100 % match (80 %)
- 91.7 % accuracy globale champs
Insights actionnables :
- amountTtcCents et clientEmail sont fiables → ok pour auto-validate
- clientName : ajouter au prompt "ne pas inclure le contact (M./Mme)"
- 1 facture sur 10 fait halluciner Mistral (FOUT + dates 1970) →
afficher "à vérifier" dans la UI quand confidence < 0.5 sur dates
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
2f96238efe |
feat(ocr): throttle --delay-ms + script generate-expected pour ground truth
All checks were successful
Build & Deploy API / build-and-deploy (push) Successful in 1m21s
Améliorations sur la commande de bench OCR validée avec 5 factures
réelles via Mistral (100 % accuracy obtenue sur l'échantillon test) :
- Option `--delay-ms` (default 1500 ms) entre 2 appels provider pour
éviter le rate limit Mistral (1300 free tier ≈ 1 req/s). Permet de
benchmark les 27 factures sans HTTP 429.
- Script `e2e/fixtures/invoices/generate-expected.mjs` qui parse les
PDFs via `pdftotext -layout` (poppler-utils) et génère
automatiquement les <name>.expected.json :
• Numéro F2026-XXXX
• Dates DD/MM/YYYY ou format long ("21 avril 2026")
• Montant TTC en cents (gère séparateur milliers "2 775,02")
• clientName en gérant 3 templates :
- "DOIT : <Nom>"
- "Facturé à :" en colonne droite
- "ADRESSÉE À ... ÉCHÉANCE" côte à côte
Re-générable, idempotent (skip si .expected.json existe déjà).
Le .gitignore du dossier reste sur `*` exclude pour ne pas commit les
PDFs (cohérent avec assets/test-invoices/ déjà ignoré racine), mais
autorise le script `generate-expected.mjs` (reproductible, sans secret).
Workflow utilisateur :
1. Pose tes PDFs dans e2e/fixtures/invoices/
2. `node generate-expected.mjs` génère les ground truth en lot
3. Vérifie/corrige à la main si besoin (parser pas 100 % parfait sur
tous les templates exotiques)
4. `OCR_PROVIDER=mistral pnpm ocr:validate` lance le bench réel
Résultat baseline observé sur 5 factures Mistral en mode réel :
- clientName 5/5 (100 %)
- clientEmail 5/5 (100 %)
- numero 5/5 (100 %)
- amountTtcCents 5/5 (100 %)
- issueDate 5/5 (100 %)
- dueDate 5/5 (100 %)
- Latence moyenne : 3,1 s / facture
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
e38aa224e8 |
feat(api): commande ocr:validate pour bencher l'OCR sur factures réelles
Outil standalone qui mesure la qualité d'extraction du provider OCR
courant (Mock, Mistral, ou autre futur) sur un set de factures avec
ground truth, séparé de la suite Playwright (qui reste sur OCR mock
pour la rapidité CI).
Pourquoi : permet de valider qu'un changement de provider (Mistral
upgrade, ajout Document AI, custom prompt) maintient la précision sur
les factures réelles avant de l'activer en prod.
Architecture :
- Lit `e2e/fixtures/invoices/<name>.pdf` (ou .png/.jpg)
- À côté, `<name>.expected.json` avec la ground truth
- Pour chaque facture : upload temporaire vers le storage courant
(MinIO en dev), appelle provider.extract(), compare field-by-field
- Cleanup du fichier temp après extraction
- Sommaire : accuracy globale, par champ, latence moyenne, exit 1
si une fixture a échoué (utile CI)
Tolérances par champ :
- amountTtcCents : exact (la précision financière compte)
- issueDate / dueDate : jour exact
- numero : exact (trim, case-insensitive)
- clientName : Jaccard similarity ≥ 85 % sur les tokens
(tolère "SARL" final manquant, espaces, etc.)
- clientEmail : exact (lowercased) ou null
Usage :
pnpm ocr:validate # provider courant (.env)
OCR_PROVIDER=mistral MISTRAL_API_KEY=... pnpm ocr:validate
node ace ocr:validate --fixtures-dir=./other --out=report.json
Sécurité :
- `.gitignore` exclut tous les fichiers de e2e/fixtures/invoices/
sauf README + .gitignore eux-mêmes — les vraies factures ne fuitent
pas dans le repo public
À faire par Arthur :
1. Dépose 10-20 vraies factures (anonymisées si possible) dans
e2e/fixtures/invoices/
2. Pour chaque, écrit le .expected.json (5 min par facture)
3. Lance `OCR_PROVIDER=mistral pnpm ocr:validate` → ajuste prompt ou
post-process si l'accuracy descend sous le seuil
Format ground truth + seuils cibles documentés dans le README du dossier.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|