Skip to content

kevmansilla/rag-for-regulated-environments

Repository files navigation

LLM para el Sector Energético

Sistema RAG (Retrieval-Augmented Generation) especializado en el sector energético utilizando LLMs y recuperación híbrida de documentos.

Python FastAPI License

Autores

  • Kevin Mansilla, FaMAF-UNC
  • Francisco Martiarena, FaMAF-UNC

Tabla de contenidos


Descripción

Este proyecto implementa un sistema RAG (Retrieval-Augmented Generation) especializado en responder consultas sobre el sector energético. Utiliza técnicas de recuperación híbrida, reranking y múltiples agentes para proporcionar respuestas precisas y contextualizadas.

Características principales:

  • Hybrid retriever con búsqueda semántica y por palabras clave
  • Reranker para mejorar la relevancia de los documentos recuperados
  • Multi-agent system para verificación y mejora de respuestas
  • Soporte multilingüe con traducción automática
  • Base de datos para tracking de tokens consumidos

Arquitectura

A continuación se muestran tres diagramas que sintetizan los componentes y el funcionamiento del sistema, desde el concepto base de RAG hasta el flujo completo y el subsistema de agentes que valida las respuestas.

1. RAG base

Diagrama de referencia de un sistema RAG estándar. El usuario envía una consulta a la interfaz; el almacén de documentos se vectoriza mediante un modelo de embeddings y se persiste en un vectorstore. En tiempo de consulta, los documentos más relevantes se recuperan y se entregan como contexto al LLM, que genera la respuesta final para el usuario.

RAG base

2. Flujo de información de la arquitectura

Pipeline implementado en este trabajo. La consulta del usuario pasa primero por un agente de idioma que detecta el lenguaje y aplica el prompt template adecuado. Luego se genera una multi-query para enriquecer la búsqueda, se vectoriza con el modelo de embeddings y se consulta el Vector Store aplicando filtros por país. Los documentos recuperados se filtran y ordenan con un reranker, se pasan al LLM como contexto y, finalmente, el modelo de agentes valida la salida. La respuesta final se devuelve en el idioma original detectado.

Flujo de información

3. Modelo de agentes

Subsistema multi-agente encargado de validar y consolidar la respuesta del LLM. La respuesta original generada por el LLM es revisada por un agente verificador que comprueba la evidencia documental. Su salida se entrega al agente de consenso, que recibe además el idioma detectado por el agente de idioma y produce la respuesta final alineada con la consulta del usuario.

Modelo de agentes

Demostración

A continuación se muestra una demostración del sistema funcionando con la interfaz de OpenWebUI conectada al backend RAG:

Demo OpenWebUI

Stack Tecnológico

  • Python 3.9.21
  • FastAPI: Framework web para la API
  • LangChain: Orquestación de LLMs y componentes RAG
  • ChromaDB: Base de datos vectorial
  • Docker: Contenedorización
  • Kubernetes: Orquestación de contenedores

Requisitos Previos

  • Python 3.9.21
  • pyenv (recomendado para gestión de versiones de Python)
  • Docker y Docker Compose (para ejecución en contenedores)
  • kubectl (para despliegue en Kubernetes)

Instalación y Configuración Local

Este proyecto está configurado para funcionar con Python 3.9.21.

1. Crear el entorno virtual con pyenv

# Instalar Python 3.9.21
pyenv install 3.9.21

# Crear el entorno virtual
pyenv virtualenv 3.9.21 env_llm_energy

# Activar el entorno
pyenv activate env_llm_energy

2. Instalar dependencias

pip3 install -r requirements.txt

3. Ejecutar el servidor

uvicorn main:app --reload --port 8000

La API estará disponible en http://localhost:8000


Estructura del Proyecto

A continuación se detallan los archivos y directorios principales del repositorio:

Directorios

Directorio Descripción
/eval Scripts para evaluar los modelos LLMs en distintas tareas del sector energético
/markdowns Documentos markdown utilizados como fuente de conocimiento del sistema

Archivos Principales

Archivo Descripción
agentes.py Agentes que interactúan con el LLM para realizar tareas específicas y mejorar el resultado final
db_utils.py Utilidades para crear y gestionar la base de datos que almacena la cantidad de tokens usados en cada consulta
extra.py Funciones auxiliares para identificar países en las preguntas y formatear los documentos fuente de manera amigable
meta_data.py Funciones para añadir metadatos (país, ruta) a los archivos markdown
vectorstore.py Manejo de embeddings, creación del vectorstore con ChromaDB, hybrid retriever y configuración de prompts
templates.py Templates de prompts utilizados en las distintas interacciones con el LLM
retriever.py Función principal retriever_agent() que maneja la consulta del usuario, detección de idioma, hybrid retriever, reranker y traducción
query_con_agen_idioma.ipynb Notebook de prueba del pipeline completo con la función multi_agent_rag() que orquesta todo el proceso

