D-OPEN

Comment deployer un pipeline RAG open source avec LlamaIndex en 7 etapes

Clara Petersen

Clara Petersen

Ingenieure MLOps et architecte RAG · 3 juin 2026 · 12 min de lecture

TL;DR

  • Le RAG (Retrieval-Augmented Generation) permet a un LLM de repondre a des questions sur vos propres documents sans fine-tuning. LlamaIndex est le framework open source de reference pour construire ces pipelines.
  • 7 etapes : ingestion de documents, chunking intelligent, generation d'embeddings, stockage dans un vector store, retrieval semantique, generation augmentee, evaluation et monitoring.
  • Budget : 200 a 500 EUR/mois pour un pipeline complet avec modele open source. 500 a 2 000 EUR/mois avec une API proprietaire.
  • Delai : 1 a 2 semaines du prototype au deploiement production pour un corpus de 50 000 documents.

Le RAG est devenu le pattern dominant pour construire des applications IA en entreprise en 2026. Au lieu de fine-tuner un modele (couteux, lent, et fragile), vous recuperez les documents pertinents au moment de la requete et les injectez dans le prompt. Le modele repond en se basant sur vos donnees, pas sur son entrainement. C'est simple en theorie. En pratique, passer d'un prototype Jupyter a un pipeline production qui gere 50 000 documents et 1 000 requetes par jour avec un taux de precision de 95 pourcent, c'est autre chose. Ce guide couvre les 7 etapes exactes que nous utilisons chez D-Open pour deployer des pipelines RAG en production avec LlamaIndex.

ARCHITECTURE PIPELINE RAG AVEC LLAMAINDEX1. IngestionPDF, Notion,SQL, API2. ChunkingSemantic512-1024 tokens3. Embeddingstext-embedding-3-large4. Vector DBQdrant /ChromaDBQUERY TIME5. RetrievalTop-K + RerankHybrid search6. GenerationLLM + contexteretrieves7. EvaluationFaithfulness | Relevance | LatenceRequeteStack recommandee :LlamaIndex 0.12 + Qdrant + vLLMou Claude API / Mistral API en alternativeMetriques cibles production :Faithfulness > 0.90 | Latence P95 < 3sRelevance > 0.85 | Throughput > 50 req/min

Etape 1 — Ingerer vos documents avec les connecteurs LlamaIndex

La premiere etape est de connecter LlamaIndex a vos sources de donnees. Le framework offre plus de 300 connecteurs (appeles « Readers ») pour ingerer des PDF, des pages Notion, des bases SQL, des fichiers Markdown, des pages web, des repos GitHub, et bien plus. La cle est de choisir le bon connecteur pour chaque source et de normaliser le format de sortie.

# Installation
pip install llama-index llama-index-readers-file \
    llama-index-vector-stores-qdrant \
    llama-index-embeddings-openai \
    llama-index-llms-openai

# Ingestion de documents PDF + Markdown
from llama_index.core import SimpleDirectoryReader

# Charger tous les documents d un dossier
documents = SimpleDirectoryReader(
    input_dir="./data/knowledge-base",
    recursive=True,
    required_exts=[".pdf", ".md", ".txt", ".docx"],
    filename_as_id=True,
).load_data()

print(f"Documents charges : {len(documents)}")
# Documents charges : 847

# Pour Notion
from llama_index.readers.notion import NotionPageReader

notion_reader = NotionPageReader(integration_token="secret_xxx")
notion_docs = notion_reader.load_data(
    database_id="votre-database-id"
)

# Fusionner toutes les sources
all_documents = documents + notion_docs

Point important : chaque document doit avoir un identifiant unique (doc_id) et des metadonnees pertinentes (source, date, categorie). Ces metadonnees seront utilisees plus tard pour le filtrage au moment du retrieval. Ne sautez pas cette etape : un index sans metadonnees, c'est un classeur sans etiquettes.

Etape 2 — Decouper intelligemment avec le chunking semantique

Le chunking est l'etape la plus sous-estimee du pipeline RAG, et pourtant c'est celle qui a le plus d'impact sur la qualite des reponses. Un mauvais chunking (trop grand, trop petit, ou qui coupe au milieu d'une idee) produit des reponses mediocres, peu importe la qualite de votre modele de generation.

