Construire un mini-RAG open-source, étape par étape
Un RAG (Retrieval-Augmented Generation) est un système qui connecte un modèle de langage à vos propres documents. Au lieu de répondre depuis sa mémoire d'entraînement, le modèle consulte votre base documentaire avant de formuler une réponse. Ce tutoriel vous guide pour construire un mini-RAG open-source étape par étape, avec des outils entièrement gratuits qui fonctionnent hors ligne. C'est la brique de base pour un moteur de recherche intelligent sur vos archives internes.
Comprendre le RAG avant de le construire
Le fonctionnement d'un RAG se décompose en trois étapes distinctes :
- Indexation : vos documents sont découpés en morceaux, chaque morceau est transformé en vecteur numérique (embedding) et stocké dans une base vectorielle.
- Recherche : lorsqu'un utilisateur pose une question, le système la transforme également en vecteur et retrouve les morceaux de documents les plus proches sémantiquement.
- Génération : les extraits pertinents sont transmis au modèle de langage comme contexte, qui formule une réponse fondée sur vos données réelles.
Les outils de ce tutoriel : Ollama pour le modèle de langage et les embeddings, ChromaDB comme base vectorielle légère, et LangChain pour orchestrer le tout.
Prérequis pour le mini-RAG open-source
- Python 3.10 ou supérieur installé
- Ollama installé et fonctionnel (exécutez
ollama --versionpour vérifier) - 8 Go de RAM minimum (16 Go si vous traitez de gros volumes)
- Vos documents sources au format PDF, TXT ou Markdown
- Connexion internet pour le premier téléchargement des dépendances et modèles
Préparer l'environnement Python
- Créez un environnement virtuel dédié :
python3 -m venv rag-env source rag-env/bin/activate # Windows : rag-env\Scripts\activate - Installez les dépendances nécessaires :
Cette commande installe LangChain, ChromaDB, les outils de lecture PDF et les bibliothèques d'embeddings.pip install langchain langchain-community chromadb \ sentence-transformers pypdf ollama - Téléchargez les modèles Ollama requis :
Le modèle nomic-embed-text est optimisé pour les embeddings. Il est léger (environ 270 Mo) et rapide.# Modele de langage pour generer les reponses ollama pull mistral:7b # Modele d'embedding pour transformer les textes en vecteurs ollama pull nomic-embed-text
Indexer vos documents
Créez un fichier indexer.py dans votre répertoire de travail. Ce script charge vos documents, les découpe et construit l'index vectoriel.
from langchain_community.document_loaders import PyPDFLoader, DirectoryLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.embeddings import OllamaEmbeddings
from langchain_community.vectorstores import Chroma
import os
# Charger tous les PDF depuis un dossier
loader = DirectoryLoader(
"./documents",
glob="**/*.pdf",
loader_cls=PyPDFLoader
)
documents = loader.load()
print(f"{len(documents)} pages chargees depuis {len(set(d.metadata['source'] for d in documents))} fichiers")
# Decouper en morceaux avec chevauchement
splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50
)
chunks = splitter.split_documents(documents)
print(f"{len(chunks)} morceaux crees")
# Creer les embeddings et stocker dans ChromaDB
embeddings = OllamaEmbeddings(model="nomic-embed-text")
db = Chroma.from_documents(
chunks,
embeddings,
persist_directory="./chroma_db"
)
db.persist()
print("Index cree avec succes dans ./chroma_db")
Placez vos PDF dans un dossier ./documents, puis lancez l'indexation :
python indexer.py
Sur du matériel modeste sans GPU, l'indexation de 100 pages peut prendre 5 à 15 minutes. L'index est sauvegardé sur disque et n'est pas à reconstruire à chaque démarrage.
Interroger votre base documentaire
Créez un fichier ask.py pour poser des questions à votre RAG :
from langchain_community.embeddings import OllamaEmbeddings
from langchain_community.vectorstores import Chroma
from langchain_community.llms import Ollama
from langchain.chains import RetrievalQA
# Charger la base vectorielle existante
embeddings = OllamaEmbeddings(model="nomic-embed-text")
db = Chroma(
persist_directory="./chroma_db",
embedding_function=embeddings
)
# Configurer le retriever : recupere les 3 morceaux les plus pertinents
retriever = db.as_retriever(search_kwargs={"k": 3})
# Creer la chaine RAG
llm = Ollama(model="mistral:7b")
qa = RetrievalQA.from_chain_type(
llm=llm,
retriever=retriever,
return_source_documents=True
)
# Boucle de questions-reponses
while True:
question = input("\nVotre question (ou 'quitter') : ")
if question.lower() == "quitter":
break
resultat = qa({"query": question})
print("\nReponse :")
print(resultat["result"])
print("\nSources consultees :")
for doc in resultat["source_documents"]:
source = doc.metadata.get("source", "document")
page = doc.metadata.get("page", "?")
print(f" - {source} (page {page})")
Lancez le script :
python ask.py
Posez une question sur le contenu de vos documents. Le système affiche la réponse et les sources consultées pour l'élaborer.
Ajouter une interface web avec Streamlit
Pour rendre le RAG accessible à des collègues non techniques, ajoutez une interface web simple :
pip install streamlit
Créez un fichier app.py avec l'interface Streamlit, puis lancez-la :
streamlit run app.py
Streamlit génère une interface web accessible depuis un navigateur sur le réseau local. Aucune connaissance en développement web n'est requise.
Mettre à jour et maintenir l'index
- Ajoutez de nouveaux documents dans le dossier
./documentset relancezpython indexer.pypour mettre à jour l'index. - LangChain prend aussi en charge les fichiers Word (
Docx2txtLoader), les fichiers texte, les pages web et les emails. - Pour de gros volumes (plus de 5 000 pages), pensez à passer à une base vectorielle plus performante comme Qdrant ou Milvus.
Limites et précautions
- La qualité des réponses dépend directement de la qualité des documents sources. Des PDFs scannés sans OCR ne sont pas lisibles par PyPDFLoader. Utilisez OCRmyPDF pour les préparer.
- Le modèle peut parfois inventer des informations si les documents sources ne contiennent pas la réponse. Ajoutez une instruction dans votre prompt système pour qu'il indique explicitement quand il ne trouve pas l'information.
- Sur une machine sans GPU, une question peut prendre 30 à 60 secondes pour obtenir une réponse. C'est acceptable pour un usage ponctuel.
Vous disposez maintenant d'un moteur de recherche intelligent sur vos propres documents, entièrement local et sans coût d'exploitation récurrent. C'est une brique fondamentale pour des assistants internes, des bases de connaissances ou des outils d'aide à la décision. Pour aller plus loin avec une version production, des connecteurs vers vos outils métier, ou une interface adaptée à vos équipes, nos services sont là pour vous accompagner.
Un projet en tête après cette lecture ?
Parlons-en. Première lecture et devis gratuits, réponse sous 24 h.
Parlons-en


