Un jour, quelqu’un m’a posé cette question : “Comment créer un assistant qui ne mente jamais, qui ne fabule pas, qui reste fidèle aux documents qu’on lui confie ?”

La réponse tenait en trois lettres : RAG.

Retrieval-Augmented Generation. Un nom savant pour une idée simple : avant de répondre, cherche d’abord dans les archives.

C’est ainsi qu’est né Nico, un gardien des savoirs institutionnels. Pas un oracle qui devine, pas un poète qui improvise — juste un bibliothécaire augmenté, capable de fouiller une base documentaire et de restituer l’information avec précision.

Dans ce projet, je vous raconte comment j’ai construit cet assistant conversationnel en combinant la puissance de FAISS pour la recherche vectorielle, Gemini pour la génération de texte, et FastAPI pour l’exposition de l’API. Une architecture simple mais efficace, pensée pour répondre à un besoin concret : offrir un accès rapide et fiable à l’information institutionnelle.

Contexte et Objectif du Projet

Les institutions — qu’il s’agisse d’écoles, d’administrations ou d’entreprises — accumulent une masse considérable de documents : plaquettes de formation, règlements intérieurs, FAQ, maquettes pédagogiques, contacts administratifs…

Le problème ? Ces informations sont souvent dispersées, difficiles à retrouver, et surtout : inaccessibles 24/7.

L’objectif de ce projet était de créer un assistant virtuel capable de :

  • Répondre instantanément aux questions des visiteurs
  • Puiser ses réponses dans une base documentaire interne (pas d’invention, pas d’hallucination)
  • Rester factuel, professionnel, et toujours cohérent avec les sources officielles
  • Être accessible en permanence via une API REST simple

Nico n’est pas un ChatGPT institutionnel. C’est un outil de récupération et de restitution d’informations — un pont entre des documents statiques et une interface conversationnelle.

Pourquoi un RAG plutôt qu’un Simple Chatbot ?

On aurait pu utiliser directement un grand modèle de langage comme ChatGPT ou Gemini pour répondre aux questions. Mais cette approche pose plusieurs problèmes.

Les limites d’un LLM seul :

  • Hallucinations : le modèle peut inventer des informations plausibles mais fausses
  • Absence de contexte institutionnel : il ne connaît pas les spécificités de votre organisation
  • Réponses génériques : il va donner une réponse “probable”, pas une réponse basée sur vos documents officiels
  • Pas de traçabilité : impossible de savoir d’où vient l’information

L’approche RAG résout ces problèmes en trois temps :

  1. Retrieval (Récupération) : Avant de répondre, le système cherche les documents pertinents dans une base vectorielle
  2. Augmentation : Ces documents sont ajoutés au contexte de la requête
  3. Generation : Le LLM génère une réponse en s’appuyant uniquement sur ces documents

Résultat : des réponses fidèles aux sources, traçables, et factuelles.

Un LLM seul devine. Un système RAG cherche d’abord, puis restitue.

Le Grimoire des Données

Avant de construire un assistant qui répond, il faut d’abord nourrir sa mémoire.

Constitution du Corpus

Pour ce projet, j’ai collecté et préparé des documents institutionnels :

  • Extraction depuis les pages web officielles via web scraping
  • Documents PDF (plaquettes, règlements)
  • Fichiers texte structurés
  • FAQ existantes

La qualité du chatbot dépend entièrement de la qualité de ces documents sources. Garbage in, garbage out.

Segmentation : Découper pour Mieux Régner

Les documents bruts ne peuvent pas être directement exploités. Il faut les découper en morceaux digestes — ce qu’on appelle des “chunks” (segments).

J’ai utilisé le RecursiveCharacterTextSplitter de LangChain avec :

  • Taille de chunk : 500 caractères (équilibre entre précision et contexte)
  • Chevauchement : 50 caractères (pour éviter de couper des phrases importantes)

