Construire un RAG from scratch en Python
Exemple de mise en oeuvre avec LlamaIndex, OpenAI et Chroma
Ecrit par Vincent
À mesure que l’IA continue de révolutionner divers secteurs, l’intégration de la récupération d’information avec les modèles de langage pour créer des applications puissantes devient de plus en plus populaire. L’une de ces approches est la Retrieval-Augmented Generation (RAG), qui combine la récupération d’informations et des modèles génératifs pour fournir des réponses contextuellement précises.
Dans ce guide, je vais vous montrer comment construire un système RAG simple à partir de zéro en utilisant LlamaIndex, OpenAI et Chroma. Le système récupérera le contenu pertinent à partir de documents indexés et générera des réponses à l’aide d’un modèle OpenAI.
Ce que nous allons couvrir
- Architecture d’un RAG
- Configuration de l’environnement
- Extraction des URL à partir d’un sitemap
- Récupération et traitement du contenu web
- Vectorisation du contenu avec LlamaIndex
- Stockage des vecteurs dans Chroma
- Exécution d’une requête RAG pour générer des réponses
Plongeons dans le sujet !
Architecture d’un RAG
L’architecture d’un système Retrieval-Augmented Generation (RAG) combine des techniques de récupération d’information avec la génération de texte alimentée par des modèles de langage (LLM). L’objectif est de fournir des réponses plus précises et pertinentes en s’appuyant sur des données ou documents externes, plutôt que de générer des réponses uniquement basées sur les paramètres du modèle. Voici les principaux composants de cette architecture :

