Aller au contenu
Paul Azeufack

Tous les articles

Un assistant RAG qui préfère refuser plutôt qu'inventer

J'ai refait de zéro mon assistant RAG sur la loi camerounaise sur l'état civil. Recherche hybride, garde-fou sur les citations, réglages mesurés sur 21 questions, et des résultats sans maquillage.

Publié le
Durée
5 min de lecture
Tags
RAGÉvaluationPython

Un assistant juridique qui préfère refuser de répondre plutôt qu’inventer un article de loi : voilà ce que j’ai voulu construire.

J’ai refait de zéro mon assistant RAG sur la loi n° 2024/016 du 23 décembre 2024 portant organisation du système d’enregistrement des faits d’état civil au Cameroun. Le premier prototype fonctionnait, mais il était écrit au fil de l’eau et difficile à faire évoluer. Cette version est mieux structurée, testée et mesurée.

Le point de départ

Pour répondre à une question précise sur cette loi, un délai par exemple, il faut souvent suivre la réponse d’article en article : le délai normal, puis les délais supplémentaires, puis le jugement déclaratif. Je voulais un assistant qui réponde à partir du seul texte public de la loi, cite ses sources et refuse plutôt que d’inventer.

Ce que ça fait

Vous posez une question en français. L’assistant retrouve les articles pertinents, répond uniquement à partir d’eux et cite les articles utilisés, chacun avec un lien vers son texte exact et sa page dans le PDF officiel. Si la loi ne permet pas de répondre, il refuse.

Réponse de l'assistant à la question « Qu'est-ce que le NIPU ? », avec les articles 3 et 81 de la loi cités

Sur l’image : la réponse à « Qu’est-ce que le NIPU ? », avec les articles 3 et 81 cités.

C’est là que se fait la vérification : ci-dessous, l’article 81 ouvert depuis cette réponse, avec son chapitre, sa section et sa page dans le PDF officiel. Le lecteur peut ainsi contrôler la réponse dans le texte de la loi, sans faire confiance au modèle.

Page de l'article 81 de la loi n° 2024/016, ouverte depuis une citation de la réponse sur le NIPU : texte exact de l'article, chapitre et section, page 30 du PDF officiel

Comment c’est construit

Parcours d'une question dans l'assistantLa question passe par trois recherches, vectorielle, BM25 et lookup, fusionnées par RRF en 8 passages. Sous le seuil de similarité de 0,80, l'assistant refuse sans appeler le modèle. Sinon Gemini répond en citant des articles ; si les citations ne sont pas valides, il redemande une fois, puis refuse.

non

oui

oui

non, 1re fois

non, 2e fois

Question

Recherche vectorielle
embeddings en local

BM25
mots rares

Lookup
« article 36 » → article 36

Fusion des rangs RRF
8 passages

Similarité ≥ 0,80
ou article cité ?

Refus sans appel au modèle

Gemini : réponse
et numéros d'articles

Citations valides ?

Réponse et articles cités

Refus

  • Recherche hybride : le sens (embeddings multilingues exécutés en local), les mots rares (BM25) et la recherche directe par numéro d’article, fusionnés par RRF.
  • Un garde-fou sur les citations : l’application vérifie que la réponse cite au moins un article, et seulement des articles réellement fournis au modèle. Sinon, nouvelle tentative, puis refus.
  • Des composants remplaçables : Embedder, VectorIndex et LLMProvider sont des interfaces. Gemini est le seul fournisseur implémenté pour l’instant ; en ajouter un demande une classe et une ligne.

Des choix mesurés plutôt que devinés

J’ai écrit un jeu de 21 questions de référence, chacune avec une réponse tirée du texte de la loi : des questions directes, des questions en cascade où un délai se prolonge d’article en article, une formulation familière, des questions hors sujet ou hors de la loi, et une consigne cachée dans la question.

Deux réglages viennent de cette évaluation :

  • 8 passages donnés au modèle, au lieu de 5. Avec 5 passages, la question « dans quel délai déclarer une naissance ? » perd l’article 13, celui du jugement déclaratif au-delà de 12 mois.
  • Un seuil de refus à 0,80. La question légitime la plus éloignée du texte est à 0,852, la question hors sujet la plus proche à 0,793. Ce seuil ne refuse aucune question légitime du jeu ; il évite seulement d’appeler le modèle pour les questions manifestement hors sujet.

Les résultats, sans maquillage

Sur les 21 questions, avec gemini-3.5-flash-lite, le plus petit modèle de la gamme : 12 réponses correctes, 6 partielles, 2 à relire, 1 tolérée, aucun échec. Aucune réponse inventée.

Les trois questions hors sujet, dont la consigne cachée, sont refusées par le seuil, sans appel au modèle. La question sur l’âge du mariage, dont la réponse n’est pas dans la loi, passe le seuil mais le modèle la refuse.

Les 6 réponses partielles sont mon prochain chantier. Elles portent toutes sur des questions en cascade : le modèle donne la première partie de la réponse et oublie la suite, alors que l’information était dans les passages fournis. Le défaut vient du modèle, pas de la recherche.

Attention

La vérification porte sur les articles cités, pas sur chaque phrase : l’outil ne remplace pas un juriste.

Les limites, et la suite

Ces 21 questions donnent une tendance, pas une garantie. Un seul modèle a été testé, et les verdicts varient d’une exécution à l’autre, même à température 0. Je compte ajouter des questions pour mener une évaluation plus conséquente ; ce sera l’objet d’un prochain Article.

Le projet

Projet indépendant, construit uniquement à partir du texte public de la loi, sans aucune donnée ni code de mon cadre professionnel, même si l’inspiration me vient de mon poste actuel. Open source (MIT), à installer en local (le premier index prend de quelques minutes à une vingtaine de minutes) : tout est dans le dépôt GitHub. La page du Projet en donne le résumé.

Je travaille sur des projets backend et données pour des structures qui manipulent des données de terrain ou sensibles. Si le sujet vous parle, écrivez-moi.