Intermédiaire 11 minStack

LlamaIndex en pratique

Réponse directe

LlamaIndex est un framework Python qui gère toute la chaîne d'un RAG : chargement des documents, découpage, embeddings, index, requêtes avec sources. En local, il se branche sur Ollama et sur des embeddings comme BGE-M3, mais ses défauts appellent OpenAI : définissez Settings.llm et Settings.embed_model avant d'indexer, et réglez context_window et request_timeout.

LlamaIndex réduit un RAG à quelques lignes, mais ses valeurs par défaut (OpenAI, fenêtre de contexte, délai de 30 secondes) piègent les installations locales, et les anciens tutoriels d'agents ne fonctionnent plus. Vous saurez monter un pipeline entièrement local, choisir un mode de requête, ajouter un reranker et écrire un agent avec l'API actuelle.

Par Mohamed Meguedmi·Màj 2026-09-30·Testé sur Windows, macOS, Linux

#LlamaIndex en pratique : à quoi sert-il, et quand l'adopter

LlamaIndex est un framework Python qui prend en charge toute la chaîne d'un RAG : charger des documents, les découper en morceaux (nodes), les transformer en vecteurs, les indexer, puis interroger l'index avec un LLM qui cite ses sources. La version 0.14.25, publiée sur PyPI le 21 septembre 2026, demande Python 3.10 ou plus. Un RAG minimal tient en une dizaine de lignes ; le framework prend son intérêt quand il faut varier les sources, changer de mode de réponse, ajouter un reranker ou brancher un agent. En local, il fonctionne avec Ollama pour le LLM et un modèle d'embeddings de votre choix, à condition de désactiver ses réglages par défaut, qui appellent OpenAI. Ce guide monte un RAG entièrement local, montre les réglages qui comptent et corrige plusieurs exemples périmés que l'on trouve encore en ligne.

Abstractions claires
Document, Node, VectorStoreIndex, retriever, query engine : chaque étape du RAG a un objet dédié, remplaçable.
Connecteurs de données
SimpleDirectoryReader lit PDF, Word, PowerPoint, Markdown, images ou audio ; d'autres lecteurs couvrent Notion, Google Docs, Slack ou Discord.
Modes de requête
Plusieurs stratégies de synthèse et des moteurs plus élaborés (sous-questions, routage entre index) pour dépasser la simple recherche vectorielle.
Local possible
Ollama et les embeddings Hugging Face ou Ollama se branchent via des paquets d'intégration dédiés.

#Les étapes d'un RAG LlamaIndex et leurs réglages par défaut

Le kit RAG Local

Tes documents, ton IA : un RAG local fiable sur tes PDF, notes et mails — sans rien envoyer dans le cloud.

  • Espace en ligne à vie
  • PDF + fichiers
  • Mises à jour à vie

Avant d'écrire du code, retenez le pipeline et surtout ses valeurs par défaut : c'est là que se cachent la plupart des surprises en local.

Pipeline LlamaIndex : objets et défauts
ÉtapeObjet ou réglageValeur par défaut à connaître
DécoupageSentenceSplitter, Settings.chunk_size1 024 tokens de taille, 20 de chevauchement
EmbeddingsSettings.embed_modeltext-embedding-ada-002 d'OpenAI, d'après la documentation
LLMSettings.llmgpt-3.5-turbo d'OpenAI, d'après le tutoriel de démarrage
StockageVectorStoreIndex, StorageContextEn mémoire ; à persister explicitement sur disque
Synthèseresponse_modecompact : concatène autant de chunks que la fenêtre le permet
LLM Ollamarequest_timeout30 secondes par défaut, souvent trop court en local
!
Sans configuration, LlamaIndex appelle OpenAI
La documentation précise que LlamaIndex utilise par défaut l'API d'OpenAI pour le LLM et les embeddings. Avec une clé OPENAI_API_KEY présente dans l'environnement, vos documents seraient donc envoyés à OpenAI pour être vectorisés, sans message d'alerte. Pour un RAG confidentiel, définissez toujours Settings.llm et Settings.embed_model avant d'indexer, comme dans la section suivante.

#Installation pour un RAG 100 % local

La commande pip install llama-index installe un lot de démarrage qui contient llama-index-core, les intégrations OpenAI pour le LLM et les embeddings, et les lecteurs de fichiers. Pour le local, ajoutez les intégrations Ollama et d'embeddings (llama-index-embeddings-ollama si vous préférez OllamaEmbedding) ; les paquets OpenAI du lot restent installés mais inutilisés tant que vous configurez Settings.

Terminal
pip install llama-index \
            llama-index-llms-ollama \
            llama-index-embeddings-huggingface

