FrameworksAgents.com Logo

RAG for agents : guide du Retrieval Augmented Generation pour agents IA

Tutorielcalendar_todayPublié le 3 juin 2026schedule15 min de lecturerag agent iaretrieval augmented generation agent

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èreDétail
ObjectifBrancher une base de connaissances sur un agent IA
Stack principalePython, LangChain / OpenClaw, Chroma / Pinecone
EmbeddingOpenAI text-embedding-3-small ou modèle local (BGE-M3)
Vector DBChroma (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 :

  1. La question est embedée
  2. 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 :

  1. 📝 L'agent décompose la question en sous-questions
  2. 🔍 Chaque sous-questions appelle le retriever en parallèle
  3. 🔄 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étriqueDescriptionCible
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 AccuracyCorrectitude factuelle de la réponse (LLM-as-judge)> 4/5
Latence retrievalTemps 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

  1. Test par domaine : Échantillonnez 50 questions par domaine (technique, factuel, conceptuel)
  2. Adversarial testing : Posez des questions hors scope pour vérifier que l'agent ne hallucine pas
  3. 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 :

  1. Seed avec FAQ générée : Générez 50 Q&A typiques et indexez-les avant le lancement
  2. 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 :

  1. 🔲 Chunking
  2. 🔲 Embedding
  3. 🔲 Indexation
  4. 🔲 Retrieval
  5. 🔲 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.

  1. Créez un retriever depuis Chroma ou Pinecone
  2. Déclarez-le comme tool disponible pour l'agent
  3. 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 ?

AspectAgent MemoryRAG
StockeHistorique conversation + préférencesDocuments externes structurés
GèreContexte conversationnelConnaissance factuelle
Use caseSuivi du dialogueRé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 caseRecommandationPourquoi
Premier setupChromaLocal, gratuit, rapide
Production cloudPinecone ou QdrantMeilleure latence, scalabilité auto
Hybrid searchQdrantVector + 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.


Restez informé sur les agents IA

Nouveaux tutoriels, comparatifs et guides pratiques directement dans votre boîte mail.

homeAccueilcodeFrameworkssmart_toyAgentsmenu_bookTutorielsTwitter