Bot RAG para Discord configurable, capaz de responder preguntas usando una base de conocimiento local con Ollama y ChromaDB, optimizado para hardware modesto.
El proyecto está pensado para que una persona pueda clonarlo, ajustar .env, añadir sus documentos, ejecutar /sync_knowledge y empezar a usar /ai sin tocar el código.
Si solo te interesa poner el bot en marcha rápido, esto es lo único que debes modificar después de clonar el repo:
| Archivo / Carpeta | Qué cambiar |
|---|---|
.env |
Copia .env.example a .env y pega tu token de Discord. Opcionalmente puedes definir los modelos que tengas en Ollama mediante variables de entorno (ver sección Configuración) |
knowledge_base/ |
Añadir tus archivos .md o .txt con la información que el bot debe conocer |
Todo lo demás (comportamiento del bot, chunking, prompt, etc.) tiene valores por defecto razonables y listos para usar.
El bot responde en Discord a partir de documentos locales en formato .md y .txt.
Flujo básico:
- Un usuario pregunta con
/ai. - El bot busca fragmentos relevantes en ChromaDB.
- Envía esos fragmentos como contexto a un modelo local en Ollama.
- Devuelve la respuesta en Discord.
No indexa documentos al arrancar. La indexación se hace manualmente con /sync_knowledge.
RAG significa Retrieval-Augmented Generation.
En este proyecto quiere decir que el modelo no responde solo con su conocimiento interno. Primero se recuperan fragmentos de tus documentos locales y después el modelo genera una respuesta usando ese contexto.
Esto permite cambiar el conocimiento del bot modificando archivos, sin reentrenar modelos.
- Slash command
/aipara hacer preguntas. - Slash command
/sync_knowledgepara reindexar manualmente. - Base de conocimiento local en archivos
.mdy.txt. - ChromaDB como base vectorial persistente.
- Ollama para chat y embeddings locales.
- Modelo de chat y modelo de embeddings configurables por separado.
- Cola simple para procesar una generación pesada a la vez.
- Estados visibles: búsqueda, procesamiento y posición en cola.
- Límite de hilos configurable con
num_thread. - División automática de respuestas largas para Discord.
- Caché simple para preguntas repetidas.
- Sin secretos en el código.
- 100% Contenedorizado: Se ejecuta mediante Docker y Docker Compose, funcionando de forma idéntica en Linux, macOS y Windows.
discord-rag-bot/
├─ Dockerfile
├─ docker-compose.yml
├─ pyproject.toml
├─ requirements.txt
├─ .gitignore
├─ .dockerignore
├─ .env.example
├─ config.example.json
├─ README.md
├─ LICENSE
├─ knowledge_base/
│ └─ .gitkeep
└─ src/
├─ bot.py
├─ config.py
├─ indexer.py
├─ rag.py
└─ utils.py
- Docker y Docker Compose instalados en el sistema (ej. Docker Desktop para Windows/macOS, o Docker Engine + Compose plugin para Linux).
- Ollama instalado y funcionando en la máquina host.
- Una cuenta de Discord.
- Un bot creado en el Discord Developer Portal.
El bot usa slash commands, así que no necesita activar el privileged intent de contenido de mensajes.
git clone https://github.com/samu-tec/discord-rag-bot.git
cd discord-rag-botInstala Ollama en la máquina host desde ollama.com/download.
Asegúrate de tener descargados los modelos definidos (por defecto qwen2.5:1.5b y nomic-embed-text):
ollama pull qwen2.5:1.5b
ollama pull nomic-embed-textImportant
Nota para usuarios de Linux:
Por defecto, el servicio de Ollama en Linux escucha únicamente en 127.0.0.1 (localhost), por lo que el contenedor Docker no podrá acceder a él. Debes configurar Ollama para que escuche en todas las interfaces:
- Ejecuta
sudo systemctl edit ollama.service. - Añade las siguientes líneas en el editor que se abrirá:
[Service] Environment="OLLAMA_HOST=0.0.0.0"
- Guarda y cierra el archivo.
- Recarga systemd y reinicia Ollama:
sudo systemctl daemon-reload sudo systemctl restart ollama
Hemos incluido scripts opcionales que preparan los archivos de configuración y arrancan el bot en Docker Compose con un solo comando.
Note
Sobre las restricciones en macOS/Windows: Dado que estos scripts se ejecutan en tu host local, los sistemas operativos pueden restringir su ejecución inicial por seguridad:
- En macOS: Para dar permisos de ejecución al script antes de poder usarlo, abre la terminal y ejecuta
chmod +x start-linux-mac.sh. - En Windows: Al hacer doble clic en
start-windows.bat, Windows SmartScreen puede mostrar una advertencia ("Windows protegió su PC"). Puedes hacer clic en "Más información" y luego en "Ejecutar de todas formas" de manera completamente segura ya que puedes leer el código plano del script.
En Linux / macOS:
./start-linux-mac.shEn Windows:
Haz doble clic en start-windows.bat o ejecútalo en la consola de comandos:
start-windows.batSi prefieres no ejecutar scripts locales en tu máquina por seguridad o simplicidad, puedes levantar el bot usando comandos nativos de Docker de forma directa:
- Crear el archivo
.env:- Linux/macOS:
cp .env.example .env - Windows (PowerShell):
Copy-Item .env.example .env - Windows (CMD):
copy .env.example .env
- Linux/macOS:
- Editar el archivo
.envpara colocar tu token en la líneaDISCORD_TOKEN=tu-token-aqui. - Crear las carpetas de datos:
mkdir knowledge_base chroma_db
- Iniciar el bot:
docker compose up -d --build
- Ver estado del servicio:
docker compose ps - Ver los logs en tiempo real:
docker compose logs -f - Detener el bot:
docker compose down
Entra en discord.com/developers/applications.
Pulsa New Application, ponle un nombre y crea la aplicación.
Dentro de la aplicación, entra en Bot y crea el bot si todavía no existe.
En la sección Bot, pulsa Reset Token, copia el token nuevo y guárdalo en tu archivo .env.
Trata el token como una contraseña:
- No lo subas a GitHub (el
.gitignoreya excluye el.env). - No lo compartas con nadie.
- Si se filtra, vuelve al portal, haz un Reset Token, actualiza el
.envy reinicia el contenedor (docker compose restart).
En el portal de Discord, ve a OAuth2 o Installation y genera una URL de invitación con estos scopes:
botapplications.commands
Permisos recomendados:
- View Channels
- Send Messages
- Read Message History
Abre la URL generada e invita el bot al servidor donde quieras usarlo.
El bot lee sus configuraciones iniciales por defecto de config.example.json (que se copia internamente como config.json), pero puedes sobrescribir absolutamente cualquier valor de configuración directamente desde tu archivo .env, sin necesidad de modificar ningún archivo JSON.
Puedes añadir o descomentar estas variables en tu .env para personalizar el comportamiento del bot:
OLLAMA_CHAT_MODEL: El modelo de chat utilizado por Ollama para responder (ej.qwen2.5:1.5b).OLLAMA_EMBEDDING_MODEL: El modelo de embeddings para procesar los textos (ej.nomic-embed-text).OLLAMA_BASE_URL: Dirección base de Ollama (el bot detecta Docker y la reescribe automáticamente ahttp://host.docker.internal:11434si es necesario).OLLAMA_TEMPERATURE: Nivel de creatividad de las respuestas (ej.0.2).OLLAMA_NUM_THREAD: Hilos de CPU reservados para Ollama (ej.3).OLLAMA_NUM_PREDICT: Longitud máxima aproximada de la respuesta generada (ej.850).
BOT_ACTIVITY_MESSAGE: Mensaje de estado/actividad del bot (ej.Base de conocimiento local).BOT_SPLIT_MESSAGE_LIMIT: Límite de caracteres por mensaje para dividir respuestas largas de Discord (ej.1900).BOT_ENABLE_AUTO_THREADS: Si se establece entrue, el bot iniciará de forma automática hilos públicos en Discord por cada consulta de/aipara no saturar el canal general (por defectofalse).BOT_MAX_HISTORY: Cantidad máxima de intercambios (pregunta y respuesta) retenidos en memoria de chat para permitir preguntas de seguimiento (por defecto5).
KNOWLEDGE_DIR: Carpeta de entrada con tus documentos locales (ej../knowledge_base).DB_DIR: Carpeta donde se guarda ChromaDB persistentemente (ej../chroma_db).COLLECTION_NAME: Nombre de la colección interna de ChromaDB.RETRIEVAL_ENABLE_HYBRID_SEARCH: Si se establece entrue, habilita la búsqueda híbrida (ChromaDB + BM25) para mayor precisión textual de palabras clave específicas (por defectotrue).RETRIEVAL_SOURCE_URL_MAP: Enlace base opcional (ej. de GitHub o wiki) para transformar los nombres de archivo de las fuentes en hipervínculos clickables en Discord.TOP_K: Cantidad de fragmentos relevantes recuperados por consulta (ej.3).CHUNK_SIZE: Tamaño de caracteres de cada fragmento (ej.1200).CHUNK_OVERLAP: Solape de caracteres entre fragmentos continuos (ej.150).
SYSTEM_PROMPT: La instrucción maestra del bot que dicta cómo procesar la información y responder.
Guarda tus archivos en la carpeta local:
knowledge_base/
Formatos soportados:
.mdy.txt: Leídos directamente como texto plano..pdf: El bot lee y extrae automáticamente todo el texto página por página (útil para manuales o libros)..url: Archivo de texto que contiene una dirección web (ej.https://ollama.com/library). Al indexar, el bot descargará el HTML y extraerá el texto limpio de forma automatizada (ideal para blogs, wikis o APIs).
Puedes organizar tus archivos en subcarpetas temáticas. Los archivos de texto plano deben estar guardados con codificación UTF-8.
Un administrador de tu servidor de Discord debe ejecutar:
/sync_knowledge
Este comando lee los archivos locales del volumen knowledge_base, los divide en fragmentos, genera los embeddings usando Ollama y regenera la base de vectores ChromaDB.
/ai pregunta: ¿Cómo se configura el puerto por defecto?
Si el bot está procesando otra pregunta en ese momento, te informará de tu posición en la cola.
El proyecto está diseñado para funcionar en hardware modesto (mini PCs o servidores caseros sin GPU dedicada). La inferencia se ejecuta localmente mediante la CPU.
- Usa modelos de chat de tamaño contenido (ej.
qwen2.5:1.5bo similar). - Mantén
top_kbajo (ej.3). Menos fragmentos resultan en una inferencia mucho más ágil. - Ajusta
num_threadpara no ahogar tu CPU. Si tienes 4 núcleos de CPU libres en la máquina host, asignar3a Ollama asegura que el sistema operativo y Docker sigan respondiendo de forma fluida.
Para actualizar el bot a la última versión disponible en el repositorio de GitHub sin perder tus configuraciones ni bases de datos:
# 1. Parar el contenedor
docker compose down
# 2. Descargar los últimos cambios
git pull
# 3. Levantar reconstruyendo la imagen con las nuevas dependencias
docker compose up -d --build- Comprueba que Ollama está activo en la máquina host (
ollama listo accediendo ahttp://localhost:11434en tu navegador). - Si estás en Linux, asegúrate de haber seguido el paso de configuración de
OLLAMA_HOST=0.0.0.0y reiniciar el servicio de Ollama.
- Confirma que has depositado archivos
.mdo.txten la carpetaknowledge_basedel host. - Ejecuta
/sync_knowledgeen tu servidor de Discord y espera a que finalice con un mensaje de éxito.
- Asegúrate de haber seleccionado el scope
applications.commandsal generar la URL de invitación del bot. - Prueba a reiniciar el contenedor (
docker compose restart) para forzar una sincronización del árbol de comandos con Discord.
Este proyecto está bajo la licencia MIT. Consulta el archivo LICENSE para más detalles.