Cet article est traduit ; la version anglaise originale fait foi.
Application de bureau2026-08-1440 min

Lawyer Assistant

Une application de bureau open source et hors ligne qui répond aux questions juridiques à partir de vos propres documents.

ElectronPythonBGE-M3ChromaDBRAGCUDA

Déploiement

100 % hors ligne

GPU

CUDA automatique

Licence

MIT · open source

Installation

Installeur en un clic

Pile technique

Frontend
Electron + React
Backend
Python · FastAPI
Embedder
BGE-M3
Base vectorielle
ChromaDB
Recherche
Hybride + reranker
Accélération
CUDA (auto)

Liens & dépôts

Captures d'écran

Lawyer Assistant
Lawyer Assistant répondant à une question de contrat avec sources citées
On interroge l'application sur les conditions de paiement d'un contrat de services — la réponse revient avec la clause exacte, la page et le passage surligné dans le panneau des sources.

Résumé

Lawyer Assistant est un système open source de génération augmentée par récupération (RAG), conçu pour fonctionner en local, dédié aux documents juridiques. Il combine un pipeline de récupération hybride — plongements denses BGE-M3, recherche lexicale BM25 et reclassement par encodeur croisé BGE-Reranker-v2-M3 — avec un routeur d'intention fondé sur un plan et un repli agentique avec intervention humaine, afin de répondre en langage naturel à des questions portant sur des contrats et des dossiers, avec des citations paginées. Un scanner de conformité au niveau des clauses classe les sections des documents et signale les clauses risquées selon des playbooks configurables. Le système est conçu pour fonctionner entièrement hors ligne : les modèles sont mis en cache localement, l'accélération GPU est provisionnée automatiquement à l'installation (sélection de PyTorch compatible CUDA avec remplacement forcé des builds inadaptés), et aucun document, plongement ou réponse ne quitte la machine de l'utilisateur, sauf si un mode API cloud optionnel est explicitement activé. Ce rapport documente l'architecture, la méthodologie de récupération, l'orchestration, l'ingénierie de déploiement et l'évaluation du système à la version v1.1.1 (août 2026).

Mots-clés : génération augmentée par récupération ; legaltech ; récupération hybride ; reclassement par encodeur croisé ; IA locale ; analyse de conformité ; compréhension documentaire


1. Introduction

Le travail juridique est un travail de documents. Contrats, mémoires, dépôts réglementaires et dossiers s'accumulent en volumes qui dépassent la revue manuelle, alors que les conséquences d'une clause manquée — ou d'une citation inventée — sont sévères. Les assistants IA généralistes offrent des réponses fluides mais ne peuvent pas être utilisés avec des documents confidentiels : ils exigent d'envoyer le corpus sur un serveur tiers, et ils sont connus pour halluciner la jurisprudence, un échec qui a déjà produit des pièces sanctionnées dans de vraies procédures (voir §2.3).

Lawyer Assistant répond aux deux problèmes avec une contrainte de conception unique : le système doit fonctionner entièrement sur la machine de l'utilisateur, sans dépendance cloud, tout en égalant la qualité de réponse des outils juridiques hébergés. Les contributions du projet sont :

  1. Un pipeline de récupération hybride (dense + lexical + reclassement par encodeur croisé) qui fonde les réponses sur les documents de l'utilisateur avec des citations précises (fichier, page, section) (§4).
  2. Un routeur d'intention fondé sur un plan, avec abstention explicite, garantissant que le modèle ne répond qu'à partir d'éléments récupérés (§5).
  3. Un scanner de conformité au niveau des clauses qui classe les sections contractuelles et signale les clauses risquées selon des playbooks à base de règles (§6).
  4. Un provisionnement GPU à l'installation qui sélectionne et remplace les builds PyTorch pour correspondre au matériel, rendant l'accélération locale fiable pour les utilisateurs non experts (§7).
  5. Un modèle d'isolation par espace de travail, chaque dossier projet possédant son propre index vectoriel, son index BM25 et son historique (§3.2).