LlamaIndex propose trois strategies principales de chunking. Le chunking fixe (SentenceSplitter) decoupe par nombre de tokens avec un overlap. Simple mais brutal. Le chunking semantique (SemanticSplitterNodeParser) utilise les embeddings pour detecter les changements de sujet et decouper aux frontieres naturelles du texte. C'est notre recommandation par defaut. Le chunking hierarchique (HierarchicalNodeParser) cree des chunks a plusieurs niveaux de granularite (paragraphe, section, document) pour le retrieval multi-echelle.

from llama_index.core.node_parser import (
    SentenceSplitter,
    SemanticSplitterNodeParser,
)
from llama_index.embeddings.openai import OpenAIEmbedding

# Option 1 : Chunking fixe (baseline)
splitter_fixe = SentenceSplitter(
    chunk_size=512,
    chunk_overlap=50,
)

# Option 2 : Chunking semantique (recommande)
embed_model = OpenAIEmbedding(model="text-embedding-3-large")
splitter_semantic = SemanticSplitterNodeParser(
    buffer_size=1,
    breakpoint_percentile_threshold=95,
    embed_model=embed_model,
)

# Generer les nodes (chunks)
nodes = splitter_semantic.get_nodes_from_documents(all_documents)
print(f"Nodes generes : {len(nodes)}")
# Nodes generes : 4 231 (pour 847 documents)

Regle empirique : visez des chunks de 512 a 1 024 tokens pour la plupart des cas d'usage. En dessous de 256, vous perdez trop de contexte. Au-dessus de 2 048, le retrieval devient moins precis car chaque chunk couvre trop de sujets. Le chunking semantique produit generalement des chunks de taille variable entre 300 et 800 tokens, ce qui est ideal.

Etape 3 — Generer les embeddings et choisir le bon modele

Les embeddings transforment vos chunks de texte en vecteurs numeriques qui capturent le sens semantique. Deux chunks qui parlent du meme sujet auront des vecteurs proches dans l'espace vectoriel, meme s'ils utilisent des mots differents. C'est le coeur du retrieval semantique.

En juin 2026, trois options dominent le marche. OpenAI text-embedding-3-large (3072 dimensions) offre le meilleur rapport qualite/cout pour la plupart des cas d'usage. Voyage AI voyage-3-large est specialise pour les documents techniques et surpasse OpenAI sur les benchmarks code et documentation. BGE-M3 (open source, BAAI) est la meilleure option gratuite et self-hosted, avec des performances 5 a 8 pourcent en dessous des modeles proprietaires mais zero cout d'API.

from llama_index.embeddings.openai import OpenAIEmbedding

# Option 1 : OpenAI (recommande pour la plupart des cas)
embed_model = OpenAIEmbedding(
    model="text-embedding-3-large",
    dimensions=1536,  # Reduire de 3072 a 1536 pour economiser du stockage
)

# Option 2 : Open source avec HuggingFace
from llama_index.embeddings.huggingface import HuggingFaceEmbedding

embed_model_os = HuggingFaceEmbedding(
    model_name="BAAI/bge-m3",
    device="cuda",  # GPU pour la vitesse
)

# Generer les embeddings pour tous les nodes
from llama_index.core.ingestion import IngestionPipeline

pipeline = IngestionPipeline(
    transformations=[
        splitter_semantic,
        embed_model,
    ],
)

nodes_with_embeddings = pipeline.run(documents=all_documents)
print(f"Embeddings generes : {len(nodes_with_embeddings)}")
# Embeddings generes : 4 231

Astuce cout : OpenAI facture les embeddings a environ 0.13 USD pour 1 million de tokens. Pour 50 000 documents de 1 000 tokens chacun, l'indexation initiale coute environ 6.50 USD. C'est negligeable. Le vrai cout, c'est le re-indexation quand vos documents changent. Mettez en place un systeme incremental qui ne re-indexe que les documents modifies.

Etape 4 — Stocker dans un vector store avec Qdrant

