LlamaIndex outil RAG pour agents IA
Guide pratique : utilisez LlamaIndex comme couche RAG dans un agent IA. Index vectoriels, query engines et intégration Python.
LlamaIndex — Outil RAG pour Agents IA
TL;DR — LlamaIndex fournit les briques pour brancher vos documents sur un agent : chargement, indexation vectorielle, retrieval et synthèse LLM. Voici comment assembler le tout en Python.
Un agent IA sans contexte, c'est un agent qui hallucine. LlamaIndex résout ça en ajoutant une couche RAG modulaire : vos documents, vos bases de connaissances, vos données internes — l'agent y accède quand l'utilisateur pose une question.
Ce que vous allez apprendre
- Monter un pipeline RAG complet avec LlamaIndex v0.10+
- Charger des documents depuis PDF, web, Notion, Confluence
- Construire et persister un index vectoriel
- Personnaliser retrievers et query engines
- Intégrer LlamaIndex dans un agent Python ou OpenClaw
Prérequis : Python 3.10+, أساس d'un LLM (OpenAI, Claude, Gemini…).
Résumé rapide — Les 5 briques LlamaIndex
| Brique | Rôle | Point clé |
|---|---|---|
| Readers | Charger PDF, web, API, bases SaaS | LlamaHub = 300+ connecteurs |
| Index | Structurer les documents en vecteurs | VectorStoreIndex pour le RAG |
| Retriever | Extraire les chunks pertinents | top_k + filtres métadonnées |
| Query Engine | Retrieval + synthèse LLM | Change de LLM sans recoder |
| Postprocessors | Affiner après retrieval | Reranking, deduplication |
1. Architecture modulaire — Les 5 couches
LlamaIndex n'est pas un agent tout-en-un. C'est une bibliothèque de composants RAG que vous cobuild selon vos besoins. Voici chaque couche.
Readers — Charger les documents
SimpleDirectoryReader lit tous les fichiers d'un dossier (PDF, TXT, MD, CSV…) :
from llama_index.core import SimpleDirectoryReader
documents = SimpleDirectoryReader("./data").load_data()
print(f"{len(documents)} documents chargés")
Pour des sources spécifiques, LlamaHub propose des readers communautaires :
from llama_index.readers.notion import NotionReader
reader = NotionReader(
integration_token="secret_xxx",
page_ids=["id-page-1", "id-page-2"]
)
documents = reader.load_data()
Autres readers disponibles : Confluence, Slack, GitHub, ArXiv, YouTube, web URLs… Voir LlamaHub.
Index — Du texte brut à la structure vectorielle
VectorStoreIndex convertit vos documents en embeddings et les stocke pour la recherche par similarité :
from llama_index.core import VectorStoreIndex
index = VectorStoreIndex.from_documents(documents)
# Persiste en RAM. Pour production → storage_context.persist()
Retrievers — Récupérer les chunks pertinents
Le retriever retourne les N chunks les plus proches de la requête via similarité cosinus :
from llama_index.core.retrievers import VectorRetriever
retriever = VectorRetriever(
index=index,
top_k=5,
# filters : filtre sur métadonnées (date, catégorie…)
)
Query Engine — Retrieval + génération
Le query engine combine retrieval et synthèse LLM. Il prend une question → retourne une réponse générée :
query_engine = index.as_query_engine(
llm=your_llm,
top_k=5,
response_mode="compact" # fusionne les chunks pour réduire les tours LLM
)
response = query_engine.query("Quel est le processus de déploiement sur VPS ?")
print(response)
Node Postprocessors — Affiner après retrieval
Postprocessors可以对结果进行重排、去重或过滤,提升最终质量:
from llama_index.core.postprocessor import SimilarityPostprocessor
query_engine = index.as_query_engine(
similarity_top_k=10, # on récupère plus que nécessaire
node_postprocessors=[
SimilarityPostprocessor(similarity_cutoff=0.7),
]
)
2. Charger et parser vos documents
Le parsing sépare le texte brut de la structure sémantique. Un mauvais parsing = un RAG médiocre, quel que soit le modèle.
PDF avec SimpleDirectoryReader
from llama_index.core import SimpleDirectoryReader
documents = SimpleDirectoryReader(
input_dir="./documents",
required_exts=[".pdf"],
# num_workers=4 : parallelise le parsing
).load_data()
for doc in documents:
print(doc.metadata) # {filename, page_number, …}
Web avec UnstructuredURLLoader
from llama_index.core import UnstructuredURLLoader
urls = [
"https://docs.llamaindex.ai/en/stable/",
"https://arxiv.org/abs/2312.10962",
]
documents = UnstructuredURLLoader(urls=urls).load()
Contrôle fin du chunking
from llama_index.core.node_parser import SentenceSplitter
node_parser = SentenceSplitter(
chunk_size=512, # caractères par chunk
chunk_overlap=128, # overlap pour maintenir le contexte aux frontières
)
nodes = node_parser.get_nodes_from_documents(documents)
print(f"{len(nodes)} nodes créés")
index = VectorStoreIndex(nodes)
Chunk size : 512 caractères = une idée. 2048 = un paragraphe ou une section. Expérimentez selon votre corpus.
3. Créer et persister un index vectoriel
Construction et persistance
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
documents = SimpleDirectoryReader("./data").load_data()
index = VectorStoreIndex.from_documents(documents)
index.storage_context.persist(persist_dir="./index_storage")
Charger un index existant
from llama_index.core import load_index_from_storage
from llama_index.core.storage import StorageContext
storage_context = StorageContext.from_defaults(persist_dir="./index_storage")
index = load_index_from_storage(storage_context)
Construisez l'index une fois, rechargez-le en production sans recalculer les embeddings.
Mise à jour incrémentale
new_docs = SimpleDirectoryReader("./new_data").load_data()
for doc in new_docs:
index.insert(doc)
index.storage_context.persist(persist_dir="./index_storage")
Les anciens vecteurs ne sont pas recalculés. Seuls les nouveaux documents sont embeddés.
4. Query Engine et Retriever — Quelle différence ?
| Concept | Que fait-il | Retourne |
|---|---|---|
| Retriever | Trouve les chunks pertinents | Chunk + score de similarité |
| Query Engine | Retrieval + synthèse LLM | Réponse générée |
Query Engine personnalisé
from llama_index.core.query_engine import RetrieverQueryEngine
from llama_index.core.retrievers import VectorRetriever
from llama_index.core.postprocessor import KeywordNodePostprocessor
retriever = VectorRetriever(
index=index,
top_k=10,
filters=KeywordNodePostprocessor(required_keywords=["déploiement"])
)
query_engine = RetrieverQueryEngine.from_args(
retriever=retriever,
llm=your_llm,
response_mode="compact"
)
response = query_engine.query("Comment déployer en production ?")
Retriever seul (chunks bruts, pas de LLM)
retriever = VectorRetriever(index=index, top_k=5)
chunks = retriever.retrieve("configuration VPS")
for chunk in chunks:
print(chunk.node.get_text()[:200])
print(f"Score: {chunk.score}")
5. Intégrer LlamaIndex dans un agent IA
LlamaIndex s'intègre en tant qu'outil (tool) dans un agent. L'agent interroge le query engine quand la question relève de la base de connaissances.
Dans un agent Python custom
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.core.tools import QueryEngineTool, ToolMetadata
# 1. Construire l'index au startup (une seule fois)
documents = SimpleDirectoryReader("./knowledge_base").load_data()
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine(top_k=5)
# 2. Exposer comme tool
llamaindex_tool = QueryEngineTool(
query_engine=query_engine,
metadata=ToolMetadata(
name="knowledge_base",
description=(
"Répondre aux questions sur la documentation interne, "
"guides techniques et procédures. "
"Ne PAS utiliser pour des questions générales."
),
)
)
# 3. L'agent decide quand utiliser ce tool
# tools = [llamaindex_tool, search_tool, calculator_tool, …]
Convention : une description de tool précise = un agent qui l'utilise à bon escient. Évitez les descriptions vagues.
Dans OpenClaw via agent-vector-memory
OpenClaw supporte LlamaIndex nativement via le skill agent-vector-memory. Configuration dans le fichier de skills :
{
"provider": "llamaindex",
"index_type": "VectorStoreIndex",
"persist_dir": "./data/index_storage",
"chunk_size": 512,
"chunk_overlap": 128
}
L'agent interroge automatiquement la base quand une requête correspond à votre domaine.
🚀 Prêt à monter un agent de support avec LlamaIndex ? La section suivante montre un exemple complet avec Pinecone en production.
6. Optimiser la qualité du RAG
Un RAG mal calibré est pire que pas de RAG : réponses hors sujet, contexte contradictoire, latence excessive.
Chunk size — guide de démarrage
| Chunk size | Overlap | Cas d'usage |
|---|---|---|
| 256 / 32 | Petit | FAQ, faits ponctuels, questions précises |
| 512 / 128 | Moyen | Documentation technique, articles |
| 1024 / 256 | Grand | Documents longs avec contexte narratif |
Commencez à 512/128. Ajustez selon le taux d'erreur sur vos cas de test.
Reranking — affiner après retrieval
La similarité cosinus est rapide mais approximative. Un reranker cross-encoder affine le classement :
from llama_index.core.postprocessor import SentenceTransformerRerank
query_engine = index.as_query_engine(
similarity_top_k=20,
node_postprocessors=[
SentenceTransformerRerank(
model="cross-encoder/ms-marco-MiniLM-L-12-v2",
top_n=5,
)
]
)
Hybrid search — vectoriel + keyword
La recherche purement vectorielle peut rater des termes techniques (noms de fonctions, acronymes). Combinez similarité sémantique + BM25 :
from llama_index.core.retrievers import BM25Retriever, QueryFusionRetriever
vector_retriever = VectorRetriever(index=index, top_k=5)
bm25_retriever = BM25Retriever.from_defaults(nodes=nodes, top_k=5)
fusion_retriever = QueryFusionRetriever(
retrievers=[vector_retriever, bm25_retriever],
mode="rrf", # Reciprocal Rank Fusion
top_k=5,
)
Évaluation continue — intégrer à votre CI
from llama_index.core.evaluation import QueryResponseEvaluator
evaluator = QueryResponseEvaluator()
result = evaluator.evaluate(
query="Comment configurer le monitoring ?",
response=response,
contexts=[n.node.get_text() for n in retrieved_nodes],
)
print(f"Score de fidélité : {result.score}")
Sans métriques, vous ne savez pas si votre RAG s'améliore. Ajoutez l'évaluation à votre pipeline CI.
7. Exemple complet — Agent de support technique
Contexte : 200 pages de documentation interne (PDF, Notion, Confluence). Objectif : un agent qui répond aux équipes support en < 10 secondes.
Stack : LlamaIndex + GPT-4o + Pinecone comme vectore store.
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.vector_stores.pinecone import PineconeVectorStore
from llama_index.core.storage import StorageContext
from llama_index.core.tools import QueryEngineTool, ToolMetadata
from pinecone import Pinecone
import os
# 1. Charger la doc
documents = SimpleDirectoryReader("./docs/support").load_data()
# 2. Connecter à Pinecone
pc = Pinecone(api_key=os.getenv("PINECONE_API_KEY"))
pinecone_index = pc.Index("support-knowledge-base")
vector_store = PineconeVectorStore(pinecone_index=pinecone_index)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
# 3. Construire et persister l'index dans Pinecone
index = VectorStoreIndex.from_documents(documents, storage_context=storage_context)
# 4. Query engine
query_engine = index.as_query_engine(llm=your_llm, top_k=5, response_mode="compact")
# 5. Exposer comme tool dans l'agent
support_kb_tool = QueryEngineTool(
query_engine=query_engine,
metadata=ToolMetadata(
name="support_knowledge_base",
description=(
"Base de connaissances support technique. "
"Questions sur procédures, erreurs connues, configuration, dépannage."
),
)
)
Résultat : temps de première réponse technique = 8 secondes (vs 4 minutes en recherche manuelle).
8. Bonnes pratiques
- top_k bas : 5-10 chunks suffisent. Plus = overflow du contexte, qualité dégradée.
- Métadonnées : author, date, catégorie, produit — utilisez-les pour filtrer lors du retrieval.
- Reconstruire l'index régulièrement : un index obsolète avec liens cassés ou processus erronés est pire que pas d'index. Automatisez avec un cron.
- Pas d'in-memory en production : toujours
persist()ou un vectore store managé (Pinecone, Weaviate, Chroma).
FAQ
LlamaIndex vs LangChain — lequel choisir pour le RAG ?
LlamaIndex est spécialisé RAG : chaque composant fait une chose. LangChain est un framework plus large (chaining, agents, multi-outils). Pour du RAG pur → LlamaIndex (plus léger, plus direct). Pour un agent complet avec gestion de conversation → OpenClaw ou LangChain.
LlamaIndex est-il gratuit ?
Oui — open source, licence MIT. Le package llama-index-core est gratuit. Les coûts = infrastructure (calcul embeddings, appels LLM) + vectore store managé.
Peut-on utiliser LlamaIndex sans OpenAI ?
Oui. LlamaIndex est agnostique du LLM. Utilisez Claude, Gemini, Mistral, Groq ou Ollama en local via le protocole LiteLLM.
Comment gérer les documents de 200+ pages ?
Découpez avec SentenceSplitter (chunk_size 512-1024, overlap aktiviert). Si le document a une structure (titres, sections), utilisez SemanticSplitterNodeParser qui coupe aux frontières sémantiques.
Articles liés
Restez informé sur les agents IA
Nouveaux tutoriels, comparatifs et guides pratiques directement dans votre boîte mail.