Pourquoi ce découpage ? Imaginez que vous cherchiez une information dans une encyclopédie. Vous ne lisez pas tout le livre — vous cherchez le paragraphe pertinent. C’est exactement ce que fait le système.

Vectorisation : Transformer le Sens en Nombres

Une fois les documents segmentés, chaque chunk est transformé en embedding — une représentation vectorielle qui capture son sens sémantique.

J’ai utilisé le modèle d’embeddings de Google (embedding-001) pour cette transformation. Chaque segment devient alors un point dans un espace multidimensionnel, où les segments sémantiquement proches sont géométriquement proches.

Indexation avec FAISS : La Bibliothèque Enchantée

FAISS (Facebook AI Similarity Search) est une bibliothèque optimisée pour la recherche de similarité vectorielle. C’est notre bibliothèque enchantée : on y stocke des milliers de segments, et elle nous retourne instantanément les plus pertinents pour une requête donnée.

Imaginez une bibliothèque infinie où chaque livre est classé non par titre, mais par sens. Quand vous posez une question, le bibliothécaire ne cherche pas mot à mot — il cherche par proximité sémantique.

Architecture du Système

L’architecture de Nico repose sur trois piliers complémentaires.

Le Retriever : FAISS comme Moteur de Recherche Sémantique

Quand un utilisateur pose une question, le système :

  1. Transforme la question en vecteur (embedding)
  2. Compare ce vecteur à tous les chunks stockés dans FAISS
  3. Retourne les 3 documents les plus proches sémantiquement (k=3)

Pourquoi 3 documents ? C’est un compromis. Avec un seul document, les réponses sont trop restreintes. Avec 10 documents, il y a trop de bruit et le modèle se perd. Trois documents offrent assez de contexte sans noyer l’information pertinente.

Le Generator : Gemini comme Conteur

Une fois les documents récupérés, il faut les transformer en une réponse naturelle et fluide. C’est le rôle du modèle de génération.

J’ai utilisé Gemini Flash pour ce projet. Pourquoi Flash ?

  • Rapide (faible latence)
  • Gratuit pour prototyper
  • Suffisant pour de la restitution factuelle

Note importante : Flash n’est pas le modèle le plus puissant. Pour des cas d’usage en production nécessitant plus de finesse, on peut utiliser Gemini Pro, Claude Sonnet, ou GPT-4. L’architecture RAG est agnostique au modèle — vous pouvez changer de LLM sans toucher au reste du système.

Le Pont : FastAPI pour l’Exposition

Pour rendre Nico accessible, j’ai construit une API REST avec FastAPI.

Pourquoi FastAPI ?

  • Simplicité : mise en place rapide avec peu de code
  • Documentation auto-générée : Swagger UI disponible instantanément
  • Typage moderne : validation des données avec Pydantic
  • Performances : basé sur Starlette et conçu pour être rapide

L’API expose un endpoint /chat qui accepte une question en JSON et retourne une réponse structurée. Rien de plus, rien de moins.

Le Prompt Engineering : L’Art de Guider le Modèle

Le prompt est la clé pour éviter les hallucinations. J’ai structuré le prompt avec des règles strictes :

  1. Identité claire : “Tu es Nico, assistant officiel de l’institution”
  2. Contrainte sur les sources : “Utilise UNIQUEMENT les documents fournis”
  3. Interdiction de redirection : “Ne redirige JAMAIS vers un site externe”
  4. Ton professionnel : “Adopte un ton institutionnel”
  5. Gestion de l’incertitude : “Si tu ne sais pas, dis-le simplement”

Ces règles transforment un LLM généraliste en assistant spécialisé. Sans elles, le modèle inventerait, extrapoleraient, comblerait les vides avec des probabilités. Avec elles, il reste dans son rôle.

Les Défis du Gardien des Savoirs

Construire Nico n’a pas été un long fleuve tranquille. Voici les principaux défis rencontrés et comment je les ai résolus.

Défi 1 : Les Hallucinations du Modèle

