Monta un RAG local con n8n y Ollama y pregunta a los documentos de tu empresa
Al terminar tendrás un asistente que responde preguntas sobre tus PDF, contratos y manuales citando el documento de origen, sin que un solo byte salga de tu red. Funciona en un Mac mini M4 de 16 GB o en cualquier PC con 16 GB de RAM. La máquina más barata para probarlo es el portátil que ya tienes.
Qué es RAG en dos frases
Un modelo de lenguaje sabe lo que vio durante su entrenamiento; no conoce tu política de vacaciones ni tu checklist de despliegue. RAG (Retrieval-Augmented Generation, generación aumentada por recuperación) añade un paso previo: busca en tus documentos los pasajes relevantes y se los pasa al modelo como contexto, así que la respuesta sale de tu documentación real y no de la memoria del modelo.
graph LR
A[Documentos<br/>PDF, DOCX, TXT] --> B[Fragmentar<br/>500 tokens]
B --> C[Embeddings<br/>nomic-embed-text]
C --> D[Base vectorial<br/>ChromaDB]
E[Pregunta] --> F[Embedding<br/>de la pregunta]
F --> G[Búsqueda<br/>5 fragmentos]
D --> G
G --> H[Prompt<br/>contexto + pregunta]
H --> I[Ollama<br/>llama3.1:8b]
I --> J[Respuesta<br/>con fuentes]
style A fill:#0B1628,color:#FAFAFA
style J fill:#F5A623,color:#0B1628
Qué necesitas
| Componente | Para qué sirve | Instalación |
|---|---|---|
| n8n | Orquestar el flujo | docker run -d --name n8n -p 5678:5678 -v n8n_data:/home/node/.n8n --add-host=host.docker.internal:host-gateway docker.n8n.io/n8nio/n8n |
| Ollama | LLM y embeddings en local | curl -fsSL https://ollama.com/install.sh | sh (Linux) o brew install ollama (macOS) |
| ChromaDB | Base de datos vectorial | pip install chromadb |
| llama3.1:8b | Genera las respuestas | ollama pull llama3.1:8b (4,9 GB) |
| nomic-embed-text | Convierte texto en vectores | ollama pull nomic-embed-text (274 MB) |
Hardware: 16 GB de RAM. Tiempo: una tarde. No hace falta ninguna cuenta ni ninguna clave de API. Si dudas qué máquina comprar, mira los mejores dispositivos para IA local en 2026.
Un detalle que ahorra una hora: si n8n corre en Docker y Ollama en el anfitrión, dentro de n8n la URL de Ollama es http://host.docker.internal:11434, y Ollama tiene que arrancar con OLLAMA_HOST=0.0.0.0. En los ejemplos usamos localhost por claridad.
Paso 1: ingesta, fragmenta y vectoriza los documentos
Crea un workflow en n8n con un Schedule Trigger cada 15 minutos seguido de un nodo Read/Write Files from Disk que lea la carpeta de documentos:
{
"nodes": [
{
"name": "Cada 15 minutos",
"type": "n8n-nodes-base.scheduleTrigger",
"parameters": { "rule": { "interval": [{ "field": "minutes", "minutesInterval": 15 }] } }
},
{
"name": "Leer documentos",
"type": "n8n-nodes-base.readWriteFile",
"parameters": { "operation": "read", "fileSelector": "/data/company-docs/*.pdf" }
}
]
}
Añade un nodo Extract from File (operación PDF) para sacar el texto y un nodo Code que lo parta en fragmentos de unos 500 tokens con 50 tokens de solapamiento. El solapamiento evita que una frase que cae justo en el corte se pierda.
Para cada fragmento, un nodo HTTP Request llama al endpoint de embeddings de Ollama:
{
"url": "http://localhost:11434/api/embed",
"method": "POST",
"body": { "model": "nomic-embed-text", "input": "{{ $json.chunk_text }}" }
}
La respuesta trae embeddings: [[...]], un vector de 768 números. Guárdalo en ChromaDB junto con el texto y los metadatos (archivo, página, índice del fragmento):
import chromadb
client = chromadb.PersistentClient(path="/data/chromadb")
col = client.get_or_create_collection("company_docs")
col.add(
ids=[f"{archivo}-{i}"],
embeddings=[vector],
documents=[texto],
metadatas=[{"archivo": archivo, "pagina": pagina, "fragmento": i}],
)
Comprueba que funciona antes de seguir:
curl -s localhost:11434/api/embed -d '{"model":"nomic-embed-text","input":"prueba"}' | head -c 120
Debe devolver {"model":"nomic-embed-text","embeddings":[[0.0123,.... Si devuelve 404, tu Ollama es anterior a la versión 0.3: actualízalo o usa el endpoint antiguo /api/embeddings con el campo prompt.
Paso 2: consulta, busca y responde
Cuando alguien pregunta, el flujo repite tres movimientos: vectoriza la pregunta, busca los cinco fragmentos más parecidos y se los pasa al modelo.
{
"url": "http://localhost:11434/api/embed",
"method": "POST",
"body": { "model": "nomic-embed-text", "input": "¿Cuál es nuestra política de vacaciones?" }
}
results = col.query(
query_embeddings=[embedding_pregunta],
n_results=5,
include=["documents", "metadatas", "distances"],
)
{
"url": "http://localhost:11434/api/chat",
"method": "POST",
"body": {
"model": "llama3.1:8b",
"stream": false,
"messages": [
{ "role": "system", "content": "Responde usando SOLO el contexto proporcionado. Si el contexto no contiene la respuesta, dilo. Cita el documento fuente." },
{ "role": "user", "content": "Contexto:\n{{ $json.retrieved_chunks }}\n\nPregunta: ¿Cuál es nuestra política de vacaciones?" }
]
}
}
La instrucción “si el contexto no contiene la respuesta, dilo” es la más importante del sistema: convierte una alucinación en un “no lo sé, pregunta a RR. HH.”.
Paso 3: pruébalo con una pregunta real
Un empleado escribe: “¿Cuál es nuestra política de vacaciones?”
- nomic-embed-text vectoriza la pregunta.
- ChromaDB devuelve cinco fragmentos de
Politica-RRHH-2026.pdf. - n8n construye el prompt con esos fragmentos.
- llama3.1:8b responde: “Según la Política de RR. HH. 2026 (sección 4.2), dispones de 23 días laborables de vacaciones retribuidas al año. Las solicitudes se presentan con 15 días de antelación a través del portal de RR. HH. Los días no disfrutados pueden trasladarse al primer trimestre del año siguiente.”
En nuestra máquina, con cinco fragmentos (5.199 tokens de contexto), la respuesta completa tardó unos 6 segundos. Coste por consulta: cero.
Qué medimos
Las filas de nuestra estación (NVIDIA GB10, 128 GB de memoria unificada, compartida con otros servicios) se midieron el 09-09-2026 con curl contra la API de Ollama.
| Hardware | Modelo | Tarea | Resultado |
|---|---|---|---|
| GB10 | nomic-embed-text | Embedding de una pregunta | 18 a 28 ms en caliente; 3,6 s la primera llamada (carga del modelo) |
| GB10 | llama3.1:8b | Leer 5.199 tokens de contexto | 2,5 s |
| GB10 | llama3.1:8b | Generar la respuesta (ventana de 8K) | 26,6 tokens/s; 37,8 tokens/s con la ventana por defecto (08-09-2026) |
| Mac mini M4, 24 GB | Qwen 2.5 7B | Generación | ~35 tokens/s (Compute Market) |
Una ventana de contexto mayor cuesta velocidad: si tus fragmentos son largos, mide con el num_ctx real y no con el valor por defecto.
Cuánto cuesta frente a la nube
Una consulta RAG típica envía unos 3.000 tokens (pregunta más cinco fragmentos) y recibe 300. Con los precios de OpenAI y de Anthropic de septiembre de 2026:
| Opción | Coste por consulta | 1.000 consultas/día, 22 días |
|---|---|---|
| Local (Ollama + ChromaDB en un Mac mini de 30 W) | 0 | ~3,25 EUR de electricidad a 0,15 EUR/kWh |
| GPT-5 mini | ~0,0014 $ | ~30 $ |
| GPT-5 | ~0,007 $ | ~150 $ |
| Claude Sonnet 5 | ~0,009 $ | ~200 $ |
A la nube súmale el alojamiento de la base vectorial y el contrato de encargado de tratamiento del RGPD. Con honestidad: si haces cien consultas al día, GPT-5 mini es difícil de batir en coste; ahí eliges local porque los documentos de RR. HH. y los contratos no deben salir del edificio. El cálculo completo está en IA en la nube o en local: calcula tu punto de equilibrio.
Tres ajustes que cambian la calidad
- Tamaño del fragmento. 500 tokens sirve para casi todo. Baja a 300 en manuales técnicos densos y sube a 800 en texto conversacional.
- Solapamiento. Un 10 % del tamaño del fragmento evita perder información en los cortes.
- Número de fragmentos recuperados. Empieza con 5. Sube a 8 o 10 para preguntas que cruzan varias secciones.
Límites que conviene saber: un modelo de 8B resume y localiza bien, pero razona peor que uno de primera línea sobre contratos largos; los PDF escaneados necesitan OCR antes de la ingesta; y las tablas dentro de PDF suelen llegar desordenadas al texto. Para elegir modelo, la comparativa de modelos locales cubre Llama, Mistral y Qwen.
Dónde encaja
El valor real aparece cuando conectas el flujo a las herramientas que ya usa la gente. n8n puede disparar la consulta desde un mensaje en un canal #preguntar-rrhh de Slack, un formulario de la intranet, un correo a una dirección concreta o un resumen semanal con las diez preguntas más repetidas. Más patrones en el tutorial de automatización con IA en n8n.
Siguientes pasos
- Aplica el mismo esquema al código: Automatiza la revisión de código con n8n y Ollama.
- Da herramientas al asistente: n8n + MCP para conectar agentes con tus sistemas.
- Documentación de referencia: API de Ollama, IA en n8n y ChromaDB.
Trabaja con nosotros
Montamos este pipeline para pymes españolas con sus documentos reales y medimos la calidad de las respuestas antes de entregarlo. Si quieres que lo hagamos contigo, escríbenos o mira cómo trabajamos en consultoría.