Projets
Data & IA

Extraction fiable de données juridiques par LLM

Pipeline qui fait lire des statuts et actes notariés en PDF par un LLM, produit un JSON contrôlé par schéma puis remplit un formulaire web, avec des garde-fous contre les hallucinations.

Par Sehenonirina Elisa Randriamasinoro, M1 Cybersécurité des Systèmes Embarqués, UBS Lorient

20267 stack
[LLM][AGENTS IA][CLAUDE CODE][PYTHON][PLAYWRIGHT][JSON SCHEMA][PDFTOTEXT]

Contexte

Des micro-tâches de saisie demandent de relire des documents juridiques de sociétés (statuts, actes notariés, procès-verbaux d'assemblée, cessions de parts) et d'en reporter le contenu dans un formulaire web : capital social, nombre de parts, liste des associés, état civil de chacun.

Le travail est répétitif, mais une seule erreur (un associé oublié, un prénom dans le mauvais ordre) fait refuser la tâche. C'était un bon terrain pour une question qui dépasse la saisie : comment rendre fiable la sortie d'un LLM quand l'erreur coûte cher ?


Architecture : le LLM lit, le code contrôle

Le principe est de séparer le jugement (lire un acte juridique) de l'exécution (remplir un formulaire), et de ne jamais laisser le LLM agir sans contrôle.

PDF de la tâche
    │  prepare.py : pdftotext + résumé compact (identité, actes, capital, répartition, état civil)
    ▼
LLM (Claude Code, terminal)
    │  lit le résumé, ouvre le texte complet aux endroits utiles, écrit un JSON
    ▼
validate.py ── contrat JSON Schema + cohérence (parts × nominal = capital)
    ▼
fill_repartition.py ── Playwright branché sur Chrome (CDP) remplit le formulaire
    ▼
verify.py ── relit le formulaire : sommes, champs obligatoires vides, SIREN ↔ dénomination
    ▼
submit.py ── soumission seulement si tout est OK, sinon arrêt et question à l'humain

Le pipeline a été conçu et itéré avec Claude Code : mon travail a porté sur l'architecture, les règles métier et surtout les contrôles.


Les garde-fous contre les hallucinations

Un LLM qui ne trouve pas une information a tendance à la « compléter » de façon plausible. Chaque garde-fou vise un mode d'échec précis :

RisqueGarde-fou
Un associé oubliéLa somme des parts doit tomber exactement sur le total, sinon blocage
Un montant inventé ou arrondiRègle écrite : ce qui n'est pas dans le document n'est pas saisi, il part dans une liste a_verifier
Une identité « plausible » mais fausseEn mode d'extraction automatique, chaque montant et chaque identité doit être justifié par une citation mot pour mot du document, dont le script vérifie l'existence
Un SIREN erroné recopié des statutsRésolution par API (Pappers, API gouv), puis affichage « SIREN - nom » pour détecter une société différente
Un cas ambiguLe pipeline s'arrête et pose la question au lieu de soumettre

Apprendre des refus

La plateforme refuse une saisie sans jamais donner le motif. Pour chaque refus, j'ai comparé le document d'origine avec ce qui avait été saisi, jusqu'à retrouver la cause.

Les refus se sont ramenés à trois causes : un associé oublié, une donnée inventée (reliquat réparti « également », arrondi), un état civil bâclé (nom d'usage à la place du nom de naissance, ville homonyme). Chacune est devenue soit un contrôle automatique, soit une règle écrite dans les instructions du LLM, consignée dans un fichier de leçons que l'agent n'ouvre qu'en cas de doute précis.


Économiser les tokens et le contexte

  • Le PDF est converti en texte, puis résumé en un seul digest : le LLM ne lit le texte complet qu'aux endroits utiles.
  • L'image d'une page n'est utilisée que pour les documents scannés, jamais en routine.
  • Les vérifications passent par des scripts qui relisent le formulaire, plutôt que par des captures d'écran analysées par le modèle.
  • Les instructions sont découpées : un chemin rapide chargé à chaque tâche, les cas particuliers seulement à la demande.

Comparer les modèles

J'ai testé une extraction entièrement automatique par un autre LLM (Gemini, plusieurs variantes « flash »), qui devait lui aussi citer ses sources.

  • Une variante allégée (« lite ») a rendu 0 part pour 4 associés sur 5 sur un même dossier, là où la variante standard trouvait tout. Le contrôle des sommes l'a attrapé, mais une erreur d'état civil serait passée : variante écartée.
  • Le quota gratuit (20 requêtes par jour et par modèle) a imposé une rotation entre modèles et un compteur local.
  • Un dossier traité de bout en bout par cette extraction a été refusé sans cause identifiable, alors qu'elle concordait ligne à ligne avec l'acte. Faute de pouvoir expliquer l'échec, elle a été désactivée au profit d'une extraction relue.

Limites

  • Les documents manuscrits ou mal scannés restent peu fiables : l'OCR est signalé comme incertain, rien n'est affirmé.
  • Le contrôle des sommes ne détecte pas une erreur d'état civil cohérente mais fausse : cette partie repose encore sur la relecture.
  • Traiter des données personnelles avec une API LLM externe doit être encadré (RGPD) avant tout usage réel.

Ce que ce projet m'a appris

Un LLM est un bon lecteur de documents, mais un mauvais juge de sa propre fiabilité. La valeur du pipeline n'est pas dans l'extraction elle-même, elle est dans tout ce qui l'entoure : un contrat de sortie strict, des contrôles indépendants du modèle, et le réflexe de transformer chaque erreur en règle ou en test.

C'est la même logique qu'en sécurité : on ne fait pas confiance à un composant, on vérifie ce qu'il produit.

Projets similaires

Tous les projets
Data & IASystèmes Embarqués

Triage automatique de haricots par CNN et ESP32-CAM

Classification binaire de haricots blancs (bonne/mauvaise graine) en temps réel, CNN Keras sur PC, ESP32-CAM pour la capture et le tri. Stage de fin d'études du DTS (niveau L2), Fablab Solidaire Mamiratra.

2023