ollama pull mistral

Le nom d'un paquet donne l'import : llama-index-llms-ollama correspond à llama_index.llms.ollama. Côté mémoire, comptez les poids du LLM (environ 5 Go pour un 7-8B en Q4, repère du site), le modèle d'embeddings et le contexte : un poste de 16 Go convient à un petit corpus, davantage donne de la marge.

#Un RAG en dix lignes (avec ses réglages OpenAI par défaut)

Python
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader

docs = SimpleDirectoryReader("./docs").load_data()
index = VectorStoreIndex.from_documents(docs)

query = index.as_query_engine()
print(query.query("Résume les points clés du contrat X"))

Ce code est valide, mais il utilise les modèles par défaut d'OpenAI : il échoue sans clé, et avec une clé il envoie vos textes chez le fournisseur. Il sert de squelette. La section suivante ajoute les quelques lignes qui le rendent local.

#Passer en local avec Ollama et des embeddings français

Trois blocs de configuration suffisent : le LLM, le modèle d'embeddings et le découpage. Pour le français, BGE-M3 est un choix courant : sa fiche indique plus de 100 langues et des entrées jusqu'à 8 192 tokens. Le téléchargement du modèle pèse environ 2,3 Go (fichier pytorch_model.bin du dépôt Hugging Face), et il se fait une seule fois.

Python
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
from llama_index.llms.ollama import Ollama
from llama_index.embeddings.huggingface import HuggingFaceEmbedding

# Configuration globale : tout est local
Settings.llm = Ollama(
    model="mistral",
    base_url="http://localhost:11434",
    request_timeout=120.0,   # le défaut est de 30 s
    context_window=8000,     # transmis à Ollama comme num_ctx
)
Settings.embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-m3")
Settings.chunk_size = 700
Settings.chunk_overlap = 100

# Pipeline
docs = SimpleDirectoryReader("./docs").load_data()
index = VectorStoreIndex.from_documents(docs, show_progress=True)

# Persister sur disque
index.storage_context.persist(persist_dir="./storage")

# Requêter
query_engine = index.as_query_engine(similarity_top_k=5)
reponse = query_engine.query("Quels sont les risques identifiés ?")
print(reponse)
for src in reponse.source_nodes:
    print(f"  - {src.metadata.get('file_name')} ({src.score:.2f})")
Python
from llama_index.core import load_index_from_storage, StorageContext

storage = StorageContext.from_defaults(persist_dir="./storage")
index = load_index_from_storage(storage)

#Pourquoi context_window et request_timeout comptent

Le code source de l'intégration Ollama de LlamaIndex transmet la valeur de context_window à Ollama sous le nom num_ctx. Sans cela, Ollama applique sa fenêtre par défaut, de 4 000 tokens environ sous 24 Gio de VRAM d'après sa documentation. Le calcul est vite fait : cinq passages de 700 tokens représentent 3 500 tokens, avant la question, les consignes du modèle de prompt et la réponse. Avec 4 000 tokens, le prompt déborde et le contexte est tronqué, souvent sans erreur visible. Avec 8 000, la marge existe.

Le délai est l'autre piège : le client Ollama de LlamaIndex fixe 30 secondes par défaut. Un premier appel qui charge le modèle en mémoire et traite un long prompt peut le dépasser. Les 120 secondes de l'exemple sont un point de départ à ajuster selon votre matériel.

→
Embeddings via Ollama plutôt que Hugging Face
Si vous ne voulez pas installer PyTorch pour les embeddings, LlamaIndex propose OllamaEmbedding : il utilise le serveur Ollama déjà lancé, avec un modèle d'embeddings tiré par ollama pull. La bibliothèque Ollama propose bge-m3. Un changement de modèle d'embeddings impose de réindexer tous les documents, car les vecteurs de deux modèles ne sont pas comparables.

#Charger vos fichiers : réglages de SimpleDirectoryReader

SimpleDirectoryReader lit un dossier entier et gère de nombreux formats : PDF, Word, PowerPoint, Markdown, images, audio et vidéo. Quelques paramètres évitent d'indexer n'importe quoi.

Python
from llama_index.core import SimpleDirectoryReader

docs = SimpleDirectoryReader(
    input_dir="./docs",
    required_exts=[".pdf", ".docx"],  # ne charger que ces formats
    num_files_limit=100,              # plafond pour un premier essai
).load_data()

Les connecteurs vers des services (Notion, Google Docs, Slack, Discord) vont chercher les données en ligne : c'est inévitable, puisqu'elles y résident. Une fois les documents chargés, l'indexation et l'interrogation restent locales, avec vos embeddings et votre LLM Ollama. Faites un premier essai sur quelques fichiers : un PDF scanné sans couche de texte ne donnera rien tant qu'il n'est pas passé par un OCR, comme le décrit le guide Tesseract.

