Mémoire sourcée
RAG sourcé à la ligne, serveur MCP, injections mises en quarantaine

- précision / rappel d’abstention sur 90 questions de test gelées (0,81 / 0,45 avant)
- 0,95 / 0,79
- de rappel sur 40 questions sans réponse jamais vues, sans abstention à tort
- 0,83
- de latence p50 (1 012 ms avant), 6 ms en cache
- 618 ms
- pièges d’injection signalés, 16 / 30 injections paraphrasées
- 6/6
- Le problème
- Un assistant documentaire qui invente est pire qu’un assistant muet, et un document piégé ne doit jamais lui dicter sa conduite.
- Pour qui
- Un assistant compatible MCP (Claude Desktop ou autre) et une interface web, sur 190 documents découpés en 1 496 passages, hors ligne.
- Le résultat
- Sur 90 questions de test gelées : abstention précision / rappel de 0,81 / 0,45 à 0,95 / 0,79, rappel@3 de 0,76 à 0,81, latence p50 de 1 012 à 618 ms ; pièges signalés 6/6.
Contexte
Une douzaine de projets, 190 documents en français et en anglais qui évoluent chaque jour. Un assistant doit y répondre avec la source exacte, sans halluciner, et sans obéir à un document qui contiendrait des consignes cachées.
Ce que j’ai construit
- Découpage qui respecte la structure (titres, tableaux, blocs de code jamais coupés) et numéros de lignes exacts ; indexation incrémentale par empreinte SHA-256.
- Recherche hybride : BM25 et embeddings multilingues fusionnés (RRF), puis cross-encodeur qui reclasse ; abstention sur seuil gelé et règle d’ancrage.
- Scanner d’injection à l’ingestion, motifs et détection sémantique : chaque passage est fiable, suspect ou en quarantaine ; la quarantaine n’est jamais servie, seulement signalée. 16 injections paraphrasées sur 30 signalées (0 avec les motifs seuls), 0 faux positif en quarantaine sur 931 passages réels.
- Détecteur d’abstention appris et gelé : précision / rappel 0,95 / 0,79 sur 90 questions de test, abstentions à tort de 5 à 2.
- Trois accès : interface web, API et serveur MCP (recherche, passage exact, source, inventaire), avec une configuration Claude Desktop prête à coller.
- Protocole figé avant mesure : 90 questions de test (40 de la v2, 50 nouvelles dont 40 sans réponse), mesurées une seule fois ; l’ancienne version rejouée sur les mêmes questions ; 60 tests.
Architecture 7 briques
- 01 · EntréeIngestionDécoupage structuré, lignes exactes, empreintes SHA-256
- 02 · OutilScannerMotifs et sémantique : fiable, suspect ou quarantaine, par passage
- 03 · DonnéesIndex SQLitePassages, vecteurs, confiance
- 04 · OutilRappel hybrideBM25 et MiniLM multilingue, fusion RRF
- 05 · ModèleReclassementCross-encodeur mmarco sur 24 candidats
- 06 · OutilDécisionCiter la ligne, ou s’abstenir (détecteur gelé)
- 07 · SortieServiceInterface web, API, serveur MCP
Fabrication 5 étapes
- IngestionDécoupage structuré, scan d’injection.
- RappelBM25 et dense, fusion RRF.
- ReclassementCross-encodeur sur 24 candidats.
- DécisionCiter la ligne, ou s’abstenir.
- ServiceWeb, API, MCP.
Décisions le choix, la raison, l’alternative écartée
- D1Geler la répartition des questions et leurs empreintes avant toute mesure de la v2.
L’évaluateur refuse de mesurer si une question a changé : le chiffre de test n’est pas sur-ajusté.
ÉcartéAjuster les seuils en regardant le test.
- D2Rejouer l’ancienne version sur les mêmes questions de test.
Le gain se lit sur le même jeu, métrique par métrique, sans changer de référence.
- D3Traiter le contenu des documents comme une donnée non fiable dès l’ingestion.
Les passages en quarantaine ne sont jamais servis ; le texte rendu est échappé et précédé d’un avertissement « données, pas instructions ».
- D4CPU uniquement, vérifié au chargement.
Le service tourne à côté des travaux GPU sans les gêner ; environ 0,8 Go de mémoire résidente pour une session MCP.
Résultats
Détecteur v3 contre règle v2, même exécution de recherche (CPU)
| Mesure | Avant | Après |
|---|---|---|
| Abstention précision / rappel (90 questions) | 0,81 / 0,45 | 0,95 / 0,79 |
| Rappel d’abstention, 40 questions sans réponse inédites | 0,48 | 0,83 |
| Abstentions à tort | 5 | 2 |
| Rappel@3 (90 questions) | 0,76 | 0,81 |
| Rappel@3, 15 questions d’origine | 0,75 | 0,83 |
| Injections paraphrasées signalées | 0 / 30 | 16 / 30 |
| Faux positifs en quarantaine (931 passages réels) | 0 | 0 |
| Latence p50 (banc de 80 requêtes) | 1 012 ms | 618 ms (6 ms en cache) |
Seuils choisis uniquement sur le jeu de mise au point, puis gelés. Protocole strict : une abstention à tort est comptée comme une erreur.
Jeu de test gelé (40 questions, CPU) : v0 du 18/10 contre v2 du 20/10
| Mesure | v0 | v2 |
|---|---|---|
| Rappel@1 | 0,33 | 0,67 |
| Source dans le top 5 (sans abstention) | 0,44 | 0,93 |
| MRR | 0,36 | 0,70 |
| Pièges d’injection signalés | 0/6 | 6/6 |
| Passages en quarantaine servis | 0 | 0 |
Livrables 4
- Interface web (recherche, évaluation), API et serveur MCP stdio en lecture seule.
- Configuration Claude Desktop prête à coller.
- Protocole gelé (90 questions de test, dont 40 sans réponse jamais vues), résultats et analyse par question.
- 60 tests ; scanner : 0 faux positif en quarantaine sur 931 passages réels, 16 / 30 injections paraphrasées signalées.
Environnement
Matériel et conditions de mesure
- Tout tourne sur CPU, modèles en cache local, environ 0,8 Go de mémoire résidente par session MCP : le service cohabite avec les travaux GPU.
- Latence p50 de 618 ms avec reclassement sur CPU, 6 ms pour une requête en cache ; plus rapide sur GPU.
Reproduire commandes du README
Code privé : accès en lecture sous accord de confidentialité, ou démo en direct de 30 minutes. Demander l’accès →
.venv/bin/atelier index
.venv/bin/atelier search "Comment RELAIS revient-il en arrière ?" -k 3
.venv/bin/atelier eval verifier
.venv/bin/atelier eval tester
.venv/bin/atelier serve
.venv/bin/atelier mcp
.venv/bin/python -m pytest- Interface sur 127.0.0.1:8341 ; tout tourne sur CPU, modèles en cache local.
- Si le corpus change, les seuils se recalibrent sur le jeu de mise au point.
Galerie 3
Ce que ce projet change pour vous
Le même savoir-faire, sur votre sujet.
Une base de connaissances qui cite
Vos procédures et documents interrogeables par vos assistants, chaque réponse avec fichier et lignes, et une abstention plutôt qu’une invention.
Résister aux documents piégés
Un document qui contient des consignes cachées est mis de côté et signalé, jamais servi à l’assistant.
Mesurer avant de déployer
Un jeu de questions écrit avec vos équipes et gelé : vous connaissez l’effet de chaque version avant la mise en service.