Le vector store est la base de donnees specialisee qui stocke vos embeddings et permet le retrieval par similarite semantique. C'est un composant critique : il doit etre rapide (latence inferieure a 50ms pour une recherche sur 1 million de vecteurs), fiable (persistant, avec backup), et filtrable (par metadata pour le multi-tenancy et le controle d'acces).

Notre recommandation pour la production : Qdrant. C'est un vector store open source (Apache 2.0), ecrit en Rust pour la performance, avec un excellent support des filtres metadata, du multi-tenancy, et du clustering. Il se deploie en Docker en 5 minutes et tourne confortablement sur une VM a 30 EUR/mois pour des corpus de moins de 500 000 vecteurs.

# Lancer Qdrant en Docker
# docker run -p 6333:6333 -v ./qdrant_data:/qdrant/storage qdrant/qdrant

from qdrant_client import QdrantClient
from llama_index.vector_stores.qdrant import QdrantVectorStore
from llama_index.core import StorageContext, VectorStoreIndex

# Connexion au vector store
client = QdrantClient(host="localhost", port=6333)

vector_store = QdrantVectorStore(
    client=client,
    collection_name="knowledge_base",
    enable_hybrid=True,  # Recherche hybride dense + sparse
)

storage_context = StorageContext.from_defaults(
    vector_store=vector_store,
)

# Creer l index a partir des nodes
index = VectorStoreIndex(
    nodes=nodes_with_embeddings,
    storage_context=storage_context,
    embed_model=embed_model,
)

print("Index cree et persiste dans Qdrant")
# Collection 'knowledge_base' : 4 231 vecteurs, 1536 dimensions

Multi-tenancy : si votre application sert plusieurs clients, utilisez les metadata Qdrant pour isoler les donnees. Ajoutez un champ tenant_id a chaque vecteur et filtrez au moment du retrieval. Cela evite d'avoir a creer une collection separee par client, ce qui simplifie l'infrastructure.

Un projet RAG en production ?

D-Open accompagne les equipes techniques dans le deploiement de pipelines RAG sur mesure, de l'architecture au monitoring.

Recevez votre devis en 24h

Etape 5 — Configurer le retrieval avec re-ranking et recherche hybride

Le retrieval est le moment ou votre pipeline brille ou s'effondre. Une requete utilisateur arrive, elle est transformee en embedding, et le vector store retourne les chunks les plus similaires. Mais la similarite vectorielle brute ne suffit pas en production : vous avez besoin de re-ranking et de recherche hybride pour atteindre une precision de 90 pourcent et plus.

La recherche hybride combine la recherche dense (embeddings, semantique) avec la recherche sparse (BM25, mots-cles). Cela garantit que vous retrouvez les documents pertinents meme quand la requete contient des termes techniques specifiques (noms de produits, codes, acronymes) que les embeddings peuvent manquer.

Le re-ranking prend les Top-K resultats (typiquement 20 a 50) et les re-ordonne avec un modele de cross-encoder plus precis mais plus lent. Le resultat : les 5 meilleurs chunks sont veritablement les plus pertinents, pas juste les plus proches en distance cosinus.

from llama_index.core.retrievers import VectorIndexRetriever
from llama_index.core.postprocessor import (
    SentenceTransformerRerank,
    MetadataReplacementPostProcessor,
)

# Retriever de base : Top-20 par similarite
retriever = VectorIndexRetriever(
    index=index,
    similarity_top_k=20,
    vector_store_query_mode="hybrid",  # Dense + Sparse
    alpha=0.7,  # 70% dense, 30% sparse
)

# Re-ranker : reduit de 20 a 5 avec un cross-encoder
reranker = SentenceTransformerRerank(
    model="cross-encoder/ms-marco-MiniLM-L-12-v2",
    top_n=5,
)

# Pipeline de retrieval complet
from llama_index.core.query_engine import RetrieverQueryEngine
from llama_index.llms.openai import OpenAI

llm = OpenAI(model="gpt-4o", temperature=0.1)

query_engine = RetrieverQueryEngine.from_args(
    retriever=retriever,
    node_postprocessors=[reranker],
    llm=llm,
    response_mode="tree_summarize",
)

# Tester une requete
response = query_engine.query(
    "Quelles sont les obligations RGPD pour le traitement de donnees IA ?"
)
print(response.response)
print(f"Sources utilisees : {len(response.source_nodes)}")
# Sources utilisees : 5