#Choisir un mode de requête et le coût en appels LLM

Le mode de synthèse détermine combien de fois le LLM est appelé, donc le temps de réponse local. Le tableau reprend les modes documentés et leur coût, avec un exemple à cinq passages de 700 tokens et une fenêtre de 8 000 tokens (estimation).

Modes de réponse et nombre d'appels au LLM
ModePrincipe (documentation)Appels dans l'exemple
compact (défaut)Concatène autant de chunks que la fenêtre le permet, puis interroge1 appel : 3 500 tokens rentrent dans 8 000
refineParcourt les chunks un par un, avec un appel par chunk5 appels, à la suite
tree_summarizeInterroge par groupes, puis résume récursivement les réponses1 appel si tout tient dans la fenêtre, sinon plusieurs, puis un résumé final
simple_summarizeTronque tout pour tenir dans un seul prompt1 appel, avec perte de détail
no_textN'exécute que le retriever, sans appeler le LLM0 appel ; utile pour déboguer la recherche

Pour une question factuelle, gardez compact. Pour résumer un long document, tree_summarize est prévu, au prix de plusieurs appels : sur une machine locale, prévoyez plusieurs fois la durée d'une réponse simple. no_text est précieux pour vérifier ce que la recherche ramène, sans attendre le LLM.

#Ajouter un reranker local

Quand la bonne réponse est dans les 20 premiers passages mais pas dans les 5 premiers, un reranker réordonne les candidats avant l'envoi au LLM. La documentation de LlamaIndex recommande, comme défaut sans clé API et exécuté localement, SentenceTransformerRerank, un cross-encoder via sentence-transformers, et cite Qwen3-Reranker-0.6B pour une meilleure qualité multilingue.

Python
from llama_index.core.postprocessor import SentenceTransformerRerank

reranker = SentenceTransformerRerank(
    model="cross-encoder/ms-marco-MiniLM-L2-v2",
    top_n=3,
)
query_engine = index.as_query_engine(
    similarity_top_k=15,             # large pour rattraper la bonne réponse
    node_postprocessors=[reranker],  # puis resserre à 3
)

Le modèle donné ici est celui de l'exemple officiel, choisi pour sa rapidité ; il est conçu pour l'anglais : pour des documents français, testez un reranker multilingue. Le guide dédié détaille le choix et l'évaluation.

#Sous-questions et routage

SubQuestionQueryEngine
Décompose une question complexe en sous-questions envoyées à des outils de requête, puis synthétise. « Compare les stratégies 2024 et 2025 » devient deux recherches séparées.
RouterQueryEngine
Choisit, pour chaque question, le bon moteur parmi plusieurs (par exemple un index de résumés ou un index vectoriel).

Ces deux moteurs multiplient les appels au LLM : une décomposition en trois sous-questions ajoute la génération des sous-questions, trois réponses et la synthèse finale, soit au moins cinq appels. Sur du matériel local, réservez-les aux questions qui le justifient.

#Agents : l'API actuelle n'est plus celle des anciens tutoriels

Beaucoup de tutoriels utilisent ReActAgent.from_tools. Cette classe n'existe plus dans les sources actuelles : le module agent/react/base.py qui la portait a disparu du dépôt. Les agents sont désormais des workflows asynchrones : FunctionAgent (un agent qui appelle des fonctions ou outils), ReActAgent version workflow, et AgentWorkflow pour orchestrer plusieurs agents. Le tutoriel local officiel construit l'agent avec AgentWorkflow.from_tools_or_functions et l'exécute avec await agent.run.

Python
import asyncio
from llama_index.core import Settings
from llama_index.core.agent.workflow import AgentWorkflow

async def search_documents(query: str) -> str:
    """Répond aux questions sur les contrats clients."""
    response = await query_engine.aquery(query)
    return str(response)

agent = AgentWorkflow.from_tools_or_functions(
    [search_documents],
    llm=Settings.llm,
    system_prompt="Tu réponds uniquement à partir des contrats indexés.",
)

async def main():
    reponse = await agent.run("Y a-t-il une clause de non-concurrence chez Acme Corp ?")
    print(str(reponse))

asyncio.run(main())

Le nom, la description et les arguments de la fonction (sa docstring) sont transmis au LLM, qui choisit s'il doit l'appeler : soignez donc cette description. Le fonctionnement de FunctionAgent repose sur des appels de fonctions natifs ; avec un modèle local, choisissez un modèle qui prend en charge les outils dans Ollama, et gardez le RAG simple si le vôtre n'en est pas capable.

