MNEMOS es un sistema de indexación semántica con memoria persistente y capacidades agénticas multimodales. Permite procesar documentos PDF, archivos de audio, videos y contenido de YouTube, proporcionando una interfaz conversacional inteligente para consultar información de estos documentos utilizando modelos de lenguaje grandes (LLMs).
- Citas Persistentes: Referencias interactivas a fuentes que se mantienen al recargar
- Gestión de Modelos: Descarga automática de modelos GGUF y gestión de modelos locales
- Lanzador Automático: Script
launcher.pypara configuración "one-click" en Windows
- PDFs: Extracción de texto y segmentación por páginas
- Audio/Video: Transcripción automática usando Whisper de OpenAI
- YouTube: Descarga y transcripción automática de videos
- Procesamiento Asíncrono: Sistema de colas con Celery para procesamiento en segundo plano
- Búsqueda Híbrida: Combina búsqueda vectorial (70%) y búsqueda de texto completo (30%)
- Embeddings Vectoriales: Utiliza pgvector con índices HNSW para búsquedas rápidas
- Búsqueda de Texto Completo: Implementación con PostgreSQL FTS y configuración en español
- Chunking Inteligente: Segmentación semántica de documentos usando LangChain
Soporte para múltiples proveedores de LLM:
- Groq (Inferencia ultra-rápida LPU)
- OpenAI (GPT-4, GPT-3.5, etc.)
- Anthropic (Claude Sonnet, Claude Opus)
- LM Studio (modelos locales)
- Ollama (modelos locales dockerizados)
- Interfaz Web Moderna: Single Page Application (SPA) construida con Angular 19.
- Diseño Responsivo: Experiencia de usuario fluida en escritorio y móviles.
- Micro-interacciones: Feedback visual inmediato y animaciones suaves.
- API REST: Endpoints completos para integración
- MCP Server: Servidor Model Context Protocol para integración con Claude Desktop
- Sistema de Conversaciones: Gestión de historial de chat con contexto
┌─────────────────────────────────────────────────────────┐
│ Frontend (Angular SPA) │
│ - Puerto 5200 (Dev) / 80 (Prod) │
│ - Gestión de documentos & Chat │
│ - Visualización de fuentes │
└────────────────────┬────────────────────────────────────┘
│
┌────────────────────▼────────────────────────────────────┐
│ Flask Application (API) │
│ - Blueprints: documents, chat, conversations │
│ - Endpoints REST │
└──────┬──────────────────────────────────────┬──────────┘
│ │
┌──────▼──────┐ ┌────────▼──────────┐
│ Celery │ │ RAG Service │
│ Worker │ │ - Búsqueda │
│ │ │ - Generación │
│ - PDF Proc. │ └─────────┬─────────┘
│ - Transcr. │ │
│ - Embedding │ ┌─────────▼─────────┐
└──────┬──────┘ │ PostgreSQL + │
│ │ pgvector │
└────────────────────────────► │
│ - Documentos │
│ - Chunks │
│ - Conversaciones │
└───────────────────┘
- id: UUID único
- filename: Nombre del archivo almacenado
- original_filename: Nombre original del archivo
- file_type: Tipo (pdf, audio, video, youtube)
- file_path: Ruta en el sistema de archivos
- youtube_url: URL de YouTube (si aplica)
- status: Estado (pending, processing, completed, error)
- metadata_: Metadatos JSON (duración, páginas, etc.)
- id: UUID único
- document_id: Referencia al documento
- content: Texto del fragmento
- chunk_index: Orden del fragmento
- start_time/end_time: Marcas de tiempo para audio/video
- page_number: Número de página para PDFs
- embedding: Vector de embeddings (384 dimensiones por defecto)
- search_vector: Vector de búsqueda de texto completo (PostgreSQL TSVECTOR)
- Sistema de conversaciones con mensajes de usuario y asistente
- Almacenamiento de fuentes utilizadas en cada respuesta
- Gestión de historial completo
RAGService (app/services/rag.py)
Motor principal de RAG que implementa:
- Búsqueda híbrida combinando similitud coseno y ranking de texto completo
- Construcción de contexto con información de fuentes
- Generación de respuestas usando LLMs
- Formato de tiempo para referencias de audio/video
LLMClient (app/services/llm_client.py)
Cliente unificado para múltiples proveedores de LLM:
- Abstracción de APIs de OpenAI, Anthropic, LM Studio y Ollama
- Manejo consistente de mensajes y respuestas
- Logging detallado para debugging
EmbedderService (app/services/embedder.py)
Generación de embeddings vectoriales:
- Soporte local con sentence-transformers
- Soporte remoto con OpenAI/LM Studio/Ollama
- Procesamiento por lotes con reintentos automáticos
- Cache de modelos para eficiencia
TranscriptionService (app/services/transcription.py)
Transcripción de audio/video usando Whisper:
- Soporte para múltiples modelos (tiny, base, small, medium, large-v3)
- Segmentación con marcas de tiempo
- Soporte CPU y GPU
ChunkerService (app/services/chunker.py)
Segmentación inteligente de texto:
- Utiliza RecursiveCharacterTextSplitter de LangChain
- Configuración de tamaño y solapamiento personalizables
- Respeta límites semánticos (párrafos, líneas, palabras)
PDFProcessor (app/services/pdf_processor.py)
Procesamiento de documentos PDF:
- Extracción de texto usando PyMuPDF
- Mantenimiento de información de páginas
- Filtrado de páginas vacías
YouTubeService (app/services/youtube.py)
Descarga y procesamiento de videos de YouTube:
- Descarga de audio usando yt-dlp
- Conversión a formato WAV
- Extracción de metadatos (título, duración)
- Sistema Operativo: Windows 10/11
- Hardware:
- CPU: Compatible con versiones modernas de AVX
- GPU (Opcional): NVIDIA con soporte CUDA para aceleración
- RAM: 8GB mínimo (16GB recomendado)
- Software:
- Ninguno pre-instalado (el instalador gestionará Podman/Docker)
- Opcional: Docker Desktop ya instalado
Hemos simplificado el proceso al máximo. Simplemente:
- Ejecuta el archivo
installer.bat(doble clic). - El script detectará si tienes Docker o Podman. Si no tienes ninguno, instalará Podman automáticamente.
- Detectará automáticamente tu tarjeta gráfica y te preguntará si quieres usarla.
- Listo. La aplicación se iniciará.
El instalador se encarga de todo:
- Descarga e instalación de Podman (si es necesario)
- Configuración de WSL2 (si es necesario)
- Detección de hardware (CPU vs GPU)
- Despliegue de contenedores
- Clonar el repositorio:
git clone <repository-url>
cd mnemos- Copiar y configurar variables de entorno:
cp .env.example .env- Editar el archivo
.envcon tus configuraciones:
# Proveedor de LLM (openai, anthropic, lm_studio, ollama)
LLM_PROVIDER=lm_studio
# Groq (Inferencia Rápida)
GROQ_API_KEY=tu-clave-api
GROQ_MODEL=llama-3.3-70b-versatile
# OpenAI (si se usa)
OPENAI_API_KEY=tu-clave-api
OPENAI_MODEL=gpt-4o-mini
# Anthropic (si se usa)
ANTHROPIC_API_KEY=tu-clave-api
ANTHROPIC_MODEL=claude-sonnet-4-20250514
# LM Studio / Local
LOCAL_LLM_BASE_URL=http://host.docker.internal:1234/v1
LOCAL_LLM_MODEL: local-model
# Configuración de Embeddings
EMBEDDING_PROVIDER=local
EMBEDDING_MODEL=bge-m3
EMBEDDING_DIMENSION=1024
EMBEDDING_DEVICE=cuda
EMBEDDING_BATCH_SIZE=0 # Auto
# Configuración de Whisper
WHISPER_MODEL=base
WHISPER_DEVICE=cpu
# Clave secreta (cambiar en producción)
SECRET_KEY=tu-clave-secreta-seguraOpción A: Estándar (Recomendado si tienes GPU NVIDIA)
# Construir e iniciar todos los servicios
docker-compose up -d --buildOpción B: CPU / Sin GPU NVIDIA Si tu equipo no tiene una tarjeta gráfica NVIDIA compatible con CUDA, usa esta configuración para evitar errores al iniciar:
# Usar el archivo de configuración adicional para CPU
docker-compose -f docker-compose.yml -f docker-compose.cpu.yml up -d --build# Ver logs
docker-compose logs -f app
# Detener servicios
docker-compose down
# Detener y eliminar volúmenes (CUIDADO: elimina datos)
docker-compose down -vEl sistema despliega los siguientes contenedores:
- app (puerto 5000): Aplicación Flask principal
- worker: Worker de Celery para procesamiento en segundo plano
- db (puerto 5432): PostgreSQL 16 con extensión pgvector
- redis (puerto 6379): Cola de mensajes para Celery
- ollama (puerto 11435): Servidor Ollama para LLMs locales (opcional)
- mcp (puerto 3000): Servidor MCP para integración con Claude Desktop
Acceder a http://localhost:5200 (o el puerto configurado).
- Ir a la sección "Documents"
- Elegir archivo PDF, audio, video, o pegar URL de YouTube
- El documento se procesará automáticamente
- El estado se actualiza en tiempo real (pending → processing → completed)
- Ir a la sección "Chat"
- Escribir pregunta en el cuadro de texto
- Opcionalmente seleccionar documentos específicos
- El sistema buscará información relevante y generará una respuesta
- Las fuentes se muestran con referencias a documentos y ubicaciones
- Ver historial de conversaciones
- Continuar conversaciones previas
- Eliminar conversaciones
# Subir archivo
curl -X POST http://localhost:5000/api/documents/upload \
-F "file=@documento.pdf"
# Procesar YouTube
curl -X POST http://localhost:5000/api/documents/upload \
-F "youtube_url=https://www.youtube.com/watch?v=VIDEO_ID"curl http://localhost:5000/api/documents/curl -X POST http://localhost:5000/api/chat/ \
-H "Content-Type: application/json" \
-d '{
"question": "¿Cuál es el tema principal del documento?",
"document_ids": ["uuid-del-documento"],
"top_k": 5
}'curl -X DELETE http://localhost:5000/api/documents/{document_id}El servidor MCP permite integrar el sistema RAG con Claude Desktop.
Editar el archivo de configuración de Claude Desktop:
MacOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"mnemos-daemon": {
"command": "docker",
"args": [
"exec",
"-i",
"rag_app-mcp-1",
"python",
"-m",
"app.mcp_server.server"
]
}
}
}-
search_documents: Buscar información en documentos
query: Pregunta a realizardocument_ids: IDs de documentos específicos (opcional)top_k: Número de chunks a usar (default: 5)
-
list_documents: Listar todos los documentos disponibles con sus IDs
Editar config/settings.py:
CHUNK_SIZE: int = 512 # Tamaño de fragmento
CHUNK_OVERLAP: int = 50 # Solapamiento entre fragmentosOpciones disponibles: tiny, base, small, medium, large-v3
WHISPER_MODEL=medium
WHISPER_DEVICE=cuda # Usar GPU si está disponibleEl sistema ajusta automáticamente el tamaño del lote según la VRAM disponible. Configurable en config/settings.py:
EMBEDDING_BATCH_SIZE: int = 0 # 0 = auto-detectar
EMBEDDING_USE_FP16: bool = True # Usar precisión media (más rápido)Ajustar pesos en app/services/rag.py:
# Cambiar proporción vector/keyword
hybrid_score = (similarity * 0.8) + (rank * 0.2) # Más peso a vectoresEl archivo docker-compose.yml ya incluye configuración GPU:
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [ gpu ]Asegurarse de tener nvidia-docker instalado.
rag_app/
├── app/
│ ├── __init__.py # Factory de aplicación Flask
│ ├── web.py # Rutas web
│ ├── extensions.py # Inicialización de extensiones
│ ├── api/
│ │ ├── documents.py # API de documentos
│ │ ├── chat.py # API de chat
│ │ ├── conversations.py # API de conversaciones
│ │ └── settings.py # API de configuración
│ ├── models/
│ │ ├── document.py # Modelo de documento
│ │ ├── chunk.py # Modelo de fragmento
│ │ └── conversation.py # Modelos de conversación
│ ├── services/
│ │ ├── rag.py # Servicio RAG principal
│ │ ├── llm_client.py # Cliente LLM
│ │ ├── embedder.py # Generación de embeddings
│ │ ├── chunker.py # Segmentación de texto
│ │ ├── pdf_processor.py # Procesamiento PDF
│ │ ├── transcription.py # Transcripción de audio
│ │ └── youtube.py # Descarga de YouTube
│ ├── tasks/
│ │ └── processing.py # Tareas Celery
│ ├── mcp_server/
│ │ └── server.py # Servidor MCP
│ └── static/ # Archivos estáticos API
├── frontend_spa/ # Código fuente Angular
│ ├── src/
│ │ ├── app/ # Componentes y Lógica
│ │ └── assets/ # Imágenes y recursos
│ ├── angular.json
│ └── package.json
├── config/
├── config/
│ └── settings.py # Configuración centralizada
├── media/ # Archivos multimedia de ejemplo
├── ollama_models/ # Modelos Ollama
├── docker-compose.yml # Orquestación Docker
├── Dockerfile # Imagen Docker
├── requirements.txt # Dependencias Python
└── .env.example # Plantilla de variables de entorno
- Flask: Framework web
- SQLAlchemy: ORM para base de datos
- Celery: Procesamiento asíncrono de tareas
- Redis: Cola de mensajes
- PostgreSQL 16: Base de datos principal
- pgvector: Extensión para búsqueda vectorial
- HNSW Index: Índice vectorial de alto rendimiento
- GIN Index: Índice para búsqueda de texto completo
- OpenAI Whisper: Transcripción de audio
- sentence-transformers: Embeddings locales
- LangChain: Segmentación de texto
- OpenAI / Anthropic: LLMs en la nube
- Ollama / LM Studio: LLMs locales
- PyMuPDF: Extracción de PDF
- yt-dlp: Descarga de YouTube
- pydub: Manipulación de audio
- tiktoken: Tokenización
- Angular 19: Framework SPA moderno y robusto.
- TailwindCSS: Diseño utilitario para estilos rápidos y consistentes.
- RxJS: Gestión reactiva de datos y eventos.
- Markdown-to-HTML: Renderizado seguro de respuestas del chat.
Verificar logs del worker:
docker-compose logs -f workerVerificar conexión a Redis:
docker-compose exec worker redis-cli -h redis pingSi usas proveedor local y el modelo no descarga:
docker-compose exec worker python -c "from sentence_transformers import SentenceTransformer; SentenceTransformer('all-MiniLM-L6-v2')"Verificar extensión pgvector:
docker-compose exec db psql -U raguser -d ragdb -c "CREATE EXTENSION IF NOT EXISTS vector;"Si hay errores de memoria con Whisper:
- Usar modelo más pequeño:
WHISPER_MODEL=tinyobase - Aumentar memoria del contenedor en docker-compose.yml
Asegurar que LM Studio está:
- Ejecutándose en el host
- Escuchando en puerto 1234
- Con CORS habilitado
- URL correcta en .env:
http://host.docker.internal:1234/v1
docker-compose exec db pg_dump -U raguser ragdb > backup.sqlcat backup.sql | docker-compose exec -T db psql -U raguser ragdbLos archivos se eliminan automáticamente al borrar documentos, pero para limpiar manualmente:
docker-compose exec app python -c "
from app import create_app
from app.models.document import Document
from app.extensions import db
import os
app = create_app()
with app.app_context():
docs = Document.query.all()
doc_files = {d.file_path for d in docs if d.file_path}
upload_dir = '/app/uploads'
for f in os.listdir(upload_dir):
if f not in doc_files:
print(f'Deleting orphan: {f}')
os.remove(os.path.join(upload_dir, f))
"# Reconstruir imágenes
docker-compose build --no-cache
# Reiniciar servicios
docker-compose up -d- Cambiar SECRET_KEY: Generar clave segura
python -c "import secrets; print(secrets.token_hex(32))"-
Configurar HTTPS: Usar nginx o traefik como reverse proxy
-
Límites de tamaño: Ajustar
MAX_CONTENT_LENGTHsegún necesidades -
Autenticación: Implementar autenticación de usuarios (no incluida por defecto)
-
Variables de entorno: No commitear
.enval repositorio -
Actualizaciones: Mantener dependencias actualizadas
Este proyecto es de código abierto y está disponible bajo la licencia GNU Affero General Public License v3.0 (AGPLv3). Consulte el archivo LICENSE para más detalles.
Las contribuciones son bienvenidas. Por favor:
- Fork del repositorio
- Crear rama de feature (
git checkout -b feature/AmazingFeature) - Commit de cambios (
git commit -m 'Add AmazingFeature') - Push a la rama (
git push origin feature/AmazingFeature) - Abrir Pull Request
Funcionalidades planeadas:
- Soporte para EPUB (Incluyendo metadatos)
- Soporte para más formatos de documentos (Word, Excel, PowerPoint)
- Procesamiento de imágenes con modelos multimodales
- Exportación de conversaciones