2. Contexte et travaux connexes

2.1 Génération augmentée par récupération

La RAG [1] fonde les sorties du LLM sur un corpus externe en récupérant les passages pertinents et en conditionnant la génération sur eux. La récupération dense encode requêtes et documents dans un espace vectoriel partagé ; les modèles multilingues comme BGE-M3 [2] produisent des représentations denses, lexicales et multi-vecteurs, et sont conçus pour une récupération multilingue de haute qualité. Les systèmes hybrides combinent signaux denses et lexicaux (BM25) ; la fusion par classement réciproque (RRF) [3] est une méthode standard, à faible coût de paramétrage, pour fusionner des listes de résultats, et constitue l'une des stratégies de fusion supportées ici.

2.2 Reclassement par encodeur croisé

La récupération de premier étage (dense et lexicale) privilégie le rappel, en retournant un large ensemble de candidats (ici, top-50 de chaque). Le second étage applique un encodeur croisé — BGE-Reranker-v2-M3 [4] — qui encode conjointement la requête et chaque candidat et attribue un score de pertinence, améliorant la précision sur la liste finale (ici, top-5). Ce schéma en deux étages est le modèle dominant des systèmes RAG en production.

2.3 Le risque d'hallucination en IA juridique

Le coût de l'hallucination en IA juridique n'est pas hypothétique. Dans Mata v. Avianca, Inc. (S.D.N.Y. 2023), des avocats ont été sanctionnés pour avoir déposé un mémoire contenant des références jurisprudentielles fabriquées par un modèle génératif [5]. Les ordonnances de sanction ultérieures — dont Couvrette v. Wisnovsky (D. Or. 2025), qui a conduit à des amendes et honoraires dépassant 110 000 \$ pour deux avocats [6] — ont établi une trajectoire réglementaire claire : en 2026, la Cour suprême de Floride a adopté une règle traitant des citations hallucinées dans les actes de procédure [7], et l'opinion formelle 512 de l'American Bar Association traite du devoir de compétence des avocats utilisant l'IA générative [8]. Les systèmes qui inventent des sources créent donc une exposition directe à la responsabilité professionnelle. La réponse de Lawyer Assistant est architecturale : le modèle ne peut pas inventer de sources car la génération est conditionnée par des passages récupérés, chaque affirmation doit citer un fichier, une page et une section qui existent dans le corpus de l'utilisateur, et une étape de vérification de pertinence filtre les éléments récupérés avant génération (§5.4).

2.4 Référentiels de compréhension contractuelle

Des ensembles publics comme CUAD (Contract Understanding Atticus Dataset) [9] et leurs variantes d'évaluation dorée fournissent des ensembles de questions standard pour évaluer la compréhension au niveau des clauses ; le harnais de benchmark de Lawyer Assistant inclut les deux (§8.2).

3. Vue d'ensemble et architecture du système

3.1 Topologie des processus

L'application est une pile locale à trois processus orchestrée par un shell Electron :

ProcessusTechnologieRôle
ShellElectron (processus principal)Gestion de la fenêtre ; lance le backend et (en dev) le serveur Vite ; pont IPC
FrontendVite + React + TypeScriptInterface de chat, panneau des sources, scanner de conformité, éditeur visuel de pipeline ; stores Zustand
BackendPython + FastAPI (uvicorn, port 8765)Toute la récupération, l'orchestration, le scan et les points de terminaison streaming
L'inférence LLM locale est fournie par Ollama sur localhost:11434 ; plongements et reclassement utilisent des modèles mis en cache localement sous models/. Tout l'état persiste localement : historique de chat dans le localStorage du navigateur (Zustand), mise en page du pipeline dans localStorage['pipeline-layout-v1'], indicateurs de scan en SQLite backend, et état des threads agent dans data/conversations.db via AsyncSqliteSaver de LangGraph.