Problème : Le LLM a tendance à “remplir les blancs” quand il ne sait pas. Il invente des informations plausibles mais fausses.

Solution :

  • Prompt strict avec interdiction explicite d’inventer
  • Retour d’un message par défaut si aucun document pertinent n’est trouvé
  • Tests réguliers avec des questions pièges pour vérifier la fiabilité

“Si tu ne sais pas, dis ‘je ne sais pas’.” Simple, mais révolutionnaire pour un LLM.

Défi 2 : Le Formatage des Réponses

Problème : Le modèle générait des phrases génériques comme “Selon les documents que j’ai analysés…” ou “D’après mes recherches…”. Ces formulations brisaient l’immersion et rendaient les réponses moins naturelles.

Solution :

  • Ajout d’une règle dans le prompt : “Donne l’information directement, sans mentionner comment tu l’as obtenue”
  • Post-traitement pour nettoyer les réponses si nécessaire

Défi 3 : La Gestion du Contexte

Problème : Trouver le bon équilibre pour le nombre de documents à récupérer (k). Trop peu = réponses incomplètes. Trop = bruit et confusion.

Solution :

  • Réglage empirique à k=3 après plusieurs tests
  • Ce nombre peut être ajusté selon le cas d’usage et la longueur moyenne des chunks

Défi 4 : Les Limites de FAISS

Problème : FAISS est excellent pour la recherche, mais ne supporte pas facilement les mises à jour incrémentales. Ajouter un nouveau document nécessite de régénérer l’index complet.

Solution actuelle :

  • Régénération périodique de l’index quand de nouveaux documents sont ajoutés

Pistes d’amélioration :

  • Pour de très grandes bases nécessitant des mises à jour fréquentes, considérer des alternatives comme Pinecone, Weaviate, ou Chroma qui supportent mieux les mises à jour dynamiques

Déploiement avec Docker

Pour rendre le projet facilement déployable, j’ai créé une image Docker. L’objectif était simple : permettre à quiconque de lancer Nico en quelques commandes, sans se soucier des dépendances.

Avantages de la dockerisation :

  • Environnement isolé et reproductible
  • Déploiement simplifié sur n’importe quelle machine
  • Facilite la collaboration et l’intégration continue

L’image est disponible publiquement sur Docker Hub : roy61/chatbotdit-rag

Lancement en quelques secondes :

1
2
docker pull roy61/chatbotdit-rag
docker run -d -p 8000:8000 roy61/chatbotdit-rag

Une fois lancé, l’API est accessible via :

  • Interface Swagger : http://127.0.0.1:8000/docs
  • Endpoint chat : http://127.0.0.1:8000/chat

Retour d’Expérience et Transmission

Ce projet n’est pas resté dans mon ordinateur. J’ai eu l’immense plaisir de le partager lors d’une formation pratique organisée par JokkoTech Community, co-animée avec Serge Mendy, une personne que je respecte énormément pour son engagement dans la transmission des savoirs en IA.

Ce que les Apprenants ont Découvert

  • L’importance cruciale de la préparation des données (garbage in, garbage out)
  • La différence fondamentale entre un LLM seul et un système RAG
  • Les limites actuelles des modèles (hallucinations, biais, absence de raisonnement)
  • La puissance d’une API simple pour démocratiser l’accès à l’information

Questions Mémorables

“Pourquoi FAISS et pas une simple recherche par mots-clés ?”
Parce que la recherche sémantique capture le sens, pas juste les mots. Quelqu’un qui demande “Quelles formations en informatique ?” et quelqu’un qui demande “Quels cursus tech ?” posent la même question avec des mots différents. FAISS le comprend.

“Peut-on utiliser ce système pour des documents confidentiels ?”
Absolument. Tout reste en local si vous le souhaitez. Pas besoin d’envoyer vos données vers un cloud externe.

“Et si le modèle invente quand même ?”
C’est pour ça qu’on teste, qu’on itère sur le prompt, et qu’on garde toujours un œil humain. L’IA n’est pas autonome — elle est assistée.

