Créer un assistant de chat basé sur Wikipedia RAG à l’aide de LlamaIndex et ReAct
Indexer les pages de Wikipédia sur demande, intégrer des extraits à l’aide d’un petit encodeur, et permettre à un agent ReAct d’appeler un outil de moteur de requêtes afin que les réponses de Chainlit restent fondées sur des preuves obtenues.
Introduction
Les grands modèles de langage sont fluides dans leur expression, mais cette fluidité ne signifie pas qu’ils savent si une réponse est exacte ou à jour. Ils peuvent inventer des fausses informations plausibles lorsque la question dépasse les limites de leur entraînement ou lorsque leur confiance dépasse les preuves disponibles.
Un assistant de chat RAG pour Wikipedia comble cette lacune en combinant un indexage de pages sur demande, une récupération sémantique, l’agrégation des preuves, un agent ReAct qui décide quand effectuer des recherches, ainsi qu’une interface conversationnelle qui répond à partir du texte récupéré. Les matériaux sources pour sa création se trouvent dans l’exemple RAG agentic-ai wiki sur le répertoire GitHub data-etl-ml.
Pourquoi RAG ?
Sans récupération de données, le processus est court mais fragile :
User Question
↓
LLM
↓
Answer
Tout dépend de ce que le modèle a mémorisé lors de son entraînement.
Avec RAG, les preuves sont intégrées avant la génération du texte :
User Question
↓
Retriever
↓
Relevant Documents
↓
LLM
↓
Grounded Answer
Le modèle répond en s’appuyant sur des extraits récupérés. Cela signifie généralement moins d’hallucinations, des faits plus récents, pas de cycle de fine-tuning nécessaire pour actualiser les connaissances, ainsi qu’une manière simple de remplacer ou d’élargir le corpus.
Objectif du projet
Créer un assistant de conversation qui répond en s’appuyant sur les pages Wikipédia que l’utilisateur choisit d’indexer. Exemple de demande :
Please index:
2023 United States banking crisis
Puis demandez :
Which bank experienced the fastest bank run
in US history during 2023?
La réponse doit citer le contenu de la page récupérée plutôt que se fier à la mémoire du modèle seule.
Aperçu de l’architecture
À un niveau général, le système se présente comme suit :
Wikipedia Pages
│
▼
WikipediaReader
│
▼
SentenceSplitter
│
▼
Embeddings
BAAI/bge-small-en
│
▼
VectorStoreIndex
│
▼
Query Engine
│
▼
QueryEngineTool
│
▼
ReAct Agent
│
▼
Chainlit UI
Deux flux sont importants : un tuyau d’indexation qui crée le stockage vectoriel consultable, et un tuyau de requête qui récupère des extraits et génère des réponses.
Étape 1 : Lire la clé API d’OpenAI
Les identifiants ne doivent pas figurer dans le code source. Évitez de les coder directement :
api_key = "xxxxx"
Chargement depuis un fichier de configuration plutôt :
def get_apikey():
with open("apikeys.yml") as file:
config = yaml.safe_load(file)
return config["OPENAI_API_KEY"]
Les secrets restent séparés de la logique de l’application.
Étape 2 : Comprendre la structure du code
Le projet se compose de trois modules Python :
utils.py
index_wikipages.py
chat_agent.py
utils.py charge les clés API et la configuration. index_wikipages.py analyse les demandes de pages, télécharge le texte de Wikipédia, insère des extraits et crée des index. chat_agent.py relie l’agent ReAct, l’outil de moteur de requêtes et l’interface Chainlit.
Étape 3 : Extraire les pages de Wikipédia à l’aide d’une sortie structurée
Les utilisateurs peuvent saisir des listes en format libre :
Please index:
London, Birmingham, New York
L’indexeur a besoin d’un tableau propre :
[
"London",
"Birmingham",
"New York"
]
Au lieu d’une segmentation de chaînes fragile, un modèle Pydantic capture une sortie structurée :
class WikiPageList(BaseModel):
pages: List[str]
Le modèle transforme automatiquement le langage naturel en une liste de pages typées.
Étape 4 : Chargement des pages Wikipedia
LlamaIndex fournit un chargeur pratique :
WikipediaReader
La saisie se fait en quelques lignes seulement :
loader = WikipediaReader()
documents = loader.load_data(
pages=["2023 United States banking crisis"]
)
À ce stade, le pipeline contient des documents de pages bruts.
Étape 5 : Division en blocs des documents
Les modèles ont du mal à gérer de grandes pages en tant que blocs uniques. Il faut les diviser en parties superposées :
SentenceSplitter(
chunk_size=150,
chunk_overlap=45
)
La superposition permet de conserver les idées qui se situent à la frontière entre deux parties :
Chunk A:
---------------------
Paragraph 1
Paragraph 2
Chunk B:
---------------------
Paragraph 2
Paragraph 3
Étape 6 : Création des embeddings
Le texte brut n’est pas suffisant pour une recherche sémantique. Chaque bloc devient un vecteur. Le modèle d’embedding utilisé ici est :
BAAI/bge-small-en
Une requête telle que :
"What is Databricks?"
est traduite en un vecteur dense :
[0.21, -0.44, 0.87 ...]
Les blocs sémantiquement liés se regroupent à proximité dans cet espace.
Étape 7 : Création de l’index vectoriel
LlamaIndex gère la construction de cet index :
index = VectorStoreIndex(nodes)
Le résultat est un index vectoriel en mémoire qui peut répondre à des recherches de similarité telles que :
Find chunks similar to:
"fastest bank run in history"
Étape 8 : Création du moteur de recherche
Exposer l’index en tant que moteur de requêtes :
query_engine = index.as_query_engine(
response_mode="compact",
similarity_top_k=10,
verbose=True
)
similarity_top_k = 10
Return 10 most relevant chunks
similarity_top_k détermine le nombre de blocs voisins qui alimentent la réponse.
Étape 9 : Construction de l’agent ReAct
ReAct signifie :
Reason + Act
Un bot naïf passe directement de la question à la réponse :
Question
→ Answer
Un agent ReAct intègre du raisonnement et l’utilisation d’outils :
Question
↓
Reason
↓
Choose Tool
↓
Observe Output
↓
Answer
La récupération devient dynamique au lieu d’être constamment active ou jamais active.
Création d’outils
Encadrer le moteur de requêtes en tant qu’outil que l’agent peut appeler :
QueryEngineTool(
query_engine=query_engine,
metadata=ToolMetadata(
name="Wikipedia"
)
)
L’agent sait alors qu’une fonction de recherche sur Wikipedia est disponible.
ReAct Loop
The agent internally performs:
En interne, la boucle ressemble à ceci :
Thought:
Need information about the banking crisis.
Action:
Wikipedia Tool
Observation:
Found relevant passages.
Answer:
Grounded response.
Celui-ci est plus fiable qu’une simple complétion de chat sans outils.
Étape 10 : Création de l’interface utilisateur avec Chainlit
Chainlit fournit une interface de chat avec un minimum de code pré-rempli. Un panneau de paramètres expose :
Model
Wikipedia Pages
Exemple de configuration :
MODEL:
gpt-5-nano
Wikipedia Pages:
Please index:
2023 United States banking crisis
Les paramètres initialisent l’index vectoriel avant le début de la conversation.
Démonstration
Après l’indexation :
2023 United States banking crisis
une question telle que :
Which bank experienced the fastest
bank run in US history?
produit une réponse fondée sur des données concrètes comme :
Silicon Valley Bank (SVB)
Approximately $42 billion
was withdrawn in 10 hours.
Les chiffres proviennent de preuves récupérées, et non d’inventions arbitraires.
Leçons apprises
Ce qui a bien fonctionné
LlamaIndex permet de garder le processus d’indexation court :
Documents
→ Nodes
→ Index
Les agents ReAct améliorent les décisions concernant le moment de récupérer les données, de sorte que la recherche ne s’exécute qu’en cas de besoin. Chainlit reste l’un des moyens les plus rapides pour obtenir une interface de chat IA utilisable.
Défis
La compatibilité avec Python 3.13 a posé des problèmes à plusieurs stacks : les combinaisons Chainlit, Pydantic et LlamaIndex étaient instables. Le verrouillage des versions :
Python 3.11
était bien plus fiable.
La qualité de la récupération influence fortement la qualité des réponses. Des données de mauvaise qualité entraînent des résultats médiocres. Leçon importante : la qualité de la récupération est souvent plus cruciale que le modèle de chat utilisé.
Améliorations futures
Les prochaines étapes logiques incluent la recherche hybride :
Keyword Search
+
Semantic Search
Le réclassement après une première phase de récupération massive — puis la récupération des résultats pertinents :
Top 50
ensuite, compresser les résultats pour n’en garder que les meilleurs. Des citations qui mettent en évidence les paragraphes correspondant à chaque affirmation. Et une base de données vectorielle persistante plutôt qu’une temporaire :
VectorStoreIndex
avec des options telles que Chroma, Pinecone, Weaviate ou Milvus.
Considerations finales
Ce projet offre un aperçu concis des modèles agents modernes : RAG, embeddings, recherche vectorielle, outils ReAct, interface Chainlit et orchestration LlamaIndex. L’aspect stratégique réside dans la combinaison de modèles avec des mécanismes de récupération d’informations, des outils et des boucles de raisonnement — et non uniquement dans la recherche de modèles dotés d’un nombre toujours croissant de paramètres. Clonez l’exemple 6_wiki_rag_react_project situé dans le dossier agentic-ai du projet GitHub data-etl-ml pour expérimenter avec l’ensemble de la structure.