Le backend expose une surface API unique, le streaming étant implémenté uniformément en événements envoyés par le serveur (SSE) : jetons de chat, traces de raisonnement, appels d'outils, statut des nœuds, progression du scan et indicateurs sont diffusés vers l'interface, de sorte qu'aucune opération visible ne bloque sur une requête de longue durée.

3.2 Isolation par espace de travail

Un espace de travail est un dossier projet choisi par l'utilisateur. Avec un espace de travail actif, l'index vectoriel, l'index BM25, les fichiers traités et history.json vivent tous sous /workspace/, de sorte que les dossiers sont totalement isolés — la recherche dans un dossier ne peut jamais faire remonter des documents d'un autre. L'ingestion ignore les répertoires de stockage de l'espace de travail pour éviter l'auto-indexation.

3.3 Flux de données

L'ingestion (/api/workspace/ingest/stream, SSE avec progression) analyse chaque document supporté, le segmente, l'encode, le stocke dans l'index ChromaDB de l'espace de travail et met à jour l'index BM25. Au moment de la requête (/api/chat/stream), le message de l'utilisateur passe par le routeur d'intention, qui planifie, appelle le pipeline de récupération, vérifie la pertinence et diffuse une réponse citée. Un observateur de dossier en arrière-plan maintient l'index synchronisé avec les fichiers ajoutés à l'espace de travail.

4. Méthodologie de récupération

4.1 Ingestion : analyse et segmentation

Les documents sont analysés avec Docling, configuré pour l'OCR anglais à 150 DPI avec images de pages et extraction de la structure des tableaux. Le texte analysé est segmenté par un segmenteur sensible à la structure, avec une taille cible de 480 jetons (ChunkingConfig.chunk_size = 480), un minimum de 32 jetons, et respect_sections=True : les titres et les limites de sections sont préservés comme délimiteurs de segments plutôt que de couper au milieu d'une section. Chaque segment porte des métadonnées de provenance — fichier, page et section — ce qui permet la citation paginée en aval.

4.2 Plongements

Requêtes et segments sont encodés avec BGE-M3 (BAAI/bge-m3), produisant des vecteurs de 1024 dimensions, normalisés L2. BGE-M3 est un modèle multilingue : les textes sources non anglais restent donc interrogeables même si l'interface et les invites sont en anglais. Les modèles de plongement sont résolus depuis un cache local (models/bge-m3) avant toute recherche réseau, préservant le fonctionnement hors ligne après la configuration initiale.

4.3 Index vectoriel et lexical

Les vecteurs denses sont stockés dans ChromaDB (collection legal_chunks, distance cosinus, index HNSW) sous /workspace/chroma_db. En parallèle, un index BM25 (workspace/bm25_index) assure la récupération lexicale, essentielle pour les requêtes à expression exacte comme les citations statutaires et les termes définis que la récupération dense peut estomper.

4.4 Pipeline de requête

requête
 ├─ encodage (BGE-M3, 1024 dim, normalisé L2)
 ├─ recherche dense  — ChromaDB, top_k_retrieval = 50
 ├─ recherche lexicale — BM25, top 50
 ├─ fusion  — combine_and_dedup (défaut) | RRF (k=60) | boost_only
 ├─ reclassement  — encodeur croisé BGE-Reranker-v2-M3 → top_k_final = 5, score ≥ 0.0
 └─ réponse — {requête, résultats[{fichier, page, section, score, texte}], latence_ms}

Les deux récupérateurs de premier étage retournent les 50 meilleurs candidats ; les deux listes sont fusionnées (par défaut avec combine_and_dedup ; la fusion par classement réciproque avec k=60 et une stratégie de renforcement sont configurables), et la liste fusionnée est reclassée par l'encodeur croisé jusqu'à une liste finale de 5 avec un score minimum de 0.0. Tous les paramètres vivent dans des dataclasses typées (ModelConfig, ChunkingConfig, StorageConfig, SearchConfig, IngestionConfig) et peuvent être remplacés via des variables d'environnement PLR_* ou, à l'exécution, via l'éditeur visuel de pipeline (§7.4).

4.5 Modes de récupération

