La réponse courte (août 2026) : Un pipeline RAG (retrieval-augmented generation) extrait les fragments pertinents de vos propres documents et les injecte dans le prompt d'un LLM avant la génération, de sorte que le modèle réponde à partir de vos données plutôt que de sa mémoire d'entraînement. Il faut quatre composants : un chargeur de documents, un séparateur de texte, un modèle d'embedding et un vector store. Le point de départ le plus rapide est pip install langchain langchain-openai langchain-chroma chromadb, une clé API OpenAI, et une après-midi. Le modèle text-embedding-3-small d'OpenAI coûte $0.02 par million de tokens sur leur API standard ; un corpus de 50,000 chunks revient généralement à moins de $0.50 à indexer depuis zéro.
Dernière vérification : 17 août 2026, d'après les documentations officielles et les pages de tarifs.
Comment fonctionne un pipeline RAG
RAG signifie retrieval-augmented generation. Le mécanisme : les documents sont convertis au préalable en embeddings vectoriels et stockés dans une base de données vectorielle ; au moment de la requête, la question de l'utilisateur est intégrée avec le même modèle et les chunks sémantiquement les plus proches sont renvoyés. Ces chunks rejoignent le prompt du LLM aux côtés de la question.
Quatre étapes distinctes s'exécutent à chaque requête :
Indexation (une seule fois) : charger les documents, les découper en chunks, intégrer chaque chunk, écrire les vecteurs en base.
Récupération : intégrer la requête entrante, lancer une recherche du plus proche voisin, renvoyer les k meilleurs chunks.
Augmentation : insérer ces chunks dans un template de prompt à côté de la question de l'utilisateur.
Génération : envoyer le prompt rempli au LLM ; il répond en s'appuyant sur le contexte récupéré comme ancrage.
La propriété clé qu'apporte le RAG : le LLM ne peut citer que ce que la récupération a remonté. Les hallucinations ne sont pas éliminées, mais elles sont substantiellement réduites parce que le modèle dispose de texte concret sur lequel s'appuyer. Si l'étape de récupération rate le chunk pertinent, le modèle n'a rien sur quoi travailler ; la qualité de la récupération est donc le principal levier à optimiser.
Choisir sa stack
Deux frameworks Python couvrent la majorité des charges de travail RAG en production : LangChain (v1.3.15 en août 2026) et LlamaIndex (llama-index-core v0.14.23 en juin 2026). Ils supportent les mêmes vector stores et modèles d'embedding, ce qui rend la migration non catastrophique, mais les modèles de programmation diffèrent.
Le modèle de composition de LangChain, LCEL (LangChain Expression Language), connecte les étapes avec l'opérateur pipe |. Il offre un contrôle explicite sur chaque étape, ce qui compte lorsqu'on veut ajouter du reranking, du routage ou des boucles agentiques. Pour construire des agents IA en parallèle d'un pipeline RAG, LangChain intègre ce travail plus naturellement.
LlamaIndex est conçu spécifiquement pour les Q&R documentaires à forte densité de données. Son appel VectorStoreIndex.from_documents() gère le chargement, le découpage, l'embedding et l'indexation en une seule ligne. Moins de composants à gérer, mais aussi moins de points d'accroche pour personnaliser chaque étape. Il utilise par défaut text-embedding-ada-002 pour les embeddings ; il faut le remplacer explicitement pour passer à un modèle plus récent.
Pour le vector store, le choix détermine à la fois la charge opérationnelle et le coût à l'échelle :
| Vector Store | Free Tier | Paid Starting Price | Self-Host Option | Best Fit |
|---|---|---|---|---|
| Chroma | Free (open source, runs in-process) | Chroma Cloud: $5 credits, then usage-based | Yes (Apache 2.0) | Local dev; in-process prototypes |
| Qdrant | Free forever: 0.5 vCPU, 1 GB RAM, 4 GB disk | Standard: hourly usage-based billing | Yes (Apache 2.0) | Production self-hosting; filtered search |
| Pinecone | Starter: 2 GB storage, 5 serverless indexes | Builder: $20/month flat rate | No (managed cloud only) | Zero-ops managed deployments |
| pgvector | Free (PostgreSQL extension) | Your existing Postgres hosting costs | Yes | Teams already running Postgres |
Chroma est le bon choix par défaut pour le développement local. Le tier cloud gratuit de Qdrant est généreusement dimensionné pour un prototype qui doit persister entre les redémarrages. Passer à Pinecone ou à un cluster Qdrant en production lorsque des SLA de disponibilité sont requis.
Installer et configurer l'environnement
LangChain avec Chroma :
pip install langchain langchain-openai langchain-text-splitters langchain-chroma chromadb
Définir la clé API :
export OPENAI_API_KEY="sk-..."
LlamaIndex avec le store en mémoire par défaut :
pip install llama-index-core llama-index-llms-openai llama-index-embeddings-openai
LlamaIndex 0.10 et les versions ultérieures utilisent une structure de packages modulaire. Installer uniquement les intégrations nécessaires. Pour Qdrant comme vector store, ajouter llama-index-vector-stores-qdrant. Pour Pinecone, ajouter llama-index-vector-stores-pinecone. Les deux frameworks lisent OPENAI_API_KEY depuis l'environnement automatiquement.
Placer les documents dans un dossier data/ avant de passer à l'étape suivante. Les deux frameworks gèrent les PDF, le texte brut, le Markdown et le HTML nativement.
Découper les documents
Les séparateurs de texte divisent les documents en fragments récupérables. La taille des chunks a autant d'influence sur la qualité de la récupération que le choix du modèle d'embedding ; à définir délibérément.
Le point de départ actuellement reconnu est 512 tokens par chunk avec 10 % de chevauchement (soit environ 50 tokens pour un chunk de 512 tokens). Des chunks plus petits offrent une récupération plus précise pour les questions factuelles. Des chunks plus grands fournissent au modèle davantage de contexte environnant par fragment récupéré, ce qui aide lorsque les réponses nécessitent un raisonnement sur plusieurs paragraphes.
Le découpage récursif par caractères est le choix le plus fiable par défaut. Il tente de couper d'abord sur les limites de paragraphes, puis de phrases, puis de mots, en préservant les unités sémantiques autant que possible.
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import DirectoryLoader
loader = DirectoryLoader("data/")
documents = loader.load()
splitter = RecursiveCharacterTextSplitter(
chunk_size=512,
chunk_overlap=50,
)
chunks = splitter.split_documents(documents)
print(f"Created {len(chunks)} chunks")
Un avertissement : un chevauchement au-delà d'un certain seuil ajoute des coûts de stockage et d'embedding sans amélioration mesurable de la récupération dans la plupart des benchmarks. Si le rappel est faible, tester des chunks plus petits ou un meilleur modèle d'embedding avant d'augmenter le chevauchement.
Intégrer et indexer
L'embedding convertit chaque chunk en un vecteur de nombres à virgule flottante encodant la signification sémantique. Cette étape s'exécute une seule fois au moment de l'indexation ; le même modèle tourne à nouveau au moment de la requête sur la question de l'utilisateur.
Les modèles d'embedding actuels d'OpenAI, vérifiés d'après leur page de tarifs officielle :
- text-embedding-3-small : $0.02 par million de tokens, 1,536 dimensions, limite d'entrée de 8,192 tokens
- text-embedding-3-large : $0.13 par million de tokens, 3,072 dimensions, limite d'entrée de 8,192 tokens
text-embedding-3-small est le bon choix par défaut pour la plupart des charges de travail RAG. Le grand modèle score 64.6% sur les benchmarks MTEB contre 62.3% pour le petit, un gain de qualité modeste pour un tarif 6.5x supérieur. Commencer avec small ; comparer les deux sur de vraies requêtes de récupération avant de payer pour large.
Indexation avec LangChain et Chroma :
from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma.from_documents(
documents=chunks,
embedding=embeddings,
persist_directory="./chroma_db",
)
print(f"Indexed {vectorstore._collection.count()} vectors")
Avec LlamaIndex, remplacer le modèle d'embedding par défaut avant de construire l'index :
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
from llama_index.embeddings.openai import OpenAIEmbedding
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")
documents = SimpleDirectoryReader("data").load_data()
index = VectorStoreIndex.from_documents(documents)
Sans le remplacement Settings.embed_model, LlamaIndex utilise par défaut text-embedding-ada-002 ($0.10/M tokens), plus ancien et surpassé par text-embedding-3-small à un cinquième du coût.
Requête : récupération et génération
Au moment de la requête, le pipeline intègre la question, récupère les k meilleurs chunks et les passe au LLM. Le paramètre k est le principal levier de réglage à ce stade.
Pattern LangChain LCEL :
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})
prompt = ChatPromptTemplate.from_template(
"Answer using only the context below. "
"If the context does not contain the answer, say so.\n\n"
"Context: {context}\n\nQuestion: {question}"
)
llm = ChatOpenAI(model="gpt-4o-mini")
chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
answer = chain.invoke("What does the refund policy cover?")
print(answer)
Pattern LlamaIndex :
query_engine = index.as_query_engine(similarity_top_k=4)
response = query_engine.query("What does the refund policy cover?")
print(response)
Commencer avec k=4. Augmenter à 6 ou 8 si le modèle indique fréquemment qu'il manque de contexte. Chaque chunk récupéré supplémentaire consomme des tokens de fenêtre de contexte et augmente le coût d'inférence ; le compromis est réel. L'instruction "if the context does not contain the answer, say so" dans le prompt réduit sensiblement les hallucinations confiantes en production.
FAQ
Le modèle d'embedding compte-t-il plus que la stratégie de découpage ?
Une étude évaluée par les pairs publiée à NAACL 2025 (Vectara) a conclu que les décisions de découpage avaient autant d'influence sur la qualité de la récupération que le choix du modèle d'embedding. Définir délibérément la taille des chunks avant de passer à un modèle plus coûteux.
Peut-on exécuter cela entièrement en local sans appels d'API externes ?
Oui. Remplacer OpenAI par un modèle local via Ollama pour l'inférence LLM et installer llama-index-embeddings-huggingface ou un package similaire pour les embeddings locaux. Chroma fonctionne entièrement en in-process sans appels réseau. Prévoir un débit inférieur et généralement une qualité de réponse moindre par rapport aux modèles hébergés.
Que se passe-t-il lorsqu'un document dépasse la limite de 8,192 tokens du modèle d'embedding ?
Le document doit être découpé avant l'embedding. Les séparateurs de texte de LangChain et les parseurs de nœuds de LlamaIndex gèrent cela automatiquement. Garder la taille des chunks confortablement en dessous de 8,000 tokens ; le tokenizer du modèle utilise un vocabulaire fixe et les estimations en nombre de caractères peuvent être légèrement décalées.
pgvector est-il suffisant pour remplacer un vector store dédié ?
Pour des corpus de taille modeste avec un index HNSW, pgvector offre des performances comparables aux vector stores dédiés et élimine un service à opérer. À plus grande échelle ou lorsqu'une recherche filtrée avancée est nécessaire, Qdrant et Pinecone offrent davantage d'options de réglage.
Comment mettre à jour l'index quand les documents changent ?
La plupart des vector stores supportent les opérations d'upsert indexées par un ID de document. Assigner des IDs stables (un hash du chemin de fichier plus la position du chunk fonctionne), puis supprimer et réinsérer uniquement les chunks du document modifié. Pinecone et Qdrant supportent ce pattern nativement. Éviter la réindexation complète à chaque mise à jour ; à 50,000 chunks, cela coûte $0.50 à chaque fois.
Plus sur les patterns agentiques qui étendent les systèmes RAG dans le guide de configuration des agents d'AI Weekly. Recevoir AI Weekly gratuitement, 3 numéros par semaine, lu par 40,000+ praticiens.