learn.chetana.fr

Parser les documents : texte, tableaux, OCR

13 min readCore

Le router : une décision, un seul endroit

Premier node du pipeline, le router choisit la route d'extraction — et c'est le SEUL endroit du code qui connaisse cette logique :

source visuelle (PDF, image) + clĂ© Mistral configurĂ©e  → route VISION (OCR)
PDF sans clĂ© Mistral                                    → route TEXTE (pdfplumber)
image sans clĂ© Mistral                                  → ERREUR (fail loud, pas de page vide)
txt / csv / xlsx / eml / json                           → route TEXTE toujours

Le principe cardinal : deux routes, un contrat. Texte ou vision, la sortie est le mĂȘme StructuredOrder (le schĂ©ma partagĂ© validĂ© Pydantic) — tout l'aval (validator, matchers) ignore la provenance du document.

La route texte : aplatir proprement

  • PDF (pdfplumber) : par page, extract_text() + extract_tables() — les tableaux sont rendus en lignes cellule | cellule | cellule injectĂ©es dans le texte (le LLM lit trĂšs bien ce format) ET conservĂ©s en structurĂ©. Le tout en asyncio.to_thread (pdfplumber est sync et CPU-bound — module 1 !). Un PDF scannĂ© ressort vide de pdfplumber : c'est le signal qu'il fallait la route vision ;
  • Excel/CSV (pandas) : lecture par feuille, dropna(how="all"), bornĂ©e Ă  1000 lignes ; pour les CSV, une cascade d'essais encodage/sĂ©parateur (utf-8 avec ,/;/tab, puis latin-1, puis le sniffing automatique) — les CSV du monde rĂ©el sont un zoo, on tente du plus probable au plus permissif.

La route vision : le document natif au modĂšle

Pour les scans et images, le pipeline n'aplatit rien : le PDF/image part en base64 Ă  mistral-ocr-latest avec le schĂ©ma d'annotation dĂ©rivĂ© du mĂȘme StructuredOrder et le mĂȘme prompt systĂšme — document en entrĂ©e, JSON structurĂ© en sortie, en un seul appel. Le context_text de l'email accompagne le document ici aussi.

Ce choix (OCR structurant plutĂŽt qu'OCR texte puis LLM) supprime une Ă©tape entiĂšre de perte : les positions de tableaux, les colonnes alignĂ©es visuellement — tout ce que l'aplatissement texte dĂ©truit — restent exploitables par le modĂšle de vision.

Les limites d'entrée : connaßtre ses plafonds

Tout pipeline d'extraction a des plafonds, et les connaßtre évite les mystÚres de prod :

  • 1000 lignes lues maximum sur la route texte (la borne pandas) ;
  • ~200 lignes structurĂ©es en pratique : le budget de sortie LLM (16k tokens) est le vrai plafond — et au-delĂ , le document est rejetĂ© entiĂšrement (fail loud), pas tronquĂ© en silence : un rĂ©sultat partiel non signalĂ© serait pire qu'une erreur ;
  • la route vision (OCR) va plus loin — encore un argument pour elle sur les gros bons scannĂ©s.

La solution structurelle en chantier : le chunking avec contexte — dĂ©couper les grosses commandes en lots, en rĂ©-envoyant Ă  chaque lot le contexte nĂ©cessaire (en-tĂȘtes de tableaux, consignes). Et la sagesse d'expĂ©rience qui guide son design, hĂ©ritĂ©e d'un produit prĂ©cĂ©dent de l'Ă©quipe : la qualitĂ© d'extraction se dĂ©grade bien avant la limite technique (~100 lignes, le modĂšle « s'emmĂȘle ») — les chunks efficaces y Ă©taient de ~40 lignes. Leçon gĂ©nĂ©rale : le plafond de qualitĂ© d'un LLM arrive avant son plafond de tokens — dimensionne tes lots sur le premier, pas le second.

đŸ§© Quiz1/3

Que fait le pipeline d'une image de bon de commande si la clé Mistral n'est pas configurée ?

🃏 Flashcards1/5