Assistant documentaire et statistique

Relier une question, des chiffres et un territoire

Comprendre une question, retrouver ses preuves, calculer et situer les résultats sur une carte. Mobiliser de grands modèles de langage en limitant les données transmises à leur API.

Découvrir le projet
010203
  1. 01

    Définir

    Comment mesurer la rentabilité ?

  2. 02

    Mesurer

    Quel taux de marge pour chaque magasin ?

  3. 03

    Situer

    Où sont les cinq magasins retenus ?

Une question peut demander un document, un calcul et une carte

« Dans le département de l’Ain, quels sont les cinq magasins les plus rentables en 2025 ? Classe-les selon leur taux de marge d’exploitation et montre-les sur une carte. » Pour répondre, il faut retrouver la définition de cet indicateur, comparer les magasins sur la même année, puis les localiser. Mon objectif est de réunir ces étapes sans envoyer tous les fichiers au fournisseur du modèle.

Pourquoi un simple chatbot ne suffit-il pas ?

Un modèle de langage sait interpréter une formulation, mais sa connaissance générale ne contient ni nos fichiers ni leurs chiffres à jour. Le RAG lui apporte des passages documentaires : il recherche d’abord, puis rédige à partir des éléments trouvés. J’y ajoute des outils statistiques et géographiques pour traiter aussi les questions auxquelles un texte seul ne peut pas répondre.

123Le résultat nourrit la suite
  1. 01

    Interpréter

    Le modèle choisit un outil et ses paramètres.

  2. 02

    Exécuter

    L’application contrôle puis réalise l’opération.

  3. 03

    Observer

    Le résultat guide la prochaine action.

Le modèle comprend ; les outils recherchent et calculent

L’assistant travaille comme un analyste équipé d’outils. Le grand modèle choisit une action : consulter un dictionnaire, chercher une règle, interroger une table ou préparer une carte. Le serveur exécute cette action et lui renvoie un résultat borné. Il peut alors poursuivre l’analyse ou formuler la réponse.

Pourquoi séparer raisonnement et exécution ?

La souplesse du langage naturel vient du modèle ; les chiffres viennent des opérations réellement exécutées. FastAPI organise les échanges côté serveur et vérifie les appels d’outils. React présente les réponses, tableaux, sources et cartes. Cette séparation permet de changer le modèle utilisé sans lui confier directement le stockage des fichiers ni le rendu de l’interface.

010203
  1. 01

    Un champ décrit

    Type, définition et unité.

  2. 02

    Une opération autorisée

    Somme, moyenne, comptage… selon le sens.

  3. 03

    Une source repérable

    Document, passage et version de données.

Avant de calculer, savoir ce que chaque colonne représente

Dans notre exemple, le fichier contient le magasin, le département, l’année, le chiffre d’affaires, les charges d’exploitation et les coordonnées. Il faut savoir si les montants couvrent la même période et quelles charges sont incluses. À l’import, les colonnes sont décrites : type, définition, unité et agrégations autorisées. Les données publiées deviennent les ressources accessibles à l’agent.

Pourquoi un dictionnaire plutôt que des noms de colonnes seuls ?

Le dictionnaire évite que le modèle devine le sens d’une abréviation ou mélange deux indicateurs. Une version publiée fixe ce qui est disponible et comment l’utiliser. Les documents suivent une autre préparation : découpage en passages, conservation de la source et indexation. On prépare ainsi les tableaux pour calculer et les textes pour justifier.

010203
  1. 01

    Question

    Comparer les marges des magasins de l’Ain.

  2. 02

    Paramètres

    Département 01, année 2025, taux de marge, top 5.

  3. 03

    Contrôle

    Vérifier la requête avant le calcul.

Transformer « les plus rentables dans l’Ain » en requête

L’agent doit filtrer le département 01 et l’année 2025, calculer le taux de marge de chaque magasin, trier du plus élevé au plus faible, puis retenir cinq résultats. Si l’utilisateur dit seulement « les plus rentables », il faut préciser le critère : bénéfice en euros ou marge en pourcentage ? Ces deux classements peuvent être différents.

Pourquoi encadrer la liberté du modèle ?

L’agent peut proposer du SQL, mais le serveur en contrôle l’accès et l’exécution. Le projet possède aussi un chemin à plan typé : filtres, mesures et regroupements passent par une représentation intermédiaire, ou Query IR. Dans les deux cas, il faut distinguer une intention plausible d’une opération autorisée sur les bonnes colonnes.

010203
  1. 01

    Deux recherches

    Mots exacts et proximité de sens.

  2. 02

    Un classement commun

    Fusion des rangs et reclassement.

  3. 03

    Quelques preuves

    Extraits retenus avec leurs sources.

Retrouver une définition même si la question change de mots