#LlamaIndex, LangChain ou RAG maison : comment choisir

Trois approches pour un RAG local
CritèreRAG maison (ChromaDB, embeddings)LlamaIndexLangChain
Objectif principalComprendre chaque étape, contrôle totalPipeline documentaire avec composants prêtsOrchestration d'outils et d'agents
Temps de mise en routePlus long : tout est à écrireCourt pour un premier RAGCourt pour une chaîne, plus long pour un RAG complet
PersonnalisationIllimitée, à vos fraisRéglages par composants, objets remplaçablesTrès flexible, plus verbeux
Risque principalRéinventer un pipeline existantDéfauts OpenAI, API qui évolue viteAPI qui évolue vite

Règle pratique : un RAG documentaire avec sources citées, des formats variés et quelques options de requête se construit vite avec LlamaIndex. Si vous voulez d'abord comprendre le mécanisme, écrivez la version maison une fois : le guide ChromaDB montre les étapes. Pour un agent qui pilote de nombreux outils externes, LangChain ou les workflows de LlamaIndex se comparent selon vos habitudes.

#Les pièges qui coûtent du temps

Réindexer à chaque exécution
Sans persist, l'index est en mémoire et disparaît à la fermeture du script. Persistez, puis rechargez avec load_index_from_storage.
Changer de modèle sans réindexer
Les vecteurs de deux modèles d'embeddings ne sont pas comparables : modifier embed_model ou le découpage impose de reconstruire l'index.
Contexte tronqué en silence
Un prompt plus long que la fenêtre d'Ollama est coupé : vérifiez context_window si les réponses ignorent les derniers passages.
Copier un ancien tutoriel
Les API d'agents ont changé : vérifiez que les imports d'un exemple existent dans la version installée (0.14.25 au moment de la rédaction).
Ne jamais mesurer
Un RAG sans évaluation dérive sans que vous le sachiez : le guide Ragas montre comment le chiffrer.
FAQ
LlamaIndex fonctionne-t-il entièrement en local ?+
Oui, à condition de définir Settings.llm (par exemple Ollama) et Settings.embed_model (Hugging Face ou Ollama) avant d'indexer. Sans cela, la documentation indique que LlamaIndex utilise par défaut les modèles d'OpenAI. Seuls les connecteurs vers des services en ligne, comme Notion ou Slack, sortent forcément de la machine pour récupérer les données.
Quel modèle d'embeddings choisir pour des documents en français ?+
BGE-M3 est un choix courant : sa fiche annonce plus de 100 langues, des entrées jusqu'à 8 192 tokens, et un téléchargement d'environ 2,3 Go. Les repères varient selon vos documents : testez-le sur vos propres questions avant de généraliser, et consultez le guide des embeddings français pour comparer les alternatives.
Pourquoi mon RAG LlamaIndex oublie-t-il des passages ?+
Souvent parce que le contexte est tronqué : Ollama applique par défaut environ 4 000 tokens sous 24 Gio de VRAM, et cinq passages de 700 tokens en occupent déjà 3 500. Fixez context_window dans l'objet Ollama, augmentez la mémoire disponible si nécessaire ou réduisez similarity_top_k.
Comment éviter de réindexer à chaque lancement ?+
Persistez l'index avec index.storage_context.persist(persist_dir="./storage"), puis rechargez-le avec StorageContext.from_defaults et load_index_from_storage. Par défaut, LlamaIndex garde les données en mémoire et les perd à la fermeture du script. Si vous changez de modèle d'embeddings ou de taille de chunk, les vecteurs calculés changent : il faut alors reconstruire l'index, puis le persister de nouveau.
ReActAgent.from_tools ne fonctionne plus, que faire ?+
Cette API des anciens tutoriels a disparu des sources actuelles. Utilisez les agents workflow : AgentWorkflow.from_tools_or_functions ou FunctionAgent, avec des fonctions asynchrones et await agent.run. Vérifiez que votre modèle Ollama prend en charge les outils ; sinon, gardez un RAG simple sans agent, ou testez le ReActAgent workflow, qui n'exige pas l'appel de fonctions natif.
LlamaIndex ou LangChain pour un RAG local ?+
LlamaIndex est centré sur les données et le RAG : chargement, index, modes de requête. LangChain se concentre sur l'orchestration d'outils et d'agents. Pour discuter avec vos documents, LlamaIndex démarre plus vite ; pour un agent multi-outils, comparez les deux sur un cas réel et gardez celui dont vous maîtrisez l'API.
Ce guide vous a aidé ?

Un retour, une erreur, une précision ? Faites-nous signe, ça améliore le guide pour tout le monde.