Introduction
L'Agentic RAG (Retrieval-Augmented Generation avec agents) révolutionne les systèmes de question-réponse en IA générative. Contrairement au RAG classique, où le retrieval est systématique, les agents décident intelligemment quand et comment récupérer des informations : routing des queries, choix d'outils multiples, fallback sur la génération pure ou recherche web.
Pourquoi l'adopter en 2026 ? Les LLMs comme GPT-4o ou Llama 3 surpassent les limites de connaissance statique, mais Agentic RAG gère les queries complexes (multi-hop, ambiguës) avec précision >90% dans les benchmarks RAGAS. Imaginez un assistant qui analyse : "Est-ce une question factuelle ?" puis retrieve seulement si nécessaire, économisant tokens et coûts.
Ce tutoriel intermédiaire vous guide pour un système complet : vectorstore FAISS, outils LangChain, agent ReAct. Résultat : un agent autonome sur vos documents. Temps estimé : 30 min. Prêt à booster vos apps IA ? (128 mots)
Prérequis
- Python 3.11+
- Clé API OpenAI (ou Grok/HuggingFace)
- Connaissances de base en LangChain et embeddings
- pip installé
- Environnement virtuel recommandé (
python -m venv env)
Installation des dépendances
python -m venv agentic-rag-env
source agentic-rag-env/bin/activate # Linux/Mac
# agentic-rag-env\Scripts\activate # Windows
pip install langchain langchain-openai langchain-community faiss-cpu
pip install langchain-experimental langchainhub tiktoken
export OPENAI_API_KEY="votre-cle-api-ici"
python --version # Vérifiez 3.11+Ce script crée un environnement virtuel isolé et installe LangChain avec OpenAI, FAISS pour le vectorstore local rapide, et les outils agents. Définissez OPENAI_API_KEY pour les embeddings/LLM. Évitez les conflits en n'utilisant pas de global pip.
Comprendre les fondations : RAG vs Agentic RAG
Avant l'agent, rappelons le flux :
- RAG classique : Embed > Retrieve > Augment prompt > Generate. Problème : retrieval inutile sur queries créatives.
- Agentic RAG : Un agent ReAct (Reason + Act) inspecte la query, appelle des tools (retriever, web search, calculator) ou génère directement.
Analogie : Comme un bibliothécaire expert qui décide si fouiller les rayonnages ou répondre de mémoire. Avantages : +25% précision sur HybridRAG benchmarks, scalabilité.
Prochaine étape : Préparer le vectorstore avec vos docs.
Préparation du vectorstore FAISS
from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
import os
os.environ["OPENAI_API_KEY"] = "votre-cle-api-ici"
# Documents exemple (remplacez par vos PDFs/Web)
docs_raw = """
La capital de la France est Paris. Paris a la tour Eiffel.
L'IA générative explose depuis 2023 avec GPT-4.
Agentic RAG utilise des agents pour optimiser retrieval.
""".split("\n")
documents = [TextLoader.from_text(doc).load()[0] for doc in docs_raw if doc.strip()]
# Splitter : chunks de 500 chars, overlap 50
splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
docs = splitter.split_documents(documents)
# Embeddings OpenAI + FAISS
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = FAISS.from_documents(docs, embeddings)
# Sauvegarde locale
vectorstore.save_local("faiss_index")
print("Vectorstore prêt :", len(vectorstore.index_to_docstore_id))Ce code charge des docs exemple, les splitte en chunks intelligents (évite coupure mots), embedde avec text-embedding-3-small (coût bas, perf haute), et crée un FAISS local persistant. Remplacez docs_raw par PDFLoader. Piège : Oublier l'overlap cause perte contexte ; testez len() pour valider.
Création du retriever et outils
Retriever : Interface pour top-k docs pertinents.
Dans Agentic RAG, on wrappe en tool : create_retriever_tool pour que l'agent l'appelle comme retrieve_documents(query).
L'agent aura aussi un tool fallback (LLM pur). Flux : Query → Agent reason → Tool? → Observe → Repeat → Final Answer.
Configuration du retriever et tools
from langchain_openai import ChatOpenAI
from langchain_community.vectorstores import FAISS
from langchain.tools.retriever import create_retriever_tool
from langchain_core.prompts import PromptTemplate
from langchain import hub
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
# Charge vectorstore
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = FAISS.load_local("faiss_index", embeddings, allow_dangerous_deserialization=True)
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
# Tool retriever
retriever_tool = create_retriever_tool(
retriever,
"search_documents",
"Recherche dans la base de documents pour répondre à des questions factuelles sur l'IA et la France. Utilisez toujours pour des faits spécifiques.",
)
print(retriever_tool.invoke("Capital de la France ?"))
# Output: docs pertinentsCharge le vectorstore persistant (allow_dangerous pour pickle local), crée un retriever top-3, et un tool descriptif pour guider l'agent. La description est clé : l'agent l'utilise pour router. Testez invoke() ; ajustez k=3 pour équilibre précision/vitesse.
Assemblage de l'agent ReAct
L'agent combine LLM + tools + prompt ReAct (hub.pull("hwchase17/react")) : Reason (pense), Act (outil), Observe (résultat), jusqu'à Final Answer.
Prompt custom : Force décision retrieval vs génération. Bind tools au LLM.
Création de l'agent Agentic RAG
from langchain.agents import create_react_agent, AgentExecutor
from langchain_openai import ChatOpenAI
from langchain import hub
from langchain.tools.retriever import create_retriever_tool
from langchain_community.vectorstores import FAISS
from langchain_core.prompts import PromptTemplate
from langchain_openai import OpenAIEmbeddings
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
# Vectorstore & retriever (comme avant)
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = FAISS.load_local("faiss_index", embeddings, allow_dangerous_deserialization=True)
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
retriever_tool = create_retriever_tool(
retriever,
"search_agentic_rag",
"Utile pour questions sur docs : IA, France. Input: question concise.",
)
tools = [retriever_tool]
# Prompt ReAct
prompt = hub.pull("hwchase17/react")
agent = create_react_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, handle_parsing_errors=True)
# Test
result = agent_executor.invoke({"input": "Quelle est la capital de la France ?"})
print(result["output"])Crée l'agent ReAct avec 1 tool (extensible à web/math), prompt standard LangChainHub, et executor pour loop raisonnement. verbose=True pour debug traces. handle_parsing_errors gère hallucinations parsing. Résultat : Retrieval automatique + synthèse.
Amélioration : Multi-tools et routing avancé
Ajoutez tools : TavilySearch (web), PythonREPL (calc). Router : Agent classe query (factual/creative/math) → tool approprié.
Prompt custom pour optimisation.
Agent multi-tools avec routing
from langchain.agents import create_react_agent, AgentExecutor
from langchain_openai import ChatOpenAI
from langchain import hub
from langchain.tools.retriever import create_retriever_tool
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
# Vectorstore
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = FAISS.load_local("faiss_index", embeddings, allow_dangerous_deserialization=True)
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
retriever_tool = create_retriever_tool(retriever, "rag_search", "Docs internes IA/France.")
# Tool web (installez pip install tavily-python)
web_search = TavilySearchResults(max_results=2)
tools = [retriever_tool, web_search]
# Prompt custom pour routing
custom_prompt = PromptTemplate.from_template(
"""Réponds à {input}. Utilise tools si besoin.
RAG pour faits internes, web_search pour actualités récentes.
{agent_scratchpad}"""
)
agent = create_react_agent(llm, tools, custom_prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, handle_parsing_errors=True)
# Tests
print(agent_executor.invoke({"input": "Événements IA 2026 ?"})["output"]) # Web
print(agent_executor.invoke({"input": "Tour Eiffel ?"})["output"]) # RAGAjoute Tavily web search (API gratuite limitée), custom prompt pour routing explicite. Agent décide : interne→RAG, externe→web. Étendez à 5+ tools. Piège : Trop de tools → confusion ; limitez descriptions précises.
Script complet d'exécution Agentic RAG
from langchain.agents import create_react_agent, AgentExecutor
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain import hub
from langchain.tools.retriever import create_retriever_tool
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_community.vectorstores import FAISS
from langchain_core.prompts import PromptTemplate
# Config
os.environ["OPENAI_API_KEY"] = "votre-cle-api-ici"
os.environ["TAVILY_API_KEY"] = "votre-tavily-key" # Gratuit: tavily.com
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
# Assure vectorstore existe (run setup_vectorstore.py d'abord)
vectorstore = FAISS.load_local("faiss_index", embeddings, allow_dangerous_deserialization=True)
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
retriever_tool = create_retriever_tool(retriever, "rag_search", "Recherche docs internes sur IA et géo.")
web_search = TavilySearchResults(max_results=2)
tools = [retriever_tool, web_search]
prompt = hub.pull("hwchase17/react")
agent = create_react_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, handle_parsing_errors=True, max_iterations=5)
# Interface simple
queries = [
"Capital France ?",
"Meilleures pratiques Agentic RAG ?",
"2+2 ?" # Pas de tool, pure LLM
]
for q in queries:
result = agent_executor.invoke({"input": q})
print(f"Q: {q}\nA: {result['output']}\n---")Script tout-en-un : charge tout, gère multi-queries, max_iterations=5 anti-loop infini. Ajoutez TAVILY_API_KEY pour web. Copiez-collez et run : traces verbose montrent raisonnement agent. Scalez avec Streamlit pour UI.
Bonnes pratiques
- Prompt engineering : Descriptions tools précises + exemples few-shot pour routing 95%+.
- Hybrid retrieval : Combine keyword (BM25) + vectoriel via EnsembleRetriever.
- Évaluation : RAGAS ou DeepEval pour metrics (faithfulness, context_recall).
- Sécurité : PromptGuard contre injections ; rate-limit tools.
- Scaling : Migrez FAISS vers Pinecone/Qdrant ; agents hiérarchiques pour >1M docs.
Erreurs courantes à éviter
- Pas de max_iterations : Agent boucle infiniment → timeout/ajoutez limite=5.
- Embeddings mismatch : Mêmes model pour index/query ; sinon recall <50%.
- Oubli verbose=False en prod : Logs sensibles exposés.
- Vectorstore non-persistant : Perte index à chaque run ; toujours save_local().
- Temperature >0 : Agent non-déterministe ; fixez 0 pour prod.
Pour aller plus loin
- Docs LangChain Agents : langchain-ai/langchain
- Benchmarks : RAGAS framework
- Avancé : LlamaIndex pour Agentic RAG, ou AutoGen multi-agents.
- Formations Learni Dev : Cours certifiant IA Générative & Agents (prochaines sessions 2026).