- Source de données / Base de connaissances Le processus RAG commence par une base de connaissances structurée ou non structurée, qui peut inclure :
- Base de données vectorielle : Stocke des représentations vectorielles de documents, pages web, articles, etc.
- Sources de documents : Fichiers texte, bases de données relationnelles, PDF, sites web ou autres dépôts.
- Indexation et Embedding Les documents ou données sont transformés en représentations vectorielles (embeddings). Ces vecteurs sont créés par un modèle transformeur (comme OpenAI, Llama, etc.) qui encode les informations textuelles en une forme numérique utilisable. Ces vecteurs sont ensuite stockés dans une base de données vectorielle (telle que Chroma) qui permet des recherches de similarité rapides et efficaces.
- Récupération des documents pertinents Lorsqu’une question est posée au système RAG, elle est convertie en un vecteur. Ce vecteur est comparé à ceux stockés dans la base de données vectorielle. Le système récupère les documents les plus pertinents (souvent en utilisant une mesure de similarité cosinus entre les vecteurs) en fonction de la requête. C’est l’étape de récupération.
- Génération de réponses via LLM Après la récupération des documents pertinents, ces informations sont transmises à un modèle de génération de texte (LLM), tel que GPT, pour produire une réponse.
Le modèle utilise les documents récupérés comme contexte pour générer une réponse plus précise, avec la possibilité de citer les sources utilisées pour répondre à la question. La réponse générée combine la capacité du modèle à raisonner sur les données récupérées et à générer un texte cohérent.
Exemple de mise en oeuvre
Configuration de l’environnement
Pour commencer, vous devez installer les bibliothèques suivantes :
pip install llama_index
pip install llama-index-readers-web
pip install chromadb llama-index-vector-stores-chroma
Préparation du contenu
Extraction des URL à partir du sitemap
Nous utilisons pour cela une classe proposée par la librairie LlamaIndex et qui permet de rapidement extraire les page d’un site sous la forme d’une liste de documents.
from llama_index.readers.web import SitemapReader
sitemap_url = 'https://www.eurelis.com/page-sitemap.xml'
reader = SitemapReader(html_to_text=True, limit=1)
documents = reader.load_data(sitemap_url=sitemap_url)
Vectorisation du contenu
Cette étape consiste à calculer les vecteurs d’embeddings associées aux en utilisant LlamaIndex et le modèle OpenAI.
Stockage des vecteurs avec Chroma
Pour cet exemple, nous utiliserons Chroma pour stocker les vecteurs. Vous pouvez choisir entre une configuration persistante ou éphémère selon vos besoins.
import chromadb
from llama_index.vector_stores.chroma import ChromaVectorStore
# Initialiser le client Chroma
chroma_client = chromadb.EphemeralClient()
# Créer une collection pour stocker les vecteurs
chroma_collection = chroma_client.get_or_create_collection("knowledge_base")
# Créer le store de vecteurs
vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
Configuration du contexte de stockage
from llama_index.core import StorageContext
# Initialiser le contexte de stockage
storage_context = StorageContext.from_defaults(vector_store=vector_store)
Calcul des Embeddings
Ensuite, nous allons intégrer le contenu à l’aide du modèle d’embedding d’OpenAI.
from llama_index.embeddings.openai import OpenAIEmbedding
embed_model = OpenAIEmbedding(model="text-embedding-3-small")
# Embed d'un texte exemple
embeddings = embed_model.get_text_embedding("Les nouveaux modèles d'embeddings d'OpenAI sont fantastiques !")
Ce modèle convertit le texte en une représentation vectorielle dense qui sera utilisée pour la recherche de similarités par la suite.
Indexation des documents
Nous allons maintenant indexer les documents en utilisant VectorStoreIndex pour les préparer à la récupération.
from llama_index.core import VectorStoreIndex
from llama_index.core.node_parser import SentenceSplitter
# Créer un splitteur de phrases pour découper le texte
parser = SentenceSplitter(chunk_size=768, chunk_overlap=56)
# Construire l'index
index = VectorStoreIndex.from_documents(documents, storage_context=storage_context, transformations=[parser], show_progress=True)
Requêter le système RAG
Maintenant que notre contenu est indexé, nous pouvons le requêter en utilisant la génération augmentée par la récupération. Ce processus récupère les vecteurs les plus pertinents pour une requête donnée, puis génère une réponse à l’aide d’un modèle de langage.
Définir la requête
query = "Qu'est-ce que Drupal ?"
Configurer le Retriever et le moteur de requête
Nous allons configurer le retriever et le moteur de requête en utilisant OpenAI comme modèle de langage.
from llama_index.core.retrievers import VectorIndexRetriever
from llama_index.core.query_engine import RetrieverQueryEngine
from llama_index.llms.openai import OpenAI
retriever = VectorIndexRetriever(index, similarity_top_k=10, filter=None)
llm = OpenAI(model="gpt-4o")
query_engine = RetrieverQueryEngine.from_args(retriever, llm=llm)
Personnalisation du prompt
Vous pouvez personnaliser le modèle de prompt utilisé pour générer des réponses :
from llama_index.core import PromptTemplate
new_prompt_template_str = (
"Les informations contextuelles sont ci-dessous.\n"
"---------------------\n"
"{context_str}\n"
"---------------------\n"
"En fonction du contexte et non des connaissances préalables, "
"répondez à la requête en moins de 15 mots.\n"
"Requête : {query_str}\n"
"Réponse : "
)
new_prompt_template = PromptTemplate(new_prompt_template_str)
query_engine.update_prompts({"response_synthesizer:text_qa_template": new_prompt_template})
Exécuter la requête
Enfin, nous exécutons la requête et affichons la réponse :
response = query_engine.query(query)
print(str(response))
Conclusion
Dans ce guide, nous avons démontré comment construire un système RAG (Retrieval-Augmented Generation) à partir de zéro en utilisant LlamaIndex, OpenAI, et Chroma. Cette approche permet de récupérer des informations pertinentes et d’utiliser un modèle de langage pour générer des réponses contextuelles basées sur des données réelles.
Les possibilités d’extension de ce système sont vastes : intégrer des mécanismes de récupération plus complexes, améliorer la pertinence des réponses, ou déployer la solution dans des environnements de production. Chez Eurelis, nous accompagnons nos clients dans la mise en œuvre de solutions IA sur mesure, qu’il s’agisse de projets exploratoires ou de déploiements à grande échelle.
Vous souhaitez transformer vos données en un avantage compétitif avec des applications d’IA avancées comme le RAG ? Contactez-nous pour discuter de la manière dont nous pouvons intégrer ces technologies dans vos projets et vous aider à optimiser vos processus métier, tout en améliorant l’expérience utilisateur et la qualité de vos services.