Trois modes de requête sont exposés : rag (défaut) exécute l'orchestration complète du routeur d'intention et répond à partir des documents ; retrieval_only retourne une liste formatée de résultats sans génération LLM ; direct génère à partir du LLM seul, sans récupération. Cette séparation est délibérée — elle rend la couche de récupération testable indépendamment et permet aux utilisateurs avancés de vérifier ce que le système a réellement trouvé.

5. Orchestration conversationnelle

5.1 Routage d'intention

Le chemin par défaut est un routeur d'intention fondé sur un plan. Le LLM reçoit une invite stricte (« vous NE DEVEZ PAS répondre directement ; choisissez un outil »), classe l'intention de l'utilisateur, rédige un plan d'une à deux phrases, et le routeur détecte l'outil à exécuter. Le chemin de recherche principal appelle search_documents avec la requête exacte de l'utilisateur (jamais reformulée), puis verify_relevance, puis rédige la réponse à partir des segments récupérés. Les événements diffusés (intent, plan, tool_call, tool_result, sources, token, done) donnent à l'interface une trace complète et transparente de ce que le modèle a fait.

5.2 Repli agentique avec intervention humaine

Un routeur agentique hérité — un agent ReAct LangGraph avec un StateGraph à trois nœuds (agent → approbation → outils) — sert les modes retrieval_only/direct et la reprise de conversation. Point crucial : le nœud d'approbation appelle interrupt() de LangGraph avant toute exécution d'outil ; l'interface présente une barre d'approbation, et /api/chat/resume diffuse la décision, reprenant au point d'interruption exact. Si l'utilisateur refuse, l'agent reçoit l'instruction de répondre sans outils. Cette barrière à intervention humaine fait la différence entre un assistant qui recommande des actions et un qui les exécute.

5.3 Ensemble d'outils

OutilRôle
search_documents(query, top_k=5, skip_rerank)Exécute le pipeline complet ; retourne les segments classés avec fichier/page/section/score
verify_relevance(query, documents)Contrôle LLM de correspondance entité/sujet ; retourne des indicateurs verified par document
scan_document(document_id, playbook)Exécute le scanner de conformité sur un document indexé ; persiste les indicateurs
ingest_file(path)Analyse → segmente → encode → stocke ; rend un fichier interrogeable et scannable

5.4 Garde-fous d'honnêteté

Trois mécanismes garantissent l'intégrité des réponses. La vérification de pertinence filtre les segments récupérés avant génération. L'abstention : le système est invité à dire qu'il ne sait pas lorsque les documents ne contiennent pas la réponse, et un signal d'abstention est testé séparément. La validation des citations : le frontend et le backend valident que chaque source citée correspond à un segment indexé, et des suites de tests dédiées couvrent la validation des citations et l'analyse des sources (§8.1). Ces mécanismes ciblent directement le mode de défaillance des autorités hallucinées documenté en §2.3.

6. Analyse de conformité

Le scanner de conformité traite la revue contractuelle comme une tâche de classification-et-règles en deux étapes plutôt que comme une synthèse libre :

document → segments (avec métadonnées page/section)
  → classification du type de clause par segment (classifieur à plongements sur références BGE-M3)
  → pour chaque règle du playbook actif : contrôle de règle (type de clause, sévérité, mots-clés/LLM)
  → émission des indicateurs → persistance en SQLite

Chaque playbook est un ensemble de règles liées à des types de clauses (responsabilité, résiliation, renouvellement, etc.), avec niveaux de sévérité et conditions par mots-clés ou LLM. Les indicateurs sont présentés dans une interface dédiée et prennent en charge un workflow de résolution (résolu / rejeté / escaladé). Les événements de scan diffusés (chunk_classified, rule_check, flag_found, scan_done) rendent les scans longs auditable en temps réel.

7. Ingénierie de déploiement

7.1 Premier lancement hors ligne

