RAG for agents : guide du Retrieval Augmented Generation pour agents IA
Maîtrisez le RAG (Retrieval Augmented Generation) pour vos agents IA : setup complet, embeddings, vector DB et patterns avancés. Code Python fourni.
RAG for agents : retrieval augmented generation guide pour vos agents IA
Introduction
Un agent IA sans base de connaissances, c'est un assistant qui répond de mémoire — et qui se trompe.
Le RAG (Retrieval Augmented Generation) change la donne : au lieu de compter uniquement sur ce qu'il a appris pendant l'entraînement, l'agent peut aller chercher l'information exacte dans vos documents, votre code, vos bases de données.
La différence fondamentale avec un chatbot classique : l'agent ne reçoit pas passivement du contexte. Il décide lui-même quand et quoi récupérer. Il主动ement query une source externe, évalue le résultat, et l'intègre dans son raisonnement.
Dans ce guide, vous allez apprendre à :
- ✅ Monter un pipeline RAG complet (chunking, embedding, vectorisation)
- ✅ Brancher ce pipeline sur un agent Python
- ✅ Implémenter les patterns avancés (Self-RAG, HyDE, Corrective RAG)
- ✅ Évaluer et optimiser vos performances
Résumé rapide
| Critère | Détail |
|---|---|
| Objectif | Brancher une base de connaissances sur un agent IA |
| Stack principale | Python, LangChain / OpenClaw, Chroma / Pinecone |
| Embedding | OpenAI text-embedding-3-small ou modèle local (BGE-M3) |
| Vector DB | Chroma (local), Pinecone (cloud), Qdrant (hybride) |
| Pattern recommandé | Self-RAG pour agents autonomes |
| ** Métrique clé** | Recall@5 > 0.85, latence retrieval < 200ms |
Anatomie d'un RAG pour agent
Un pipeline RAG pour agent fonctionne en 5 étapes critiques. Chaque étape détermine la qualité du retrieval final.
Les 5 étapes du pipeline
1. Chunking (découpage)
On fragmente les documents sources en morceaux de 500 à 1500 tokens. Chaque chunk doit garder son sens même sorti de son contexte.
📌 Chunking stratégique (paragraphe, section, page) dépasse le simple RecursiveCharacterTextSplitter.
2. Embedding (vectorisation)
Chaque chunk devient un vecteur de :
- 1536 dimensions (OpenAI)
- 1024 dimensions (BGE-M3)
Le vecteur capture le sens sémantique — pas les mots exacts. Deux phrases synonymes = vecteurs similaires.
3. Indexation (stockage vectoriel)
Les vecteurs sont stockés dans une base vectorielle. Celle-ci construit un index ANN (Approximate Nearest Neighbors) optimisé pour la recherche par similarité.
4. Retrieval (requête)
Quand l'agent pose une question :
- La question est embedée
- On cherche les K chunks les plus similaires dans la base vectorielle
5. Ré-ranking et injection
Les résultats bruts sont ré-ordonnés par un cross-encoder (ex: bge-reranker-v2-m3). Les top chunks sont injectés dans le prompt avec la question originale.
Question → Embedding → Vector DB (top-K) → Reranker → Prompt enrichi → Agent → Réponse
Pourquoi le chunking est crucial pour les agents
Pour un chatbot, le chunking standard suffit. Pour un agent, c'est différent.
L'agent peut faire des :
- Requêtes multi-steps (décomposition de question)
- Requêtes parallèles
La qualité du chunking détermine si l'agent retrouve l'info exacte ou juste un chunk approximatif.
Un bon chunking pour agents inclut :
- ✅ Respect des frontières sémantiques (pas de coupure au milieu d'une instruction)
- ✅ Métadonnées (source, date, section, auteur)
- ✅ Overlap de 10-20% pour capturer le contexte adjacent
🚀 Pas à pas ? Consultez notre tutoriel complet Agent IA avec LangChain pour voir ces étapes en action.
Setup RAG pas-à-pas
Prérequis
pip install langchain langchain-community langchain-openai chromadb openai
pip install rank-bm25 # pour hybrid search
Étape 1 — Chargement des documents
from langchain_community.document_loaders import DirectoryLoader, PyPDFLoader
# Chargement depuis un dossier
loader = DirectoryLoader(
"./docs",
glob="**/*.pdf",
loader_cls=PyPDFLoader
)
docs = loader.load()
# Alternative : depuis une URL Notion ou Confluence
# from langchain_community.document_loaders import NotionLoader
# loader = NotionLoader("notion-integration-token")
📌 Tip : Pour un agent de production, centralisez vos sources dans un dossier unique. Moins de loaders à maintenir.
Étape 2 — Chunking stratégique
from langchain.text_splitter import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=1000, # tokens par chunk
chunk_overlap=150, # overlap pour contexte adjacent
separators=["\n\n", "\n", ". ", " ", ""]
)
chunks = splitter.split_documents(docs)
# Ajout de métadonnées pour les agents
for i, chunk in enumerate(chunks):
chunk.metadata["chunk_id"] = i
chunk.metadata["source"] = chunk.metadata.get("source", "unknown")
Étape 3 — Embedding et indexation
from langchain_openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
embeddings = OpenAIEmbeddings(
model="text-embedding-3-small",
dimensions=1536
)
# Stockage local avec Chroma
vectorstore = Chroma.from_documents(
documents=chunks,
embedding=embeddings,
persist_directory="./chroma_db"
)
Alternative avec modèle local (BGE-M3) :
# Pour éviter les appels API (privacy-sensitive ou coût)
# from langchain_community.embeddings import HuggingFaceBgeEmbeddings
# embeddings = HuggingFaceBgeEmbeddings(
# model_name="BAAI/bge-m3",
# encode_kwargs={"normalize_embeddings": True}
# )
Étape 4 — Vector DB en production (Pinecone)
from langchain_community.vectorstores import Pinecone
# Configuration Pinecone
import pinecone
pinecone.init(api_key="YOUR_API_KEY", environment="us-west-2")
vectorstore = Pinecone.from_documents(
documents=chunks,
embedding=embeddings,
index_name="rag-agent-index"
)
Intégrer le RAG à un agent
Le tool de retrieval dans l'agent
On expose le vector store comme un tool que l'agent peut appeler. L'agent decide quand et comment l'invoquer — pas le developer.
from langchain.tools.retriever import create_retriever_tool
from langchain_openai import ChatOpenAI
from langchain.agents import create_openai_functions_agent, AgentExecutor
# Création du retriever
retriever = vectorstore.as_retriever(
search_kwargs={"k": 5} # top 5 chunks
)
# Exposition comme tool
retriever_tool = create_retriever_tool(
retriever,
name="knowledge_base",
description="Recherche dans la base de connaissances de l'entreprise. Utilise ce tool pour répondre aux questions techniques ou factuelles."
)
# Outils disponibles par l'agent
tools = [retriever_tool]
# Agent avec capacité de retrieval
llm = ChatOpenAI(model="gpt-4o", temperature=0)
agent = create_openai_functions_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools)
Requête multi-step et query decomposition
L'agent ne se contente pas de poser une question brute. Il peut la décomposer en sous-requêtes, puis aggregator les résultats.
from langchain.prompts import ChatPromptTemplate
from langchain.schema import StrOutputParser
# Décomposition de question complexe
decomposition_prompt = ChatPromptTemplate.from_template("""
Tu décomposes cette question en 2-3 sous-questions indépendantes.
Question : {question}
Sous-questions :
""")
decomposition_chain = decomposition_prompt | llm | StrOutputParser()
sub_questions = decomposition_chain.invoke({"question": user_question})
# Exécution parallèle des sous-requêtes
# → chaque sous-question appelle le retriever
# → les résultats sont fusionnés
Le processus :
- 📝 L'agent décompose la question en sous-questions
- 🔍 Chaque sous-questions appelle le retriever en parallèle
- 🔄 Les résultats sont fusionnés avant la réponse finale
Intégration avec OpenClaw
# Dans OpenClaw, le tool se déclare ainsi dans le workflow :
tools=[
{
"name": "rag_retrieval",
"description": "Interroge la base de connaissances pour répondre aux questions techniques.",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Question naturelle de l'utilisateur"
},
"top_k": {
"type": "integer",
"description": "Nombre de chunks à récupérer (défaut: 5)"
}
},
"required": ["query"]
}
}
]
Le runtime OpenClaw lie ce tool à l'agent. L'agent decide autonomously quand et comment l'appeler.
💡 Pour aller plus loin : Découvrez comment la mémoire des agents complète le RAG pour une compréhension contextuelle complète.
Patterns RAG avancés
Trois patterns transforment le retrieval en mécanisme réflexif. Choisissez selon votre use case.
Self-RAG — L'agent decide quand retrieve
Self-RAG est le pattern le plus puissant pour les agents autonomes.
Principe : On ajoute un token spécial [RETRIEVE] que le modèle peut générer quand il estime avoir besoin d'information externe. Après le retrieval, le modèle évalue avec [PASSWORD] (utilise le document) ou [NO PASS] (ignore).
# Pseudo-code pour Self-RAG
class SelfRAGAgent:
def step(self, state):
# Le modèle génère, potentiellement avec [RETRIEVE]
generation = self.llm.generate(state.messages)
if "[RETRIEVE]" in generation:
query = extract_query(generation)
docs = self.retriever.invoke(query)
graded_docs = self.grade_documents(docs) # PASSWORD ou NO PASS
filtered_docs = [d for d in graded_docs if d.is_passage()]
state.messages.append(retrieval_result(filtered_docs))
return self.llm.generate(state.messages) # Réponse finale
Quand utiliser Self-RAG :
- ✅ Agents autonomes avec banyak tool calls
- ✅ Scenarios ou le retrieval fréquent n'est pas nécessaire
- ✅ Reduction du nombre de retrievals inutiles
HyDE — Hypothetical Document Embedding
HyDE génère d'abord un document hypothétique qui répondrait à la question. Ce document fictif est embedé pour trouver les chunks réels les plus similaires.
from langchain.schema import HumanMessage
def hyde_retrieval(question, vectorstore, llm):
# 1. Générer un document hypothétique
hypothetical_prompt = f"""
Écris un court document factuel qui répondrait exactement à cette question.
Question : {question}
Document :
"""
hypo_doc = llm.invoke([HumanMessage(content=hypothetical_prompt)])
# 2. Embed le document hypothétique
hypo_embedding = embeddings.embed_query(hypo_doc.content)
# 3. Retrieve avec cet embedding
results = vectorstore.similarity_search_by_vector(hypo_embedding, k=5)
return results
Pourquoi ça marche : Le document hypothétique capture l'intention de la question. Il utilise les bons termes techniques, ce qui améliore la匹配 entre la query et les chunks.
Corrective RAG — L'agent corrige le retrieval
CRAG détecte quand le retrieval est insuffisant ou incorrect, et corrige le tir dynamiquement.
def corrective_rag(question, vectorstore, llm):
# 1. Retrieval initial
docs = vectorstore.similarity_search(question, k=5)
# 2. Évaluation par cross-encoder
graded = cross_encoder_score(docs, question) # 0-1 score
# 3. Action selon le score moyen
if sum(graded) / len(graded) > 0.7:
return docs # Bon enough
elif sum(graded) / len(graded) > 0.3:
# Retry avec query expansion
expanded_queries = query_expansion(question, llm)
all_docs = []
for q in expanded_queries:
all_docs.extend(vectorstore.similarity_search(q, k=3))
return deduplicate(all_docs)
else:
# Fallback : web search comme备用
return web_search_fallback(question)
Le flowchart CRAG :
Retrieval initial
↓
Cross-encoder score > 0.7 ?
→ OUI : ✅ Use documents
→ NON : Score > 0.3 ?
→ OUI : 🔄 Query expansion + retry
→ NON : 🌐 Web search fallback
Évaluer un RAG agent
Métriques essentielles
| Métrique | Description | Cible |
|---|---|---|
| Recall@K | % de documents pertinents retrievés dans les K premiers | > 0.85 |
| Precision@K | % de documents pertinents parmi les K récupérés | > 0.60 |
| Answer Accuracy | Correctitude factuelle de la réponse (LLM-as-judge) | > 4/5 |
| Latence retrieval | Temps de retrieval (embedding + search + rerank) | < 200ms |
| Hallucination rate | % de réponses contenant des faits non présents dans les docs | < 5% |
Protocole de test automatisé
from langchain.evaluation import QAEvalChain
# Évaluation automatique avec LLM-as-judge
eval_chain = QAEvalChain.from_llm(llm)
test_questions = [
{"question": "Comment configurer le retriever ?", "expected": "via search_kwargs"},
{"question": "Quelle est la taille de chunk recommandée ?", "expected": "500-1500 tokens"},
# ... 20+ questions représentatives
]
results = eval_chain.evaluate(examples=test_questions)
Utilisez RAGAS pour une évaluation standardisée :
pip install ragas
from ragas import evaluate
from ragas.metrics import (
faithfulness, answer_relevancy, context_relevancy
)
results = evaluate(
dataset=test_dataset,
metrics=[faithfulness, answer_relevancy, context_relevancy]
)
Tests de qualité manuels
- Test par domaine : Échantillonnez 50 questions par domaine (technique, factuel, conceptuel)
- Adversarial testing : Posez des questions hors scope pour vérifier que l'agent ne hallucine pas
- Test de couverture : Pour chaque réponse, vérifiez manuellement que les docs utilisés contiennent bien l'information citée
Optimisation
Caching des embeddings
Les mêmes queries reviennent souvent. Un cache Redis réduit drastiquement les appels aux embedding models.
import redis
from functools import lru_cache
r = redis.Redis(host="localhost", port=6379, db=0)
def cached_embed(text):
cache_key = f"embed:{hash(text)}"
cached = r.get(cache_key)
if cached:
return eval(cached) # Ou pickle.loads
embedding = embeddings.embed_query(text)
r.setex(cache_key, 3600, str(embedding)) # TTL 1h
return embedding
Résultat typique : 40-60% de réduction des appels API pour un agent en production.
Cold start problem
Quand la base est vide ou presque vide, le retrieval est inutile.
Solutions :
- Seed avec FAQ générée : Générez 50 Q&A typiques et indexez-les avant le lancement
- Hybrid search : Combinez vector search + keyword search (BM25)
Pourquoi hybrid search :
- Vector : capture la semantics
- BM25 : capture les termes exacts non présents dans le query embedding
from langchain.retrievers import EnsembleRetriever
# Fusion des deux approches
vector_retriever = vectorstore.as_retriever(search_kwargs={"k": 5})
bm25_retriever = BM25Retriever.from_documents(chunks)
ensemble = EnsembleRetriever(
retrievers=[vector_retriever, bm25_retriever],
weights=[0.6, 0.4] # 60% vectoriel, 40% keyword
)
Hybrid search complète avec RRF
from rank_bm25 import BM25Okapi
import numpy as np
tokenized_chunks = [chunk.page_content.split() for chunk in chunks]
bm25 = BM25Okapi(tokenized_chunks)
def hybrid_search(query, k=5):
# Vector similarity
query_vector = embeddings.embed_query(query)
vector_results = vectorstore.similarity_search_with_score(query_vector, k=k*2)
# BM25 score
tokenized_query = query.split()
bm25_scores = bm25.get_scores(tokenized_query)
top_bm25_indices = np.argsort(bm25_scores)[::-1][:k*2]
# Fusion with RRF (Reciprocal Rank Fusion)
rrf_scores = {}
for i, (doc, score) in enumerate(vector_results):
rrf_scores[doc.page_content] = rrf_scores.get(doc.page_content, 0) + 1 / (60 + i)
for i, idx in enumerate(top_bm25_indices):
doc = chunks[idx]
rrf_scores[doc.page_content] = rrf_scores.get(doc.page_content, 0) + 1 / (60 + i)
sorted_results = sorted(rrf_scores.items(), key=lambda x: x[1], reverse=True)
return sorted_results[:k]
Votre prochaine étape :
🔧 Prêt à commencer ? Montez Chroma en local, montez un premier agent avec retrieval tool, puis itérez vers Self-RAG une fois le setup validé. Le setup minimal prend 30 minutes avec LangChain + Chroma.
Conclusion
Le RAG pour agents repose sur 5 étapes clés :
- 🔲 Chunking
- 🔲 Embedding
- 🔲 Indexation
- 🔲 Retrieval
- 🔲 Ré-ranking
Le setup minimal prend 30 minutes avec LangChain + Chroma. L'intégration dans un agent demande d'exposer le vector store comme un tool que l'agent peut appeler de manière autônome.
Les patterns avancés (Self-RAG, HyDE, Corrective RAG) transforment le retrieval en un mécanisme réflexif : l'agent ne se contente pas de retrieve, il évalue et corrige. Pour un agent de production en 2026, c'est le standard.
Les métriques à surveiller :
- 📊 Recall@5 (cible > 0.85)
- ⚡ Latence retrieval (< 200ms)
- 🚫 Taux d'hallucination (< 5%)
Questions fréquentes
Qu'est-ce que le RAG pour un agent IA ?
Le RAG (Retrieval Augmented Generation) pour agent est un système qui permet à un agent IA d'aller chercher de l'information dans une base de connaissances externe avant de répondre. Contrairement à un chatbot classique qui utilise uniquement ses données d'entraînement, l'agent peut interroger vos documents, code, ou bases de données en temps réel pour produire des réponses factuelles et à jour.
Comment brancher une base de connaissances sur un agent Python ?
Utilisez LangChain ou OpenClaw pour exposer votre vector store comme un tool.
- Créez un retriever depuis Chroma ou Pinecone
- Déclarez-le comme tool disponible pour l'agent
- L'agent decidera autonomement quand l'invoquer
Le code minimal : 5 lignes pour créer le retriever, une déclaration de tool pour l'intégrer.
Quelle est la différence entre RAG et agent memory ?
| Aspect | Agent Memory | RAG |
|---|---|---|
| Stocke | Historique conversation + préférences | Documents externes structurés |
| Gère | Contexte conversationnel | Connaissance factuelle |
| Use case | Suivi du dialogue | Réponses à jour sur vos docs |
Les deux sont complémentaires. Voir /agents/agent-memory pour les détails sur la mémoire d'agent.
Quel vector store choisir pour un agent en production ?
| Use case | Recommandation | Pourquoi |
|---|---|---|
| Premier setup | Chroma | Local, gratuit, rapide |
| Production cloud | Pinecone ou Qdrant | Meilleure latence, scalabilité auto |
| Hybrid search | Qdrant | Vector + keyword intégré |
Voir notre guide Pinecone pour les détails complets.
Comment évaluer la qualité du retrieval d'un agent ?
Métriques principales :
- Recall@K — quelle proportion des docs pertinents est retrouvée
- Precision@K — quelle proportion des docs retrieval est pertinente
- Answer Accuracy — via LLM-as-judge
Outils recommandés :
- RAGAS — évaluation automatisée standardisée
- Test manuel — 50 questions représentatives par domaine
Articles liés
Le RAG pour agents s'inscrit dans une stack plus large. Voici les ressources pour aller plus loin.
- 📚 Mémoire des agents IA : comment donner une vraie capacité de rétention à vos agents — Complément direct du RAG pour la mémoire conversationnelle
- 🧠 Mémoire vectorielle pour agents IA : la layer embeddings qui change tout — Approfondissez votre compréhension des vector stores
- ☁️ Guide Pinecone : vector database pour IA et agents — Setup complet Pinecone en production
- 🔗 LangChain : le framework pour construire des chains RAG et des agents — L'outil principal pour assembler RAG + agent
- 🚀 Agent IA avec LangChain : le tutoriel complet — De zéro à agent fonctionnel avec retrieval intégré
Restez informé sur les agents IA
Nouveaux tutoriels, comparatifs et guides pratiques directement dans votre boîte mail.