Parametrage cle : le ratio alpha entre recherche dense et sparse depend de votre corpus. Pour des documents techniques avec beaucoup de jargon, montez le sparse a 40-50 pourcent. Pour du contenu general, 20-30 pourcent de sparse suffit. Testez avec votre jeu de donnees d'evaluation (etape 7) pour trouver le ratio optimal.

Etape 6 — Configurer la generation augmentee avec prompts optimises

La generation est l'etape ou le LLM synthetise une reponse a partir des chunks retrieves. La qualite de la reponse depend de trois facteurs : la qualite du retrieval (etapes precedentes), le choix du modele de generation, et la conception du prompt systeme.

Pour le modele de generation, vous avez deux options. API proprietaire (Claude, GPT-4o, Gemini) : zero infrastructure, haute qualite, cout variable. Modele open source via vLLM (Llama 4, Mistral Medium, Qwen 3) : infrastructure a gerer mais cout fixe et souverainete des donnees. Pour un pipeline RAG en production en France, on recommande generalement de commencer avec une API proprietaire pour valider le use case, puis de migrer vers un modele self-hosted quand le volume justifie l'investissement infrastructure.

from llama_index.core import PromptTemplate

# Prompt systeme optimise pour le RAG
QA_TEMPLATE = PromptTemplate(
    """Vous etes un assistant expert. Repondez a la question en utilisant
UNIQUEMENT les informations fournies dans le contexte ci-dessous.

Regles :
- Si le contexte ne contient pas l information, dites-le clairement.
- Citez vos sources en referençant le nom du document.
- Repondez en francais, de maniere structuree et precise.
- Ne fabriquez JAMAIS d information non presente dans le contexte.

Contexte :
{context_str}

Question : {query_str}

Reponse :"""
)

# Appliquer le prompt au query engine
query_engine.update_prompts({
    "response_synthesizer:text_qa_template": QA_TEMPLATE,
})

# Pour utiliser un modele open source a la place
from llama_index.llms.openai_like import OpenAILike

llm_local = OpenAILike(
    api_base="http://localhost:8000/v1",  # vLLM
    model="mistral-medium-3.5",
    api_key="not-needed",
    temperature=0.1,
    max_tokens=2048,
    is_chat_model=True,
)

# Remplacer le LLM dans le query engine
query_engine = RetrieverQueryEngine.from_args(
    retriever=retriever,
    node_postprocessors=[reranker],
    llm=llm_local,
    response_mode="tree_summarize",
)

Anti-pattern a eviter : ne mettez jamais temperature au-dessus de 0.3 pour un pipeline RAG en production. Le RAG est concu pour des reponses factuelles basees sur des documents, pas pour de la generation creative. Une temperature elevee introduit des hallucinations que votre pipeline est cense eliminer. Valeur recommandee : 0.0 a 0.1 pour les cas d'usage critiques, 0.1 a 0.3 pour les assistants conversationnels.

Pour aller plus loin sur le deploiement du modele de generation en self-hosted, consultez notre guide deployer un modele MoE open source en production en 7 etapes.

Etape 7 — Evaluer et monitorer avec des metriques de production

Un pipeline RAG sans evaluation, c'est un avion sans instruments de bord. Vous ne savez pas si vos reponses sont correctes, vous ne detectez pas les regressions, et vous ne pouvez pas justifier le ROI aupres de vos stakeholders. LlamaIndex integre un module d'evaluation complet qui mesure trois metriques essentielles :

Faithfulness (fidelite) : est-ce que la reponse generee est fidele aux documents retrieves ? Un score de 1.0 signifie que chaque affirmation de la reponse est supportee par le contexte. Seuil production : superieur a 0.90.

Relevancy (pertinence) : est-ce que les documents retrieves sont pertinents par rapport a la question ? Un score bas ici indique un probleme de retrieval, pas de generation. Seuil production : superieur a 0.85.

Answer correctness (exactitude) : est-ce que la reponse est factuellement correcte par rapport a une reponse de reference ? Cette metrique necessite un jeu de donnees d'evaluation avec des questions et reponses de reference. Seuil production : superieur a 0.80.