Un lanceur de première exécution pré-télécharge les modèles de mise en page/tableaux de Docling aux côtés de BGE-M3, pointe HUGGINGFACE_HUB_CACHE vers le répertoire local models/, désactive hf_xet/torch.compile et exécute un contrôle d'importation — afin qu'une installation neuve indexe réellement les PDF au lieu d'échouer silencieusement sur un modèle manquant ou un appel réseau.

7.2 Provisionnement PyTorch compatible CUDA

L'accélération GPU est la première source d'échecs d'installation de l'IA locale. La procédure d'installation : (1) sonde la machine et installe la roue PyTorch correspondant au matériel — CUDA 12.4 sur GPU NVIDIA, CPU sinon — avant d'installer le fichier d'exigences ; (2) sonde l'environnement résultant via torch.version.cuda ; (3) remplace de force un build préexistant incompatible (pip uninstall d'abord) afin qu'un torch CPU déjà installé ne puisse pas neutraliser silencieusement l'indexation GPU ; et (4) vérifie torch.cuda.is_available() et journalise le résultat.

7.3 Gestionnaire GPU

Un gestionnaire GPU d'exécution suit le périphérique, la VRAM libre/totale, le placement et la résidence par modèle, ainsi que les modèles Ollama résidents, avec des profils de résidence sélectionnables par l'utilisateur et persistés par projet. La mémoire GPU — ressource rare et disputée sur le matériel grand public — devient ainsi une allocation explicite et observable.

7.4 Éditeur visuel de pipeline

Un canevas ReactFlow expose le pipeline sous forme de nœuds éditables (intention, planificateur, dense, lexical, reclassement, ingestion, scan, réponse). La mise en page exportée n'est pas cosmétique : depuis /api/pipeline/config, elle reconfigure le backend Python à l'exécution — activation du reclassement, changement de mode de recherche, remplacement de top_k et des poids de fusion dense/lexicale via pipeline_config.py, lu par le pipeline de récupération à la construction.

7.5 Intégrité des mises à jour

Le programme d'installation écrit un manifeste de version dans la charge utile livrée ; au lancement, le lanceur le compare à la copie dans le répertoire d'état de l'utilisateur et recopie l'application lorsque la charge utile est plus récente, plutôt que de faire confiance à un marqueur « déjà copié » obsolète. Cela a clos la boucle de mise à jour dans laquelle une application installée pouvait continuer à exécuter du code obsolète après une mise à niveau (une classe d'échec qui avait livré le correctif de l'écran blanc à personne jusqu'à l'existence de ce mécanisme).

8. Évaluation

8.1 Suite de tests

La suite de tests du backend est organisée par phase système (démarrage, modèle de données, segmentation, plongements, stockage vectoriel, récupération, bout-en-bout, gestionnaire GPU, configuration de pipeline, espace de travail, validation des citations, analyse des sources, abstention/température, porte post-outil) et compte actuellement 255 tests réussis, dont 37 tests du gestionnaire GPU. La validation des citations, l'analyse des sources et l'abstention disposent chacune de suites dédiées, reflétant l'accent mis par le projet sur l'intégrité des réponses.

8.2 Benchmarks de récupération

Un harnais de benchmark (backend/benchmark/) mesure trois dimensions — qualité de récupération, performance des composants et précision de bout-en-bout — avec des métriques standard (Recall@K, MRR, Precision@K) sur un ensemble de 200 questions, un ensemble d'évaluation dorée et CUAD [9]. L'analyse des échecs catégorise et diagnostique les manques, et des benchmarks par composant couvrent la segmentation, le débit d'encodage, la vitesse-qualité du reclassement et la précision de la récupération.

8.3 Attributs qualitatifs

  • Confidentialité : la configuration par défaut n'effectue aucun appel réseau après la configuration initiale ; le mode API cloud est opt-in.
  • Explicabilité : chaque réponse affiche les sources fichier/page/section, et les traces SSE exposent le plan et l'utilisation d'outils du modèle.
  • Récupération multilingue : les représentations multilingues de BGE-M3 rendent les corpus non anglais interrogeables malgré une interface anglaise.

9. Discussion

Plusieurs décisions de conception méritent d'être soulignées. Un seul processus FastAPI possède à la fois le chat et le scan, les modèles étant préchauffés dans un thread d'arrière-plan au démarrage, ce qui rend la première requête rapide au prix d'un domaine de défaillance monoprocessus. Le SSE partout échange un peu de cérémonie protocolaire contre une expérience de streaming uniforme entre chat, ingestion et scan. La récupération hybride par défaut reflète l'observation que la recherche juridique est adversariale : les termes exacts et les citations statutaires comptent autant que la sémantique, et le BM25 seul ou le dense seul manque manifestement une classe de requêtes que l'autre attrape. Le routage agentique avec intervention humaine accepte un petit coût d'interaction en échange de l'élimination de l'exécution non autorisée d'outils. L'insistance du routeur d'intention sur la requête exacte de l'utilisateur (jamais reformulée) pour la récupération est une mesure délibérée anti-dérive : la reformulation par le modèle est une source connue de dégradation de la récupération.

10. Limites et travaux futurs

Les limites actuelles incluent : un OCR et des invites centrés sur l'anglais (la récupération est multilingue, mais la qualité d'analyse documentaire est la plus forte pour les textes anglais) ; une dépendance à un Ollama installé localement pour la génération (atténuée par le mode API cloud optionnel) ; un backend à stockage vectoriel unique (ChromaDB) sans partitionnement au moment de la requête pour de très grands corpus ; et des benchmarks internes au projet plutôt que publiés contre des classements externes. Les travaux futurs visent la référence croisée multi-espaces de travail, l'extraction structurée de clauses au-delà du simple signalement, des résultats de benchmark publiés et un meilleur support des documents non anglais.

