Le RAG expliqué : faire répondre une IA sur vos propres documents
- 01Le RAG retrouve les passages pertinents de TES documents et les donne à l'IA comme contexte — sans réentraîner le modèle.
- 02Deux temps : indexer une fois (découper → vectoriser → stocker), puis à chaque question récupérer les morceaux proches et les injecter dans le prompt.
- 03La qualité se joue sur le découpage et le prompt "réponds uniquement d'après les extraits", pas sur le modèle.
À la fin de ce tuto, tu auras un RAG minimal qui tourne : un petit script Python qui répond à des questions sur tes propres documents (notes, FAQ, fiches produit). Plus important : tu comprendras chaque étape du mécanisme, au point de pouvoir l'adapter à ton cas.
Durée : 30 min. Prérequis : savoir lancer un script Python, une clé API (OpenAI ou Mistral — ou Ollama en local, voir le tuto dédié).
Le problème que le RAG résout
Un modèle de langage ne connaît pas tes documents internes, tes procédures ni tes fiches produit. Le RAG (Retrieval-Augmented Generation, « génération augmentée par récupération ») règle ça sans réentraîner le modèle : il va chercher les bons passages dans tes données et les fournit à l'IA au moment de répondre. C'est la brique derrière la plupart des « chatbots qui connaissent ton entreprise ».
L'idée en une phrase : plutôt qu'espérer que l'IA « sache », on lui met la réponse sous les yeux.
Les deux temps du RAG
TEMPS 1 — INDEXATION (une fois, en amont)
documents → découper en morceaux → vectoriser → stocker
TEMPS 2 — REQUÊTE (à chaque question)
question → vectoriser → retrouver les morceaux proches → injecter dans le prompt → réponse
Décortiquons, puis on code.
Temps 1 — l'indexation
- Découper tes documents en morceaux (chunks) de quelques paragraphes.
- Transformer chaque morceau en vecteur — une liste de nombres qui capture son sens — via un modèle d'embeddings.
- Stocker ces vecteurs dans une base vectorielle (Chroma, Qdrant, pgvector…).
Temps 2 — la requête
- Transformer la question en vecteur, de la même façon.
- Retrouver les morceaux dont le vecteur est le plus proche de celui de la question.
- Injecter ces morceaux dans le prompt et demander à l'IA de répondre en s'appuyant dessus.
Pourquoi des vecteurs et pas une recherche par mots-clés ?
Une recherche classique trouve « congés payés » seulement si ces mots exacts figurent dans le texte. Les embeddings capturent le sens : une question sur les « vacances » retrouvera un paragraphe parlant de « congés », même sans le mot exact. C'est ce qui rend les réponses pertinentes même quand l'utilisateur ne reprend pas tes termes.
Le RAG minimal, en Python
On va le construire avec chromadb (base vectorielle locale, zéro config) et la lib openai. Installe :
pip install chromadb openai
1. Indexer quelques documents
import chromadb
from openai import OpenAI
client = OpenAI() # OPENAI_API_KEY dans l'environnement
db = chromadb.Client()
collection = db.create_collection("docs")
# Tes documents (en vrai : lus depuis des fichiers, découpés en morceaux)
docs = [
"Nos congés payés : 25 jours par an, à poser avant le 31 mai de l'année suivante.",
"Le télétravail est autorisé jusqu'à 3 jours par semaine, sur accord du manager.",
"Les notes de frais se déclarent sous 30 jours via l'outil interne Notilus.",
]
def embed(texts):
r = client.embeddings.create(model="text-embedding-3-small", input=texts)
return [d.embedding for d in r.data]
collection.add(
ids=[f"doc{i}" for i in range(len(docs))],
documents=docs,
embeddings=embed(docs),
)
2. Répondre à une question
def ask(question: str) -> str:
# a) retrouver les 2 morceaux les plus proches
q_vec = embed([question])[0]
hits = collection.query(query_embeddings=[q_vec], n_results=2)
extraits = "\n".join(hits["documents"][0])
# b) injecter dans le prompt, cadré pour ne pas inventer
prompt = f"""Réponds à la question en t'appuyant UNIQUEMENT sur les extraits ci-dessous.
Si la réponse ne s'y trouve pas, dis-le clairement. N'invente rien.
Extraits :
{extraits}
Question : {question}"""
r = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
)
return r.choices[0].message.content
print(ask("Combien de jours de télétravail par semaine ?"))
# → "Jusqu'à 3 jours par semaine, sur accord du manager."
print(ask("Quelle est la politique sur les animaux au bureau ?"))
# → "Cette information ne figure pas dans les extraits fournis."
Teste les deux cas : une question couverte par tes docs, une qui ne l'est pas. Le second montre le garde-fou en action — l'IA refuse d'inventer.
Le prompt qui change tout
L'instruction finale est décisive. Le « réponds uniquement d'après les extraits, sinon dis que tu ne sais pas » est ton meilleur rempart contre les hallucinations. Sans cette phrase, le modèle comble les trous avec ses connaissances générales — et invente.
Les réglages qui font la qualité
- Taille des chunks : trop petits, ils perdent le contexte ; trop gros, ils noient l'info. Vise quelques centaines de mots, avec un léger chevauchement entre morceaux pour ne pas couper une idée en deux.
- Nombre de morceaux récupérés (
n_results) : 3 à 5 suffisent souvent. Plus, c'est du bruit (et des tokens payés pour rien). - Qualité des documents : un RAG nourri de documents mal structurés répondra mal. Le nettoyage en amont compte autant que le code.
- Le découpage : découpe sur la structure (titres, paragraphes), pas au caractère près.
L'adapter à tes besoins
Trois changements suffisent pour ton cas réel :
- Charge tes vrais documents (PDF, Markdown, pages…) et découpe-les en morceaux au lieu de la liste en dur.
- Persiste la base :
chromadb.PersistentClient(path="./db")au lieu deClient(), pour ne pas réindexer à chaque lancement. - Branche le modèle que tu veux : pour rester 100 % local, pointe
base_urlvers Ollama (voir le tuto Ollama) — embeddings vianomic-embed-text, génération viamistral.
Le passage à l'échelle (milliers de documents, recherche hybride, reranking) fait l'objet d'un tuto avancé.
À retenir
Le RAG ne réentraîne rien : il retrouve les bons passages de tes documents et les donne à l'IA comme contexte. On indexe une fois (découper → vectoriser → stocker), puis à chaque question on récupère les morceaux proches et on les injecte dans le prompt. Soigne le découpage et cadre le prompt sur « uniquement d'après les extraits » : c'est là, pas dans le choix du modèle, que se joue la fiabilité.
Articles liés
Mettre un RAG en production : chunking, embeddings et reranking
Les leviers qui font passer un RAG du prototype au système fiable : chunking structuré, recherche hybride vecteurs + mots-clés, reranking, et mesure du retrieval. Avec le code des étapes clés et les métriques à suivre.

Les réponses IA de Google affichées dans 43 % des recherches
Les résultats de recherche générés par IA de Google deviennent la norme pour près de la moitié des requêtes.

Une étudiante développe un algorithme d'assemblage autonome pour les robots de la NASA
Focus sur les travaux d'une étudiante pour doter les robots de la NASA de compétences d'assemblage autonomes.