from llama_index.core.evaluation import (
    FaithfulnessEvaluator,
    RelevancyEvaluator,
    BatchEvalRunner,
)

# Initialiser les evaluateurs
faithfulness_eval = FaithfulnessEvaluator(llm=llm)
relevancy_eval = RelevancyEvaluator(llm=llm)

# Jeu de donnees d evaluation (20 questions minimum)
eval_questions = [
    "Quelles sont les obligations RGPD pour le traitement IA ?",
    "Comment configurer un reverse proxy Nginx pour vLLM ?",
    "Quel est le cout d un GPU H200 chez Scaleway ?",
    # ... 17 autres questions metier
]

# Lancer l evaluation en batch
runner = BatchEvalRunner(
    {"faithfulness": faithfulness_eval, "relevancy": relevancy_eval},
    workers=4,
)

eval_results = await runner.aevaluate_queries(
    query_engine, queries=eval_questions
)

# Calculer les scores moyens
faith_scores = [r.score for r in eval_results["faithfulness"]]
relev_scores = [r.score for r in eval_results["relevancy"]]

print(f"Faithfulness moyen : {sum(faith_scores)/len(faith_scores):.2f}")
print(f"Relevancy moyen : {sum(relev_scores)/len(relev_scores):.2f}")
# Faithfulness moyen : 0.93
# Relevancy moyen : 0.88

Monitoring en production : integrez ces evaluations dans un cron job quotidien. Envoyez les resultats a Grafana ou Langfuse et configurez des alertes quand les scores passent en dessous des seuils. Surveillez aussi la latence P95 (objectif : moins de 3 secondes end-to-end) et le taux d'erreur de l'API vector store.

COMPARAISON : NAIVE RAG vs PIPELINE OPTIMISEMETRIQUERAG NAIF (baseline)PIPELINE OPTIMISEChunkingFixe 1024 tokensSemantique 512-800RetrievalTop-5 dense onlyTop-20 hybrid + rerank Top-5Faithfulness0.720.93Relevancy0.650.88Latence P954.2s2.1sTaux hallucination28%7%Benchmark sur corpus de 50 000 documents, 200 questions de test, modele GPT-4o

Questions frequentes

Quelle est la difference entre RAG et fine-tuning pour un LLM ?

Le RAG recupere des documents pertinents au moment de la requete et les injecte dans le prompt. Le fine-tuning modifie les poids du modele. Le RAG est preferable quand vos donnees changent frequemment et que vous voulez des sources citables. Le fine-tuning est plus adapte pour modifier le style ou le format de sortie du modele. En pratique, 80 pourcent des cas d'usage en entreprise sont mieux servis par le RAG.

LlamaIndex ou LangChain pour un pipeline RAG ?

LlamaIndex est la reference pour les pipelines RAG purs : son architecture est nativement concue autour de l'indexation et du retrieval, avec un meilleur support des strategies de chunking avancees et des re-rankers. LangChain est plus generaliste et mieux adapte si vous construisez un agent IA complexe qui fait du RAG parmi d'autres actions. Notre recommandation : LlamaIndex pour le RAG, LangChain pour les agents multi-outils.

Quel vector store choisir pour un pipeline RAG en production ?

Qdrant est notre recommandation par defaut : hautes performances, filtrage par metadata, support natif du multi-tenancy, hebergeable en France. ChromaDB est ideal pour les prototypes. Weaviate et Pinecone sont des alternatives pour la recherche hybride ou le SaaS manage. Evitez FAISS en production : il n'a pas de persistance native ni de filtrage metadata.

Combien coute un pipeline RAG en production ?

Pour un pipeline typique avec 50 000 documents et 1 000 requetes par jour : 200 a 500 EUR/mois avec un modele open source via vLLM (serveur vectoriel + compute). Avec une API proprietaire (Claude, GPT-4o), le cout d'inference monte a 500 a 2 000 EUR/mois selon la longueur des contextes. L'indexation initiale coute moins de 10 EUR en embeddings.

Pret a deployer votre pipeline RAG en production ?

D-Open accompagne les equipes techniques francaises de l'architecture au monitoring. Premier appel gratuit, 30 minutes, sans engagement.

Parlons de votre projet

Articles similaires