Aplicación web full stack de chatbot personal con IA generativa, memoria conversacional, RAG (Retrieval-Augmented Generation) y búsqueda en internet.
- Características
- Arquitectura
- Stack Tecnológico
- Requisitos Previos
- Instalación
- Configuración
- Ejecución
- Testing
- Build para Producción
- API Reference
- Estructura del Proyecto
- Posibles Mejoras
- Contribución
- Licencia
- Conversaciones ilimitadas con historial persistente
- Streaming en tiempo real de respuestas del asistente vía WebSocket
- Títulos autogenerados para cada conversación
- Selector de modelo por mensaje: elige entre
gpt-5-nano,gpt-5-miniogpt-5 - Sidebar de conversaciones con fechas formateadas (
dd/MM/yyyy HH:mm)
- Memoria de corto plazo: historial de conversación por thread usando
PostgresSaver - Memoria de largo plazo: preferencias y datos del usuario persistidos cross-conversation usando
PostgresStore - Summarization automático: resume conversaciones largas para mantener el contexto sin exceder límites
- Base de conocimiento indexada desde documentos Markdown en
/docs - Embeddings con
text-embedding-3-smallde OpenAI - Base vectorial PGVector integrada en PostgreSQL
- Reindexado bajo demanda vía endpoint REST
- Retrieval agentic: el modelo decide cuándo consultar la base documental
- Redacción de PII: información sensible redactada antes de enviar al LLM
- Búsqueda en internet: tool TavilySearch integrada
- Observabilidad completa con LangSmith
- Request tracking con
x-request-iden todas las respuestas
- Angular 21 con arquitectura basada en signals
- Tailwind CSS v4 para estilos modernos y responsive
- Accesibilidad WCAG AA: landmarks, foco visible, contraste
- Estados de carga y error bien manejados
┌─────────────────────────────────────────────────────────────────────────────┐
│ FRONTEND (Angular 21) │
├─────────────────────────────────────────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Sidebar │ │ Chat Thread │ │ Composer │ │ Model Sel. │ │
│ │ Conversations│ │ Messages │ │ Input/Send │ │ nano/mini/5 │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │ │
│ └─────────────────┴─────────────────┴──────────────────┘ │
│ │ │
│ ┌─────────┴─────────┐ │
│ │ ChatUiStore │ │
│ │ (Signals/State) │ │
│ └─────────┬─────────┘ │
│ │ │
│ ┌───────────────┼───────────────┐ │
│ │ │ │ │
│ ┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐ │
│ │ REST API │ │ WebSocket │ │ Stream │ │
│ │ Service │ │ Service │ │ Service │ │
│ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ │
└────────────────────┼───────────────┼───────────────┼────────────────────────┘
│ │ │
└───────────────┼───────────────┘
│
┌────────────────────────────────────┼────────────────────────────────────────┐
│ BACKEND (FastAPI) │
├────────────────────────────────────┼────────────────────────────────────────┤
│ │ │
│ ┌─────────────┐ ┌────────────────┴────────────────┐ ┌─────────────┐ │
│ │ REST │ │ WebSocket │ │ RAG │ │
│ │ Routers │ │ /assistant/stream │ │ Indexing │ │
│ └──────┬──────┘ └────────────────┬────────────────┘ └──────┬──────┘ │
│ │ │ │ │
│ └──────────────────────────┼──────────────────────────┘ │
│ │ │
│ ┌─────────┴─────────┐ │
│ │ LangChain Agent │ │
│ │ (create_agent) │ │
│ └─────────┬─────────┘ │
│ │ │
│ ┌───────────────────────────────┼───────────────────────────────┐ │
│ │ │ │ │
│ ┌──┴──┐ ┌──────┐ ┌──────┐ ┌────┴────┐ ┌──────┐ ┌──────────┐ │ │
│ │Tools│ │Memory│ │ RAG │ │ OpenAI │ │ PII │ │Summarize │ │ │
│ │Tavi.│ │Short │ │Tool │ │ Models │ │Redact│ │Middleware│ │ │
│ │Prefs│ │Long │ │ │ │ │ │ │ │ │ │ │
│ └──┬──┘ └──┬───┘ └──┬───┘ └────┬────┘ └──┬───┘ └────┬─────┘ │ │
│ │ │ │ │ │ │ │ │
│ └────────┴─────────┴───────────┴──────────┴───────────┘ │ │
│ │ │ │
└───────────────────────────────────┼────────────────────────────────┴────────┘
│
┌───────────────────────────────────┼─────────────────────────────────────────┐
│ PostgreSQL 17 + PGVector │
├───────────────────────────────────┼─────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────┼──────────────┐ ┌──────────────────┐ │
│ │ conversation │ │ message │ │ │ langchain_* │ │
│ │ table │ │ table │ │ │ (checkpoints) │ │
│ └──────────────┘ └──────────────┘ │ └──────────────────┘ │
│ │ │
│ ┌───────────────────────────────────────────────┴───────────────────┐ │
│ │ PGVector (embeddings) │ │
│ │ docs_knowledge_base collection │ │
│ └───────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
| Tecnología | Versión | Propósito |
|---|---|---|
| Python | 3.13 | Runtime |
| FastAPI | 0.133 | Framework web |
| SQLModel | 0.0.37 | ORM |
| LangChain | 1.2 | Orquestación IA |
| LangGraph | - | Agentes y memoria |
| PostgreSQL | 17 | Base de datos |
| PGVector | - | Embeddings vectoriales |
| uv | - | Gestor de dependencias |
| Tecnología | Versión | Propósito |
|---|---|---|
| Node.js | 24 | Runtime |
| Angular | 21.2 | Framework |
| Tailwind CSS | 4.2 | Estilos |
| RxJS | 7.8 | Reactividad |
| Vitest | 4.0 | Testing |
| Servicio | Propósito |
|---|---|
| OpenAI GPT-5 | Modelos de chat |
| OpenAI Embeddings | text-embedding-3-small |
| Tavily | Búsqueda en internet |
| LangSmith | Observabilidad |
- Docker y Docker Compose (para PostgreSQL)
- Python 3.13+ con uv
- Node.js 24+ con npm
- Cuentas y API Keys:
- OpenAI API Key
- Tavily API Key (opcional, para búsquedas web)
- LangSmith API Key (opcional, para observabilidad)
git clone https://github.com/tu-usuario/genai-fullstack.git
cd genai-fullstackcd backend
# Instalar dependencias con uv
uv sync
# Copiar archivo de configuración
cp .env.example .envcd frontend
# Instalar dependencias
npm installEdita el archivo backend/.env con tus credenciales:
# OpenAI (requerido)
OPENAI_API_KEY=sk-...
# Tavily (opcional - para búsquedas web)
TAVILY_API_KEY=tvly-...
# LangSmith (opcional - para observabilidad)
LANGSMITH_TRACING=true
LANGSMITH_API_KEY=...
LANGSMITH_ENDPOINT=https://eu.api.smith.langchain.com
# Embeddings y RAG
OPENAI_EMBEDDINGS_MODEL=text-embedding-3-small
RAG_COLLECTION_NAME=docs_knowledge_base
RAG_TOP_K=4
RAG_CHUNK_SIZE=1200
RAG_CHUNK_OVERLAP=200
RAG_DOCS_PATH=docs
# PostgreSQL
DATABASE_URL=postgresql+psycopg://postgres:postgres@localhost:5434/postgres
TEST_DATABASE_URL=postgresql+psycopg://postgres:postgres@localhost:5434/postgres| Modelo | Descripción |
|---|---|
gpt-5-nano |
Modelo rápido y económico (default) |
gpt-5-mini |
Balance entre velocidad y capacidad |
gpt-5 |
Máxima capacidad |
cd backend
docker-compose up -dVerifica que está corriendo:
docker ps
# Deberías ver el contenedor 'pgvector' corriendo en el puerto 5434cd backend
uv run fastapi dev main.pyEl servidor estará disponible en: http://localhost:8000
- Documentación API:
http://localhost:8000/docs - Health check:
http://localhost:8000/health
cd frontend
npm startLa aplicación estará disponible en: http://localhost:4200
Para habilitar el RAG sobre la base documental:
curl -X POST http://localhost:8000/api/v1/rag/reindexRespuesta esperada:
{
"documents_indexed": 4,
"chunks_indexed": 25,
"collection_name": "docs_knowledge_base",
"docs_path": "docs",
"duration_ms": 1234
}cd backend
# Ejecutar todos los tests
uv run pytest
# Tests de persistencia
uv run pytest tests/persistence -v
# Tests de API
uv run pytest tests/api -v
# Tests unitarios
uv run pytest tests/unit -v
# Con cobertura
uv run pytest --cov=. --cov-report=htmlcd frontend
# Tests unitarios
npm test
# Tests en modo watch
npm test -- --watch
# Smoke test de integración con backend
npm run test:integration:backend-
Levantar el sistema completo (PostgreSQL + Backend + Frontend)
-
Verificar flujo de chat:
- Abrir
http://localhost:4200 - Crear una nueva conversación
- Enviar un mensaje
- Verificar streaming de respuesta
- Verificar autogeneración de título
- Cambiar modelo y enviar otro mensaje
- Abrir
-
Verificar RAG:
- Invocar
POST /api/v1/rag/reindex - Preguntar sobre productos de "Aurora Dynamics"
- Verificar que la respuesta usa información de los docs
- Invocar
-
Verificar memoria de largo plazo:
- Pedir que recuerde una preferencia
- Crear nueva conversación
- Verificar que recuerda la preferencia anterior
-
Verificar persistencia en DB:
docker exec -it pgvector psql -U postgres -d postgresSELECT id, title, user_id, created_at FROM conversation ORDER BY created_at DESC LIMIT 10; SELECT id, conversation_id, role, substring(content, 1, 50), model FROM message ORDER BY created_at DESC LIMIT 20;
cd backend
# Verificar que todo pasa
uv run pytest
uv run ruff check .
# El backend se despliega como aplicación FastAPI estándar
# Ejemplo con gunicorn:
uv run gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorkercd frontend
# Build de producción
npm run build
# Los archivos estarán en dist/frontend/browser/| Método | Endpoint | Descripción |
|---|---|---|
POST |
/api/v1/conversations |
Crear conversación |
GET |
/api/v1/conversations |
Listar conversaciones |
GET |
/api/v1/conversations/{id} |
Obtener conversación |
PATCH |
/api/v1/conversations/{id} |
Actualizar conversación |
DELETE |
/api/v1/conversations/{id} |
Eliminar conversación |
| Método | Endpoint | Descripción |
|---|---|---|
POST |
/api/v1/conversations/{id}/messages |
Crear mensaje |
GET |
/api/v1/conversations/{id}/messages |
Listar mensajes |
GET |
/api/v1/messages/{id} |
Obtener mensaje |
DELETE |
/api/v1/messages/{id} |
Eliminar mensaje |
| Endpoint | Descripción |
|---|---|
WS /api/v1/conversations/{id}/assistant/stream |
Stream de respuesta del asistente |
Eventos WebSocket:
assistant_token: Token parcial de respuestaassistant_done: Respuesta completaconversation_title_updated: Título actualizadoassistant_error: Error en la generación
| Método | Endpoint | Descripción |
|---|---|---|
POST |
/api/v1/rag/reindex |
Reindexar documentos |
genai-fullstack/
├── backend/
│ ├── api/ # Dependencias de API
│ ├── models/ # Modelos SQLModel
│ │ ├── conversation.py
│ │ └── message.py
│ ├── routers/ # Endpoints REST/WS
│ │ ├── conversations.py
│ │ ├── messages.py
│ │ ├── chat_stream.py
│ │ └── rag_indexing.py
│ ├── schemas/ # DTOs Pydantic
│ ├── services/ # Lógica de negocio
│ │ ├── langchain_agent.py
│ │ ├── conversation_title_service.py
│ │ ├── long_term_memory.py
│ │ ├── rag_indexing_service.py
│ │ ├── rag_retrieval_service.py
│ │ ├── pii_redaction.py
│ │ └── tools_registry.py
│ ├── tests/
│ │ ├── api/
│ │ ├── persistence/
│ │ └── unit/
│ ├── db.py # Configuración BD
│ ├── settings.py # Settings de la app
│ ├── main.py # Punto de entrada
│ ├── docker-compose.yml
│ └── requirements.txt
├── frontend/
│ └── src/app/
│ ├── chat/
│ │ ├── application/ # Stores y facades
│ │ ├── data-access/ # Servicios API
│ │ ├── models/ # Tipos TypeScript
│ │ └── ui/ # Componentes
│ └── shared/ # Utilidades compartidas
├── docs/ # Documentos para RAG
│ ├── aurora-dynamics-company-profile.md
│ ├── lumabuds-and-firmware.md
│ ├── nebulabook-and-docks.md
│ └── warranty-and-rma-policy.md
└── README.md
| Mejora | Descripción | Complejidad |
|---|---|---|
| Autenticación | OAuth2/JWT con gestión de usuarios | Media |
| Multitenancy | Aislamiento de datos por organización | Alta |
| File Upload | Subir documentos para RAG desde UI | Media |
| Code Interpreter | Ejecutar código Python en sandbox | Alta |
| Plugins/MCP | Integración con herramientas externas vía MCP | Media |
| Voice Input | Whisper para entrada de voz | Media |
| Export/Import | Exportar conversaciones a JSON/MD | Baja |
| Mejora | Descripción | Complejidad |
|---|---|---|
| RAG Incremental | Sync por checksum en vez de full reindex | Media |
| Hybrid Search | Combinar búsqueda vectorial + BM25 | Media |
| Reranking | Cross-encoder para mejorar relevancia | Media |
| Multi-modal | Soporte para imágenes con GPT-4V | Media |
| Fine-tuning | Modelos customizados por dominio | Alta |
| Caching | Redis para respuestas frecuentes | Baja |
| Rate Limiting | Control de uso por usuario/API key | Baja |
| Mejora | Descripción | Complejidad |
|---|---|---|
| Kubernetes | Despliegue en K8s con Helm charts | Alta |
| CI/CD | GitHub Actions para tests y deploy | Media |
| Monitoring | Prometheus + Grafana dashboards | Media |
| CDN | Servir frontend desde CDN | Baja |
| SSR/Prerender | Server-side rendering para SEO | Media |
| Mejora | Descripción | Complejidad |
|---|---|---|
| Dark Mode | Tema oscuro con toggle | Baja |
| i18n | Internacionalización (EN/ES) | Media |
| Shortcuts | Atajos de teclado | Baja |
| Markdown | Renderizado de Markdown en respuestas | Baja |
| Code Highlight | Syntax highlighting en bloques de código | Baja |
| PWA | Instalable como app | Media |
- Fork el repositorio
- Crea una rama para tu feature (
git checkout -b feature/amazing-feature) - Commit tus cambios (
git commit -m 'Add amazing feature') - Push a la rama (
git push origin feature/amazing-feature) - Abre un Pull Request
- Sigue el estilo de código existente
- Añade tests para nuevas funcionalidades
- Actualiza la documentación según sea necesario
- Usa commits descriptivos y concisos
Este proyecto está bajo la Licencia MIT.