L’utilisateur parle de « rentabilité », tandis que le guide décrit le « résultat d’exploitation » et le « taux de marge ». La recherche doit retrouver les bonnes définitions sans traiter ces termes comme des synonymes exacts. La recherche lexicale SQLite FTS5 trouve les mots et identifiants exacts. La recherche vectorielle encode les passages en coordonnées, appelées embeddings, et rapproche les formulations de sens voisin. Les embeddings et leur index ChromaDB sont exploités localement.

Pourquoi combiner deux recherches ?

Le lexical est utile pour une référence précise ; le vectoriel aide quand l’utilisateur reformule. La fusion RRF combine leurs classements à partir des rangs, sans supposer que leurs scores sont comparables. Un reclassement léger affine la sélection. Le modèle rédacteur reçoit ensuite un petit ensemble de passages pertinents, plutôt que le corpus entier.

Que signifie « rentable » dans ce classement ?

Pour cet exemple, le guide définit le résultat d’exploitation comme le chiffre d’affaires moins les charges d’exploitation. Le taux de marge rapporte ce résultat au chiffre d’affaires. La réponse cite cette définition et les règles sur les charges retenues : l’utilisateur comprend ainsi ce que le classement mesure, avant de lire les chiffres.

Pourquoi afficher la preuve à côté de la réponse ?

Une formulation fluide peut être convaincante même lorsqu’elle est fausse. Relier les affirmations aux passages retrouvés permet de vérifier leur origine et leur portée. Les références sont contrôlées, mais une citation existante ne suffit pas à garantir une bonne interprétation : l’évaluation vérifie aussi que le texte soutient la réponse et que le système sait s’abstenir.

Le plus gros chiffre d’affaires n’est pas la meilleure marge

Dans le tableau de l’exemple, le magasin de Bourg-en-Bresse réalise 1,2 M€ de chiffre d’affaires pour 960 000 € de charges : son résultat est de 240 000 €, soit une marge de 20 %. Celui de Gex réalise 2,5 M€ de chiffre d’affaires mais dégage 200 000 €, soit 8 %. DuckDB calcule ces valeurs côté application et classe les cinq magasins par taux de marge décroissant.

Pourquoi préciser le critère avant de désigner le meilleur magasin ?

Bourg-en-Bresse arrive en tête pour la marge : 20 centimes de résultat d’exploitation par euro de ventes. Oyonnax dégage pourtant davantage de résultat en euros : 340 000 €, contre 240 000 €. « Meilleur » dépend donc de la question posée. Le modèle explique la différence ; le calcul applique la définition choisie, sur une même année et un périmètre de charges comparable.

Les mêmes résultats prennent une position géographique

« Montre ces cinq magasins sur une carte. » Le serveur réutilise la sélection classée : Bourg-en-Bresse, Oyonnax, Ambérieu-en-Bugey, Belley et Gex dans notre exemple. Leaflet affiche leurs coordonnées ; un clic sur un point révèle le chiffre d’affaires, le résultat et le taux de marge du magasin.

Pourquoi une carte apporte-t-elle autre chose qu’un tableau ?

Le tableau classe les performances ; la carte révèle leur répartition dans le département. Elle permet de repérer des magasins proches ou éloignés, sans expliquer à elle seule la cause de leur marge. Le GeoJSON associe les coordonnées aux indicateurs. Un magasin sans coordonnées peut figurer dans le classement, mais ne doit pas être placé arbitrairement sur la carte.

« Parmi ces cinq magasins, garde ceux dont la marge atteint 15 % »

La demande conserve le département, l’année et les cinq magasins précédemment classés. Elle ajoute un seuil inclusif de 15 %. Bourg-en-Bresse (20 %), Oyonnax (17 %) et Ambérieu-en-Bugey (15 %) restent affichés. Belley (11 %) et Gex (8 %) sortent de cette sélection.

Pourquoi distinguer un filtre, un regroupement et une limite ?

« Parmi ces cinq magasins » demande de filtrer la sélection précédente. « Tous les magasins de l’Ain au-dessus de 15 % » demanderait de repartir du département entier, sans conserver le top 5. L’agent doit distinguer ces intentions pour ne pas afficher un sous-ensemble incomplet. Ici, la carte et l’export doivent contenir les trois mêmes magasins.

010203
  1. 01

    Dans l’application

    Fichiers, index, calculs et résultats complets.

  2. 02

    Vers le modèle

    Demande, définitions, extraits et aperçus bornés.

  3. 03

    Vers l’interface

    Tableaux, cartes et exports issus des résultats locaux.

Le fournisseur reçoit une sélection utile à la tâche

Les fichiers sources, les index et les résultats de travail sont conservés côté application. Pour agir, le modèle peut recevoir la question, du contexte de conversation, les définitions utiles des colonnes, des extraits de documents et un aperçu de résultats. Le code plafonne les aperçus à 40 lignes et 40 000 caractères, avec des budgets configurables plus bas.

Pourquoi garder un résultat local derrière un identifiant ?

