Construire un pipeline RAG avec LangChain et MongoDB
Guide complet pour implémenter un pipeline RAG performant en utilisant LangChain et MongoDB Atlas Vector Search.
La Retrieval-Augmented Generation (RAG) est devenue l'architecture de référence pour construire des applications IA capables de répondre à des questions sur vos propres données. Dans cet article, nous allons construire un pipeline RAG complet en combinant LangChain et MongoDB Atlas Vector Search.
Pourquoi RAG ?
Les grands modèles de langage (LLMs) souffrent de deux limitations majeures : leur knowledge cutoff et leur incapacité à accéder à des données propriétaires. Le RAG résout ces problèmes en récupérant dynamiquement les documents pertinents avant de générer une réponse, garantissant ainsi des réponses à jour et contextualisées.
Architecture du pipeline
Notre pipeline se compose de trois étapes principales :
- Ingestion : découpage des documents, génération des embeddings, stockage dans MongoDB
- Retrieval : recherche vectorielle pour trouver les passages pertinents
- Generation : envoi du contexte au LLM pour produire une réponse
Configuration de l'environnement
# requirements.txt
langchain==0.3.0
langchain-mongodb==0.2.0
langchain-openai==0.2.0
pymongo==4.8.0
python-dotenv==1.0.0# config.py
import os
from dotenv import load_dotenv
load_dotenv()
MONGODB_URI = os.getenv("MONGODB_URI")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
DB_NAME = "rag_demo"
COLLECTION_NAME = "documents"
VECTOR_INDEX_NAME = "vector_index"Étape 1 : Ingestion des documents
La qualité du chunking est critique pour la pertinence des réponses. Nous utilisons le RecursiveCharacterTextSplitter qui respecte la structure naturelle du texte.
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_mongodb import MongoDBAtlasVectorSearch
from pymongo import MongoClient
def ingest_documents(documents: list[str]) -> MongoDBAtlasVectorSearch:
client = MongoClient(MONGODB_URI)
collection = client[DB_NAME][COLLECTION_NAME]
# Découpage en chunks avec chevauchement pour préserver le contexte
splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
separators=["\n\n", "\n", ".", " "]
)
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vector_store = MongoDBAtlasVectorSearch.from_texts(
texts=splitter.split_text("\n\n".join(documents)),
embedding=embeddings,
collection=collection,
index_name=VECTOR_INDEX_NAME,
)
return vector_storeÉtape 2 : Création de l'index vectoriel MongoDB
Dans MongoDB Atlas, créez un index vectoriel sur votre collection via la console ou via l'API :
{
"fields": [
{
"type": "vector",
"path": "embedding",
"numDimensions": 1536,
"similarity": "cosine"
},
{
"type": "filter",
"path": "metadata.source"
}
]
}Étape 3 : Chaîne RAG complète
from langchain_openai import ChatOpenAI
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate
PROMPT_TEMPLATE = """Vous êtes un assistant expert. Utilisez uniquement les extraits de contexte
suivants pour répondre à la question. Si vous ne trouvez pas la réponse dans le contexte,
dites-le clairement.
Contexte:
{context}
Question: {question}
Réponse:"""
def build_rag_chain(vector_store: MongoDBAtlasVectorSearch) -> RetrievalQA:
llm = ChatOpenAI(model="gpt-4o", temperature=0)
prompt = PromptTemplate(
template=PROMPT_TEMPLATE,
input_variables=["context", "question"]
)
retriever = vector_store.as_retriever(
search_type="similarity",
search_kwargs={"k": 5}
)
chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=retriever,
chain_type_kwargs={"prompt": prompt},
return_source_documents=True
)
return chainOptimisations avancées
Hybrid Search
MongoDB Atlas supporte la recherche hybride (vectorielle + full-text), ce qui améliore significativement la précision :
retriever = vector_store.as_retriever(
search_type="similarity_score_threshold",
search_kwargs={
"k": 10,
"score_threshold": 0.75,
"pre_filter": {"metadata.category": {"$eq": "technical"}}
}
)Mise en cache des embeddings
Générer des embeddings est coûteux. Utilisez CacheBackedEmbeddings de LangChain pour éviter de recalculer les embeddings existants et réduire vos coûts jusqu'à 70 %.
Résultats et métriques
Sur un corpus de 50 000 documents techniques, ce pipeline atteint :
- Précision@5 : 89% (les 5 documents récupérés contiennent la réponse)
- Latence P95 : 340ms (retrieval + génération)
- Coût par requête : ~$0.004 avec GPT-4o
Conclusion
LangChain et MongoDB Atlas forment un duo redoutable pour construire des pipelines RAG en production. La flexibilité de LangChain pour orchestrer les étapes et la robustesse de MongoDB Atlas Vector Search pour indexer et requêter des millions de vecteurs en font une stack idéale pour des applications IA à grande échelle.
Le code complet de cet exemple est disponible sur notre GitHub. N'hésitez pas à l'adapter à votre cas d'usage.