Cette expérience m’a rappelé que la technique n’a de valeur que si elle est partagée. Un projet qui reste sur GitHub sans documentation ni transmission est un projet à moitié fini.

Impact et Utilité

Cas d’Usage Concrets

  • Support client automatisé 24/7 : répondre aux questions fréquentes sans intervention humaine
  • Aide à la navigation documentaire : orienter les visiteurs vers les bonnes informations
  • Réduction de la charge administrative : libérer du temps pour les tâches à forte valeur ajoutée
  • Accès rapide aux règlements et procédures : éviter les allers-retours par email

Limites Actuelles

  • Dépendant de la qualité des sources : si les documents sont incomplets ou obsolètes, les réponses le seront aussi
  • Pas de raisonnement complexe : Nico restitue, il ne raisonne pas
  • Mise à jour manuelle : ajouter de nouveaux documents nécessite de régénérer l’index

Pistes d’Amélioration

  • Ajouter un système de feedback utilisateur (pouce en haut/bas pour évaluer les réponses)
  • Intégrer des sources multiples (web scraping, API externes, bases de données)
  • Mettre en place un pipeline de mise à jour automatique des documents
  • Tester d’autres vector stores (Chroma, Pinecone, Weaviate) pour des mises à jour dynamiques
  • Expérimenter avec des modèles plus puissants (Gemini Pro, Claude Sonnet) pour améliorer la qualité des réponses

Visuels

Interface Swagger de Nico L’interface de documentation interactive générée automatiquement par FastAPI

Architecture RAG

Schéma de l’architecture : Retrieval → Augmentation → Generation

Ce que Nico M’a Appris

Nico n’est pas un oracle. Il ne comprend pas vraiment les questions qu’on lui pose. Il ne “pense” pas.

Mais il fait quelque chose de remarquable : il récupère l’information pertinente et la restitue de manière fluide, naturelle, presque humaine.

C’est la force du RAG — combiner la précision de la recherche documentaire avec la fluidité de la génération de texte.

Leçons Techniques

  • Les LLM seuls ne suffisent pas pour des cas d’usage factuels. Il faut leur donner un contexte.
  • La qualité des réponses dépend avant tout de la qualité des données. Un modèle brillant sur des données médiocres donnera des réponses médiocres.
  • Un bon prompt vaut mieux qu’un modèle plus puissant mal guidé. L’ingénierie du prompt est un art en soi.
  • La simplicité architecturale est souvent la meilleure approche. Pas besoin de sur-ingénierie pour résoudre un problème réel.

Leçons Humaines

  • Un chatbot ne remplace pas l’humain. Il le libère des tâches répétitives pour qu’il puisse se concentrer sur ce qui compte vraiment — penser, créer, transmettre.
  • La technologie n’a de sens que si elle sert un besoin réel. Construire pour construire ne sert à rien.
  • Partager ses connaissances multiplie leur valeur. Un projet qui reste dans un tiroir (ou sur GitHub sans documentation) est un projet perdu.

Si vous souhaitez explorer le code en détail, reproduire ce projet, ou l’adapter à votre contexte, tout est disponible sur GitHub : Chatbot RAG - Nico

N’hésitez pas à l’adapter, à l’améliorer, à le critiquer. C’est comme ça qu’on progresse — ensemble.


Pour aller plus loin

Ressources sur le RAG :

Outils et frameworks :

Lectures recommandées :



Dans ce voyage entre recherche et génération, nous avons vu qu’un assistant intelligent n’est pas celui qui sait tout, mais celui qui sait où chercher.
Nico ne pense pas. Mais il restitue fidèlement. Et parfois, c’est exactement ce dont nous avons besoin.
Un gardien des savoirs qui ne dort jamais, qui ne se trompe pas volontairement, qui reste humble dans son ignorance.
Magiquement vôtre,

M. Royce