11. Conclusion

Lawyer Assistant démontre qu'une IA juridique entièrement locale et respectueuse de la vie privée n'est pas un produit de compromis : un pipeline de récupération hybride dense/lexical/encodeur croisé, un routeur fondé sur un plan avec abstention et un scanner de conformité au niveau des clauses fournissent des réponses fondées et citables sans téléverser un seul document. Son provisionnement GPU à l'installation et ses mécanismes d'intégrité des mises à jour traitent les échecs opérationnels qui tuent généralement l'adoption de l'IA locale. Le projet est open source sous licence MIT, et son architecture — isolation des espaces de travail, interfaces orientées streaming, garde-fous de réponses honnêtes — est conçue comme une référence pour la legaltech locale.

Références

  1. Lewis, P., et al. Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks. NeurIPS 2020. https://arxiv.org/abs/2005.11401
  2. Chen, J., et al. BGE M3-Embedding: Multi-Lingual, Multi-Functionality, Multi-Granularity Text Embeddings Through Self-Knowledge Distillation. 2024. https://arxiv.org/abs/2402.03216
  3. Cormack, G., Clarke, C., Buettcher, S. Reciprocal Rank Fusion Outperforms Condorcet and Individual Rank Learning Methods. SIGIR 2009.
  4. BAAI. BGE Reranker v2.0. 2024. https://huggingface.co/BAAI/bge-reranker-v2-m3
  5. Mata v. Avianca, Inc., n° 22-cv-1461 (S.D.N.Y., 22 juin 2023) (ordonnance de sanction).
  6. Couvrette v. Wisnovsky, D. Or., 2025 WL 4109655 (12 déc. 2025) (ordonnance de sanction).
  7. Cour suprême de Floride, règle 2.515 (adoptée le 28 mai 2026 ; en vigueur le 15 juin 2026).
  8. American Bar Association, avis formel 512 (2024).
  9. Hendrycks, D., et al. CUAD: An Expert-Annotated NLP Dataset for Legal Contract Review. NeurIPS 2021. https://arxiv.org/abs/2103.06298
  10. GGUF Loader, GGUF Loader : runtime de modèles locaux open source et hors ligne. https://github.com/GGUFloader/gguf-loader
Next

Continue exploring