Asistente Académico Universitario basado en RAG
Arquitectura desacoplada Frontend Java (Swing) ⇄ Backend Python (FastAPI + MongoDB + Gemini)
Nota: el prefijo «ELO» del nombre alude al código de asignaturas de Electrónica (p. ej. ELO-329), dominio sobre el que opera el asistente; no corresponde a un sistema de ranking ELO.
El sistema ELOBOT es una aplicación cliente–servidor con dos límites bien definidos que se comunican exclusivamente por HTTP:
ElobotChat, ElobotApiClient, ChatMessage, Conversation, Theme, RamoCodeNormalizer, AnimatedAvatar, VectorIcon). Es responsable de la interfaz, el modelo de datos en memoria del chat y la orquestación de la interacción con el usuario.api.py, respuestas_bro.py, queries.py) que exponen la API REST, ejecutan la canalización RAG (embeddings + búsqueda vectorial) y orquestan la llamada al LLM.| Componente | Tecnología | Responsabilidad detectada en el código |
|---|---|---|
| Frontend | Java 17 · Swing | Vistas, captura de eventos, historial de conversaciones, temas claro/oscuro, normalización del código de ramo. |
| Backend / API | FastAPI + Uvicorn | Endpoint POST /consultar; valida el cuerpo con Pydantic (Consulta) y delega en la lógica de negocio. |
| Motor RAG | sentence-transformers · NumPy | Genera embeddings de la pregunta y calcula similitud del coseno contra los chunks almacenados. |
| Motor de generación | Google Gemini 2.5 Flash | Produce la respuesta final restringida al contexto recuperado. |
| Actores / Usuarios | — | El Estudiante (único actor humano) formula preguntas; los servicios MongoDB y Gemini actúan como actores/sistemas externos. |
| Persistencia | MongoDB (Docker) | Colección programas_asignaturas: 840 chunks de 84 asignaturas con su vector de embedding. El estado del chat es volátil (en memoria del Frontend). |
ElobotApiClient arma un JSON {"pregunta","codigo_ramo"} y lo envía por HttpClient (HTTP/1.1) al endpoint http://localhost:8001/consultar. La respuesta JSON se parsea manualmente para extraer el campo respuesta.MONGO_URI; pre-filtrado por codigo_asignatura antes del cálculo vectorial.google-genai): llamada a generate_content con rotación de hasta 4 API keys (fallback ante cuota agotada), configuradas en variables de entorno vía python-dotenv.CORSMiddleware con orígenes abiertos, permitiendo el consumo desde clientes heterogéneos..txt) como entrada y exportación de transcripciones de la conversación.Los casos de uso se documentan siguiendo la plantilla revisada en clases, considerando nombre, propósito, actores, precondiciones, evento gatillante, curso normal de eventos, curso alternativo, requerimientos no funcionales y autor. El foco está en describir funcionalidades visibles para el actor principal, evitando detalles internos de implementación.
En este proyecto, el sistema considerado es ELOBOT, un asistente académico universitario para consultar información de asignaturas. El actor principal es el Estudiante, quien interactúa con el sistema mediante una interfaz conversacional.
| Elemento | Descripción |
|---|---|
| 1. Nombre | Consultar información de una asignatura. |
| 2. Propósito | Permitir que el estudiante obtenga información académica de una asignatura específica, como requisitos, contenidos, evaluaciones o bibliografía. |
| 3. Actores | Estudiante. |
| 4. Precondiciones | El sistema ELOBOT se encuentra disponible y posee información académica cargada para consulta. |
| 5. Evento | El estudiante ingresa un código de asignatura y formula una pregunta sobre ella. |
| 6. Curso normal de eventos | Se detalla en la tabla Actor/Sistema presentada a continuación. |
| 7. Curso alternativo de eventos | Si el código tiene un formato no estándar, el sistema intenta normalizarlo. Si no existe información suficiente, el sistema informa que no puede responder con los datos disponibles. Si ocurre un error de conexión, el sistema muestra un mensaje de error controlado. |
| 8. Requerimientos no funcionales | La respuesta debe ser clara, legible y entregarse en un tiempo razonable para mantener una interacción fluida. |
| 9. Autor | Equipo ELOBOT. |
| Actor | Sistema |
|---|---|
| 1. El estudiante ingresa el código de la asignatura. | |
| 2. El estudiante escribe una pregunta sobre la asignatura. | |
| 3. El sistema valida y normaliza el código ingresado. | |
| 4. El sistema busca información académica relacionada con la consulta. | |
| 5. El sistema genera una respuesta basada en la información disponible. | |
| 6. El estudiante revisa la respuesta entregada. |
| Elemento | Descripción |
|---|---|
| 1. Nombre | Realizar búsqueda temática. |
| 2. Propósito | Permitir que el estudiante consulte información académica aunque no conozca el código exacto de una asignatura. |
| 3. Actores | Estudiante. |
| 4. Precondiciones | El sistema ELOBOT se encuentra disponible y posee información académica cargada. |
| 5. Evento | El estudiante realiza una pregunta general sin ingresar un código de asignatura. |
| 6. Curso normal de eventos | Se detalla en la tabla Actor/Sistema presentada a continuación. |
| 7. Curso alternativo de eventos | Si la consulta es demasiado ambigua, el sistema puede entregar una respuesta general o solicitar mayor precisión. Si no se encuentra información relacionada, el sistema informa que no posee antecedentes suficientes. |
| 8. Requerimientos no funcionales | La respuesta debe ser comprensible para el estudiante y consistente con la información académica disponible. |
| 9. Autor | Equipo ELOBOT. |
| Actor | Sistema |
|---|---|
| 1. El estudiante escribe una consulta general sobre un tema académico. | |
| 2. El sistema interpreta la consulta sin restringirla a una asignatura específica. | |
| 3. El sistema busca información académica relacionada con la pregunta. | |
| 4. El sistema entrega una respuesta con la información más relevante encontrada. | |
| 5. El estudiante revisa la respuesta y puede realizar una nueva consulta. |
| Elemento | Descripción |
|---|---|
| 1. Nombre | Revisar historial de conversaciones. |
| 2. Propósito | Permitir que el estudiante retome consultas realizadas durante la sesión de uso. |
| 3. Actores | Estudiante. |
| 4. Precondiciones | El estudiante ha realizado al menos una consulta durante la sesión actual. |
| 5. Evento | El estudiante selecciona una conversación desde el historial o inicia una nueva conversación. |
| 6. Curso normal de eventos | Se detalla en la tabla Actor/Sistema presentada a continuación. |
| 7. Curso alternativo de eventos | Si no existen conversaciones previas, el sistema muestra el historial vacío. Si el estudiante inicia una nueva conversación, el sistema limpia el área actual y conserva la conversación anterior durante la sesión. |
| 8. Requerimientos no funcionales | El historial debe ser simple de usar y no debe interferir con la consulta principal del estudiante. |
| 9. Autor | Equipo ELOBOT. |
| Actor | Sistema |
|---|---|
| 1. El estudiante realiza una consulta en el chat. | |
| 2. El sistema registra la conversación activa durante la sesión. | |
| 3. El estudiante selecciona una conversación previa desde el historial. | |
| 4. El sistema carga los mensajes asociados a esa conversación. | |
| 5. El estudiante revisa la conversación o continúa realizando nuevas consultas. |
ELOBOT adopta una arquitectura desacoplada cliente–servidor. El Frontend Java desconoce por completo la lógica RAG: solo invoca callApi(pregunta, codigo) y recibe texto. El contrato de integración es un único endpoint REST con carga JSON, lo que permite evolucionar cada capa de forma independiente (alta adaptabilidad y portabilidad).
El Frontend aplica composición (la ventana «tiene un» cliente HTTP), agregación (la ventana «tiene muchas» conversaciones y mensajes), el patrón Singleton (Theme) y una clase de utilidad sin estado (RamoCodeNormalizer). El Backend se organiza como módulos funcionales con dependencias unidireccionales.
| Relación | Origen → Destino | Tipo y multiplicidad |
|---|---|---|
| ◆── | ElobotChat → ElobotApiClient | Composición (1 → 1): colaborador final creado por la ventana. |
| ◇── | ElobotChat → Conversation | Agregación (1 → 0..*): historial de conversaciones. |
| ◇── | ElobotChat / Conversation → ChatMessage | Agregación (1 → 0..*): lista de mensajes. |
| - -> | ElobotChat → RamoCodeNormalizer | Dependencia: uso de métodos estáticos. |
| - -> | Todos → Theme | Dependencia: acceso global vía Theme.getInstance(). |
| ──▷ | VectorIcon ⊳ Icon | Realización de interfaz; AnimatedAvatar ⊳ JLabel y ElobotChat ⊳ JFrame: herencia. |
Escenario representativo del caso de uso CU-01: el estudiante consulta información de una asignatura. El diagrama muestra la interacción temporal entre el actor, la interfaz del sistema y los componentes responsables de obtener y presentar la respuesta. Se omiten detalles internos de implementación para mantener el foco en la dinámica funcional del sistema.
Estándar de documentación: el código fuente está auto-documentado en los archivos originales.
Javadoc a nivel de clase y de método (véanse ElobotApiClient, ChatMessage, Conversation, Theme, RamoCodeNormalizer), documentando responsabilidades, patrones aplicados y relaciones de composición/agregación.recuperar_contexto_rag, armar_prompt_llm, consultar_asistente_universitario), describiendo los pasos del pipeline RAG y la estrategia de fallback de claves.Nota de entrega: siguiendo las instrucciones de la cátedra, se omiten los archivos HTML redundantes generados automáticamente por herramientas de Javadoc; el entregable se mantiene limpio y contiene solo el código fuente y esta documentación.
Prueba 01 — Despliegue del Frontend. Verifica que ElobotChat.main inicializa la ventana Swing sin decoración, aplica el look-and-feel del sistema y renderiza el saludo (GREETING) junto al avatar animado, el sidebar de historial y las preguntas rápidas. Valida la construcción correcta de la vista (CU-03) antes de cualquier interacción de red.
Prueba 02 — Procesamiento en el Backend. Se ingresa el código ELO-329 junto a la pregunta. El backend filtra los chunks en MongoDB por codigo_asignatura, calcula similitud coseno y envía el prompt a Gemini con rotación de claves. Valida el flujo RAG completo de CU-01.
Prueba 03 — Validación extremo a extremo. Con el backend activo, se envía una pregunta desde la interfaz Java y se verifica que la respuesta fundamentada aparece en pantalla, que el código se normalizó a ELO-329 y que la conversación queda disponible en el historial. Confirma la integración Java ⇄ Python y los criterios de aceptación de CU-01 y CU-02.
Prueba 04 — Búsqueda global. Con el campo de código vacío, el sistema busca en los 840 chunks sin filtro, aplica deduplicación por asignatura y retorna los ramos más relevantes al tema consultado. Valida el modo de búsqueda global descrito en CU-02.
| Desafío multi-lenguaje | Solución adoptada en el código |
|---|---|
| Integración Java ↔ Python sin acoplamiento | Frontera REST/JSON única (POST /consultar); ElobotApiClient es la única clase que conoce el endpoint. |
| Serialización de datos entre entornos | Escape manual de JSON (esc) al enviar y parser específico (parseRespuesta) que interpreta \n, \t y comillas al recibir. |
| Bloqueo de la interfaz durante la espera de red | La llamada se ejecuta en un Thread aparte y la UI se actualiza con SwingUtilities.invokeLater. |
| Cuotas agotadas del LLM | Rotación secuencial de hasta 4 API keys con fallback y mensaje de error controlado. |
| Alucinaciones del modelo | Prompt restrictivo que obliga a responder solo con el contexto recuperado. |
| Inconsistencia en el código del ramo | RamoCodeNormalizer unifica variantes (elo329, ELO329…) al formato ELO-329 mediante expresión regular. |
No se registran bugs críticos en la versión actual de evaluación. Se documentan, por transparencia de ingeniería, las siguientes condiciones de borde menores:
ElobotApiClient es manual y por posición; asume un único campo respuesta bien formado. Un cambio en el esquema del backend requeriría ajustarlo.localhost), lo que limita el despliegue en otros entornos sin recompilar.Código fuente completo del proyecto, comprimido para navegación portable:
⬇ Descargar ELO-BOT.zip ⎇ Ver en GitHub| Elemento | Descripción |
|---|---|
frontend/ | Código fuente Java (8 clases Swing) desarrollado por el equipo. |
api.py · queries.py · respuestas_bro.py | Backend Python: API REST y motor RAG. |
docker-compose.yml | Automatización del despliegue de MongoDB. |
requirements.txt | Dependencias Python declaradas formalmente. |
README.md | Instrucciones de instalación, despliegue y ejecución. |
.env.example | Plantilla de variables de entorno (claves de Gemini). |
RAMOS_Y_PREGUNTAS.md | Catálogo de las 84 asignaturas y preguntas de prueba. |
Declaradas formalmente en README.md y requirements.txt con sus guías de obtención:
| Dependencia | Rol | Consideración de licencia (según cátedra) |
|---|---|---|
| FastAPI · Uvicorn · Pydantic | API REST del backend | MIT/BSD — permisiva (usar con aviso de copyright). |
| PyMongo · MongoDB | Persistencia vectorial | Apache 2.0 (driver) — permisiva. |
| sentence-transformers · NumPy | Embeddings y álgebra | Apache 2.0 / BSD — permisivas. |
| google-genai (Gemini) | Generación de respuestas | SDK Apache 2.0; el servicio requiere API key y términos de uso propios. |
| Java SE / Swing (JDK 17) | Interfaz gráfica | GPL con Classpath Exception (OpenJDK) — apta para el uso académico. |
Herramientas de instalación referenciadas en el README.md: Docker Desktop, Python 3.10+ y JDK 17 (winget install Microsoft.OpenJDK.17).
.class, .o o binarios intermedios (excluidos vía .gitignore)..env con claves reales se excluye; solo se entrega la plantilla .env.example.