Flujo Principal

  1. El usuario envía una consulta a través de retriever_agent()
  2. Se detecta el idioma de la consulta
  3. El hybrid retriever busca documentos relevantes
  4. El reranker filtra y ordena los resultados
  5. Los agentes verifican y mejoran la respuesta
  6. La respuesta se traduce al idioma original del usuario

Docker

Ejecutar Localmente con Docker

Construir e iniciar la imagen

docker compose up -d

Detener los contenedores

docker compose down

Reconstruir la imagen después de cambios en el código

docker compose down
docker compose up -d --build

Publicar imagen en Docker Hub

Por primera vez

# Loguearse en Docker Hub
docker login

# Construir la imagen
docker build -t kevmansilla/rag-backend:latest .

# Subir la imagen
docker push kevmansilla/rag-backend:latest

Actualizar imagen existente

# Commitear cambios
git add .
git commit -am "Descripción del cambio"
git push

# Reconstruir y subir
docker build -t kevmansilla/rag-backend:latest .
docker push kevmansilla/rag-backend:latest

Testing con OpenWebUI

Para conectar el backend con OpenWebUI, ambos contenedores deben correr en la misma red de Docker.

1. Crear la red

docker network create ragnet

# Verificar que se creó correctamente
docker network ls

2. Levantar el backend

docker run -d \
  --name rag-backend \
  --network ragnet \
  -p 8000:8000 \
  kevmansilla/rag-backend:latest

3. Levantar OpenWebUI en la misma red

docker run -d \
  --name openwebui-ragnet \
  --network ragnet \
  -p 3000:8080 \
  -e OPENAI_API_BASE_URL=http://rag-backend:8000/v1 \
  ghcr.io/open-webui/open-webui:main

La conexión entre OpenWebUI y el backend RAG se realiza automáticamente mediante la variable de entorno OPENAI_API_BASE_URL.

4. Acceder a la interfaz

http://localhost:3000

5. Ver logs del backend

docker logs -f rag-backend

Actualizar imagen en el servidor

docker compose pull rag-backend
docker compose up -d rag-backend

Primero loguearse en docker hub y crear repo llamado rag-backend

docker login
docker build -t kevmansilla/rag-backend:latest .
docker push kevmansilla/rag-backend:latest

Testear la imagen que subi a docker-hub

Para hacer la conexion con openweb-ui, ambos contenedores deben correr en la misma red de docker. Para esto se puede usar docker compose. Entonces debemos crear la red llamada ragnet

docker network create ragnet

verificamos que la red fue creada con

docker network ls

Levantar el backend

docker run -d \
  --name rag-backend \
  --network ragnet \
  -p 8000:8000 \
  kevmansilla/rag-backend:latest

Levantamos openweb-ui en la misma red

docker run -d \
  --name openwebui-ragnet \
  --network ragnet \
  -p 3000:8080 \
  -e OPENAI_API_BASE_URL=http://rag-backend:8000/v1 \
  ghcr.io/open-webui/open-webui:main

Esto hace la conexion entre openweb-ui y el backend del rag-llm automatico, al agregar la variable de entorno OPENAI_API_BASE_URL con la url del backend. Para acceder a openweb-ui, abrir en el navegador

http://localhost:3000

ver logs del backend

docker logs -f rag-backend

Si hacemos cambios en el codigo y queremos actualizar la imagen en docker-hub

git add .
git commit -am "cambio X"
git push

docker build -t kevmansilla/rag-backend:latest .
docker push kevmansilla/rag-backend:latest

Luego en el server

docker compose pull rag-backend
docker compose up -d rag-backend

Kubernetes

Desplegar en Kubernetes

El despliegue se realiza utilizando el archivo deploy.yaml:

kubectl apply -f deploy.yaml

Asegúrese de tener las credenciales previamente cargadas en kubeconfig.yaml.

Comandos útiles

Ver logs del pod

kubectl logs -f <nombre-del-pod>

Acceder al pod

kubectl exec -it <nombre-del-pod> -- bash

Verificar despliegue

kubectl get pods
kubectl get services

Integración con OpenWebUI

Dado que OpenWebUI ya está desplegado en Kubernetes, la conexión se realiza mediante el servicio externo:

http://rag-backend-serv:8000/v1

Monitoreo

Consultar base de datos de tokens

Para verificar el consumo de tokens del modelo:

En Docker

# Entrar al contenedor
docker exec -it rag-backend-calden bash

# Dentro del contenedor
python - <<EOF
import db_utils
print("Tokens:", db_utils.get_tokens())
EOF

En Kubernetes

# Entrar al pod
kubectl exec -it <nombre-del-pod> -- bash

# Dentro del pod (mismo comando que en Docker)
python - <<EOF
import db_utils
print("Tokens:", db_utils.get_tokens())
EOF

Licencia

Este proyecto está bajo la Licencia MIT.

About

Computer Science Thesis

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors