Crea un asistente de chat para Wikipedia basado en RAG con LlamaIndex y ReAct
Traduzca las páginas del índice de Wikipedia según sea necesario, incorpore fragmentos con un pequeño codificador y permita que un agente ReAct llame a una herramienta de motor de consultas para que las respuestas de Chainlit se basen en evidencias obtenidas.
Introducción
Los modelos de lenguaje grandes son fluidos en su expresión, pero esa fluidez no equivale a saber si una respuesta es precisa o actual. Pueden inventar falsedades plausibles cuando una pregunta está fuera del rango de entrenamiento o cuando su confianza supera a las pruebas disponibles.
Un asistente de chat RAG para Wikipedia que sea práctico cierra esa brecha al combinar indexación de páginas bajo demanda, recuperación semántica, agrupación de pruebas, un agente ReAct que decide cuándo buscar y una interfaz de usuario conversacional que responde a partir del texto recuperado. Los materiales de origen para su desarrollo se encuentran en la muestra agentic-ai wiki RAG del repositorio GitHub data-etl-ml.
¿Por qué RAG?
Sin recuperación de información, el camino es corto pero frágil:
User Question
↓
LLM
↓
Answer
Todo depende de lo que el modelo memorizó durante su entrenamiento.
Con RAG, las pruebas se introducen antes de la generación:
User Question
↓
Retriever
↓
Relevant Documents
↓
LLM
↓
Grounded Answer
El modelo responde a partir de los fragmentos recuperados. Eso generalmente significa menos alucinaciones, hechos más oportunos, sin necesidad de un ciclo de ajuste fino para actualizar los conocimientos, y una forma sencilla de cambiar o ampliar el corpus.
Objetivo del proyecto
Crear un asistente de chat que responda a partir de las páginas de Wikipedia que el usuario elija para indexar. Ejemplo de solicitud:
Please index:
2023 United States banking crisis
Luego preguntar:
Which bank experienced the fastest bank run
in US history during 2023?
La respuesta debe citar el contenido de la página recuperada en lugar de depender únicamente de la memoria del modelo.
Descripción general de la arquitectura
A un nivel alto, el sistema se ve así:
Wikipedia Pages
│
▼
WikipediaReader
│
▼
SentenceSplitter
│
▼
Embeddings
BAAI/bge-small-en
│
▼
VectorStoreIndex
│
▼
Query Engine
│
▼
QueryEngineTool
│
▼
ReAct Agent
│
▼
Chainlit UI
Hay dos flujos importantes: un pipeline de indexación que crea el almacén vectorial buscable, y un pipeline de consulta que recupera fragmentos y genera respuestas.
Paso 1: Leer la clave API de OpenAI
Las credenciales no deben estar en el código fuente. Evite codificarlas directamente:
api_key = "xxxxx"
Cargue desde un archivo de configuración en su lugar:
def get_apikey():
with open("apikeys.yml") as file:
config = yaml.safe_load(file)
return config["OPENAI_API_KEY"]
Los secretos permanecen separados de la lógica de la aplicación.
Paso 2: Comprender la estructura del código
El proyecto consta de tres módulos en Python:
utils.py
index_wikipages.py
chat_agent.py
utils.py carga las claves de API y la configuración. index_wikipages.py analiza las solicitudes de páginas, descarga el texto de Wikipedia, incrusta los fragmentos y crea índices. chat_agent.py conecta el agente ReAct, la herramienta de motor de consultas y la interfaz de Chainlit.
Paso 3: Extraer páginas de Wikipedia mediante salida estructurada
Los usuarios pueden escribir listas en formato libre:
Please index:
London, Birmingham, New York
El indexador necesita un array ordenado:
[
"London",
"Birmingham",
"New York"
]
En lugar de usar divisiones de cadenas frágiles, un modelo Pydantic captura la salida estructurada:
class WikiPageList(BaseModel):
pages: List[str]
El modelo convierte el lenguaje natural en una lista de páginas con tipos definidos automáticamente.
Paso 4: Carga de páginas de Wikipedia
LlamaIndex incluye un cargador práctico:
WikipediaReader
La inserción se realiza con unas pocas líneas:
loader = WikipediaReader()
documents = loader.load_data(
pages=["2023 United States banking crisis"]
)
En este punto, el pipeline contiene los documentos de página en formato raw.
Paso 5: División de los documentos en fragmentos
Los modelos manejan mal las páginas grandes como bloques únicos. Es necesario dividirlas en fragmentos superpuestos:
SentenceSplitter(
chunk_size=150,
chunk_overlap=45
)
La superposición permite conservar las ideas que se extienden más allá de los límites entre fragmentos:
Chunk A:
---------------------
Paragraph 1
Paragraph 2
Chunk B:
---------------------
Paragraph 2
Paragraph 3
Paso 6: Creación de embeddings
El texto en formato raw no es suficiente para la búsqueda semántica. Cada fragmento se convierte en un vector. El modelo de embeddings utilizado aquí es:
BAAI/bge-small-en
Una consulta como esta:
"What is Databricks?"
se traduce en un vector denso:
[0.21, -0.44, 0.87 ...]
Los fragmentos semánticamente relacionados se agrupan cerca unos de otros en ese espacio.
Paso 7: Creación del índice vectorial
LlamaIndex se encarga de la construcción del almacenamiento:
index = VectorStoreIndex(nodes)
El resultado es un índice vectorial en memoria que puede responder a búsquedas de similitud como:
Find chunks similar to:
"fastest bank run in history"
Paso 8: Creación del motor de búsqueda
Exponer el índice como un motor de consultas:
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 controla cuántos fragmentos vecinos se utilizan para generar la respuesta.
Paso 9: Construcción del agente ReAct
ReAct significa:
Reason + Act
Un bot ingenuo pasa directamente de la pregunta a la respuesta:
Question
→ Answer
Un agente ReAct incluye razonamiento y uso de herramientas:
Question
↓
Reason
↓
Choose Tool
↓
Observe Output
↓
Answer
La recuperación de información se vuelve dinámica en lugar de estar siempre activa o nunca activa.
Creación de herramientas
Envolver el motor de consultas como una herramienta que el agente pueda llamar:
QueryEngineTool(
query_engine=query_engine,
metadata=ToolMetadata(
name="Wikipedia"
)
)
De esta manera, el agente sabe que existe la capacidad de realizar búsquedas en Wikipedia.
ReAct Loop
The agent internally performs:
Internamente, el bucle se ve así:
Thought:
Need information about the banking crisis.
Action:
Wikipedia Tool
Observation:
Found relevant passages.
Answer:
Grounded response.
Ese patrón es más fiable que una simple completación de chat sin herramientas.
Paso 10: Crear la interfaz de usuario con Chainlit
Chainlit ofrece una estructura para chats con un código mínimo. Un panel de configuración muestra:
Model
Wikipedia Pages
Ejemplo de configuración:
MODEL:
gpt-5-nano
Wikipedia Pages:
Please index:
2023 United States banking crisis
La configuración inicializa el índice vectorial antes de que comience la conversación.
Demostración
Después del indexado:
2023 United States banking crisis
una pregunta como:
Which bank experienced the fastest
bank run in US history?
produce una respuesta basada en evidencias reales como:
Silicon Valley Bank (SVB)
Approximately $42 billion
was withdrawn in 10 hours.
Las cifras provienen de pruebas obtenidas, no de invenciones arbitrarias.
Aprendizajes
Lo que funcionó bien
LlamaIndex mantiene el proceso de indexado breve:
Documents
→ Nodes
→ Index
Los agentes ReAct mejoran las decisiones sobre cuándo recuperar información, de modo que la búsqueda se realiza solo cuando es necesaria. Chainlit sigue siendo una de las vías más rápidas para obtener una interfaz de chat con IA utilizable.
Desafíos
La compatibilidad con Python 3.13 afectó a varios conjuntos de herramientas: las combinaciones de Chainlit, Pydantic y LlamaIndex resultaron inestables. Fijar las versiones:
Python 3.11
fue mucho más fiable.
La calidad de la recuperación determina la calidad de las respuestas. Los fragmentos de mala calidad generan vecinos de mala calidad, lo que a su vez produce respuestas deficientes. La lección clave: la calidad de la recuperación suele ser más importante que el modelo de chat utilizado.
Mejoras futuras
Los siguientes pasos lógicos incluyen la búsqueda híbrida:
Keyword Search
+
Semantic Search
Reclasificación después de una primera fase de recuperación amplia: recuperar:
Top 50
Luego, comprimir hasta obtener las mejores opciones. Citas que muestren los párrafos correspondientes a cada afirmación. Y una b base de datos vectoriales persistente en lugar de una efímera:
VectorStoreIndex
con opciones como Chroma, Pinecone, Weaviate o Milvus.
Reflexiones finales
El proyecto ofrece una visión concisa de los patrones agentes modernos: RAG, embeddings, búsqueda vectorial, herramientas ReAct, interfaz Chainlit y orquestación LlamaIndex. El punto estratégico radica en algo más que en una sola biblioteca. Los sistemas fiables surgen de combinar modelos con mecanismos de recuperación, herramientas y bucles de razonamiento, no solo de buscar cantidades cada vez mayores de parámetros. Clona la muestra 6_wiki_rag_react_project dentro de la carpeta agentic-ai del proyecto GitHub data-etl-ml para experimentar con toda la estructura.
Lecturas relacionadas
- Construye tus primeros flujos de trabajo LangGraph antes de los sistemas multiagentes — Aprende LangGraph con ejemplos compatibles con Colab: estado compartido, nodos secuenciales, un único paso de LLM y una pipeline de blog en múltiples etapas.
- Orquesta agentes de investigadores y programadores con LangGraph — Crea una aplicación multiagentes de LangGraph con prompts especializados, modelos Ollama, búsquedas en Tavily, herramientas de transferencia de tareas y puntos de control en Postgres para flujos de trabajo dirigidos por un orquestador.