L’agent peut demander une carte ou un export à partir d’un identifiant de résultat : l’application retrouve alors les lignes complètes. L’aperçu envoyé au modèle ne devient pas la limite des données affichées. Ce mécanisme réduit la circulation des données et le coût des échanges, tout en conservant assez d’information pour que le modèle choisisse la suite. Un aperçu peut toutefois contenir des valeurs : limiter le volume ne les anonymise pas.

123Le résultat nourrit la suite
  1. 01

    Contexte utile

    Ce qui a été demandé et sélectionné.

  2. 02

    Nouvelle intention

    Ce que la relance conserve ou remplace.

  3. 03

    Résultat actualisé

    Un calcul ou une carte sur la portée mise à jour.

Se souvenir de l’analyse sans renvoyer tous les fichiers

« Et dans le département du Rhône ? » n’a de sens qu’avec la question précédente. Le projet conserve l’historique applicatif et un état utile à l’analyse : portée géographique, opération et résultat précédent. Redis soutient les sessions et les caches, pour réutiliser le contexte entre les requêtes.

Pourquoi la continuité implique-t-elle un choix de conservation ?

La voie agent utilise une chaîne de réponses conservée chez le fournisseur pour poursuivre la conversation. Ses identifiants sont suivis localement, avec des mécanismes d’expiration et de suppression. Le rédacteur documentaire séparé utilise une demande sans stockage de réponse. L’architecture cherche donc à maîtriser ce qui circule et sa durée de vie ; elle ne correspond pas à un fonctionnement entièrement hors ligne.

Retrouver la bonne preuve

Hit@5 · part des questions dont un passage attendu figure parmi les 5 premiers résultats.

  1. Vectoriel seul76,4 %
  2. Hybride sans reclassement90,6 %
  3. Hybride + reclassement léger93,4 %
  4. Cross-encoder testé85,8 %

Comparaison locale sur 118 questions. Une bonne recherche est nécessaire ; la justesse de la réponse rédigée se vérifie séparément.

Une recherche plus complexe est-elle forcément meilleure ?

La campagne locale compare les méthodes sur 118 questions. Le bon passage est présent parmi les cinq premiers résultats dans 76,4 % des cas avec le vectoriel seul, 90,6 % avec l’hybride sans reclassement et 93,4 % avec un reclassement léger. Cette mesure, Hit@5, évalue la recherche : elle ne représente pas le taux de réponses finales correctes.

Pourquoi retenir le compromis plutôt que le plus gros dispositif ?

Le cross-encoder testé, qui relit ensemble la question et chaque passage, sélectionne un contexte plus précis mais retrouve moins souvent la bonne preuve : 85,8 % de Hit@5, avec une latence p95 proche de 1,96 s. Le profil équilibré garde aussi le rappel du profil plus coûteux avec 8 extraits au lieu de 12. Sur ce corpus, ajouter du calcul ou du contexte n’améliore donc pas tout : il faut mesurer recherche, rédaction, abstention et latence séparément.

010203
  1. 01

    Déployer

    Une configuration de services reproductible.

  2. 02

    Observer

    Latence, erreurs et comportement des outils.

  3. 03

    Vérifier

    Accès, sources, calculs et scénarios de conversation.

Une réponse utile doit aussi pouvoir être contrôlée

Après une démonstration réussie, il reste à gérer les accès, les versions de données, les erreurs et le temps de réponse. Le serveur contrôle les ressources accessibles et les requêtes. L’utilisateur peut consulter les sources, examiner les résultats et exporter son analyse pour la vérifier ou la poursuivre.

Pourquoi ces outils autour du modèle ?

Docker Compose rassemble les services dans une configuration reproductible. Prometheus collecte les mesures de fonctionnement ; Grafana les rend lisibles pour repérer une hausse de latence ou des erreurs. Les tests portent aussi sur les demandes ambiguës, les données absentes et les changements de zone. Ces briques rendent le comportement observable, au-delà de la qualité d’une réponse isolée.

010203
  1. 01

    Flexibilité

    Formuler, reformuler et combiner les analyses.

  2. 02

    Échanges limités

    Transmettre ce qui est utile, avec des budgets explicites.

  3. 03

    Intégrité

    Relier les réponses aux données, aux calculs et aux sources.

Un RAG déployable en entreprise, flexible et vérifiable

Le but est de proposer un assistant pour des données non sensibles, capable de passer d’une question libre à une explication sourcée, un calcul, une carte et un export. Les grands modèles apportent la souplesse de compréhension ; les outils et le stockage applicatif donnent une base concrète aux résultats.

Pourquoi associer flexibilité et intégrité ?

La flexibilité permet de formuler une nouvelle analyse sans créer un écran pour chaque besoin. L’intégrité consiste à préserver le sens des colonnes, le périmètre demandé et la traçabilité des résultats, tout en limitant les données transmises au fournisseur. Ce projet vise ce compromis pour un déploiement en entreprise : une capacité à expliquer et vérifier, à éprouver sur chaque corpus et chaque configuration.