Módulo 2: El cerebro del agente: modelo y system prompt

4. Modelos locales con Ollama: un agente a $0 (Llama 3, Mistral)

Descripción

En la lección anterior conectaste el nodo de modelo del agente a las credenciales de Anthropic, OpenAI y Google: tres proveedores de nube que cobran por token y que reciben tus prompts en sus propios servidores. En esta cápsula vas a hacer la operación contraria. Vas a levantar el Self-Hosted AI Starter Kit v2, conectar ese mismo nodo a Ollama, y correr tu agente con Llama 3.2 o Mistral corriendo en tu propia máquina. Al terminar vas a poder levantar el stack local con el perfil correcto para tu hardware, conectar el AI Agent a un modelo local sin pagar por token, y —lo más importante— decidir con criterio cuándo un modelo local te alcanza para el trabajo y cuándo te conviene volver a la nube.

Esto pesa más allá del ejercicio. Hay clientes —un despacho legal, una clínica, una fintech con datos regulados— donde sacar información hacia un proveedor externo no es negociable, sin importar cuánto prometa su política de privacidad. Saber montar un agente que nunca toca internet es una habilidad de venta tanto como técnica: le puedes responder a esa objeción con "esto corre completo en tu servidor", en vez de con una promesa contractual.

Conexión con el módulo: ya elegiste modelos vigentes y conectaste proveedores de nube (lección 3). Aquí agregas la tercera opción —local— antes de escribir el system prompt (lección 5) que le da personalidad y límites al agente, sin importar qué motor tenga detrás.

Nube vs. garage propio: el modelo mental

Piensa en las dos formas de moverte por una ciudad que no conoces. Contratar un auto con chofer —le dices a dónde vas, te lleva, pagas por el viaje— es la nube: Anthropic, OpenAI y Google corren el modelo en su infraestructura, tú pagas por token y dependes de que su servidor esté arriba y de que tu conexión aguante. Comprar un auto usado y guardarlo en tu garage es la otra opción: el viaje es gratis siempre que quieras hacerlo, no necesitas pedirle permiso a nadie para arrancarlo, pero el auto es tuyo —con tu batería, tu tanque, tu mantenimiento— y no tiene la misma potencia que la flota profesional de un chofer.

Un modelo local es ese auto en tu garage. Ollama es el motor que lo enciende: descarga los pesos de un modelo —Llama 3.2, Mistral, y decenas más— a tu disco, y expone una API en tu propia máquina, sin llave, sin factura, sin salir a internet, para que cualquier programa —incluido n8n— le mande prompts y reciba respuestas.

El Self-Hosted AI Starter Kit v2 es la manera más rápida de tener ese garage ya armado. Es un stack de Docker Compose que, con un solo comando, levanta cuatro piezas: n8n (donde vive tu agente), Ollama (el motor local), Qdrant (una base de datos vectorial, que vas a usar más adelante en los módulos de RAG) y Postgres (donde n8n guarda sus workflows y credenciales). No introduce ningún concepto nuevo: junta piezas que ya conocías bajo un único docker compose up.

Ejemplo trabajado

Paso 1 — Clonar el stack y levantarlo.

git clone https://github.com/n8n-io/self-hosted-ai-starter-kit.git
cd self-hosted-ai-starter-kit
cp .env.example .env
docker compose --profile cpu up

El flag --profile le dice a Docker Compose qué motor de Ollama levantar: cpu si tu máquina no tiene GPU dedicada (incluye Apple Silicon, porque Docker en Mac no puede exponerle la GPU a un contenedor), gpu-nvidia si tienes una tarjeta NVIDIA con drivers CUDA, o gpu-amd para AMD en Linux. Si tienes un Mac con GPU potente y quieres aprovecharla, la alternativa es instalar Ollama nativo en macOS (fuera de Docker) y apuntar el contenedor de n8n hacia host.docker.internal:11434 en vez de usar el perfil cpu.

Qué esperar: en los logs vas a ver un contenedor llamado ollama-pull-llama-cpu (el nombre cambia según el perfil: ollama-pull-llama-gpu o ollama-pull-llama-gpu-amd) ejecutando ollama pull llama3.2. Esa es la descarga automática del modelo por defecto del kit —2.0 GB—, y puede tardar varios minutos según tu conexión. Cuando termine, n8n queda disponible en http://localhost:5678.

Paso 2 — Confirmar que Ollama responde antes de tocar n8n.

docker exec -it $(docker ps -qf "name=ollama-cpu") ollama list

Qué esperar:

NAME               ID              SIZE      MODIFIED
llama3.2:latest    a80c4f17acd5    2.0 GB    3 minutes ago

Si esta lista sale vacía, la descarga del paso 1 todavía no terminó —vuelve a los logs de docker compose antes de seguir.

Paso 3 — Crear la credencial Ollama en n8n.

Entra a http://localhost:5678, crea una credencial de tipo Ollama, y en Base URL pon:

http://ollama-cpu:11434

Aquí está el detalle que rompe a la mayoría en el primer intento: no es http://localhost:11434, aunque ese sea el puerto que Ollama expone. n8n y Ollama corren en contenedores distintos dentro de la misma red de Docker Compose, y dentro de un contenedor, localhost apunta al propio contenedor, no a sus vecinos. El nombre correcto es el del servicio tal como lo define el docker-compose.yml del kit —ollama-cpu, ollama-gpu o ollama-gpu-amd, según el perfil con el que levantaste el stack—. Docker resuelve ese nombre como si fuera un hostname dentro de su propia red interna.

Paso 4 — Conectar el modelo al AI Agent.

Arma un workflow mínimo: Chat Trigger → AI Agent, y en el AI Agent conecta como entrada de modelo de lenguaje el nodo Ollama Chat Model. En su campo Model vas a ver un desplegable que se llena automáticamente con los modelos que tienes descargados en esa instancia de Ollama —el mismo resultado que te dio ollama list en el paso 2—. Elige llama3.2:latest.

Envía un mensaje de prueba desde el Chat Trigger:

Explícame en una frase qué hace una base de datos vectorial.

Qué esperar (la redacción exacta varía según el muestreo del modelo, esto es un ejemplo representativo):

Una base de datos vectorial guarda información como coordenadas numéricas
que representan su significado, para poder encontrar contenido parecido
por cercanía en vez de por coincidencia exacta de palabras.

Paso 5 — Comparar contra Mistral.

docker exec -it $(docker ps -qf "name=ollama-cpu") ollama pull mistral

Cuando termine la descarga (4.4 GB), vuelve al nodo Ollama Chat Model, cambia el desplegable a mistral:latest, y corre el mismo mensaje de prueba. Vas a notar diferencias de tono y de longitud —y probablemente de latencia, porque Mistral tiene más del doble de parámetros que Llama 3.2 3B—. No profundices todavía en medir esas diferencias con precisión: para eso está el motor de depuración de la lección 7. Aquí el objetivo es solo confirmar que puedes intercambiar modelos locales sin tocar el resto del workflow.

Cuándo un modelo local alcanza y cuándo no

La pregunta no es "¿el modelo local es peor?". Es "¿peor para qué?".

Herramientas (tool calling). Si en un módulo más adelante le das herramientas a tu agente —buscar en una API, consultar una base de datos—, el modelo necesita poder emitir una respuesta en formato tool_calls que n8n reconozca como "quiero ejecutar esta herramienta". Ollama documenta ese soporte para modelos puntuales: Llama 3.1, Llama 3.2, Mistral Nemo, Firefunction v2 y Command-R+, entre otros. El Mistral 7B base que acabas de descargar —el que corresponde al tag mistral:latest— no está en esa lista. Antes de apoyarte en tool calling con un modelo local, revisa su ficha en ollama.com/library: si no menciona soporte de herramientas, el agente puede "decir" que ejecutó algo sin haberlo hecho realmente.

Hardware y latencia. Un modelo local corre con el CPU o la GPU que tú tienes, no con la infraestructura de un data center. Llama 3.2 en su versión de 3B (2.0 GB en disco) responde en un par de segundos en una laptop común. Sube a un modelo de 13B o más y, sin GPU, la espera se vuelve notoria —ese es el costo real de "gratis": no pagas por token, pagas con el tiempo y los recursos de tu propia máquina.

Residencia de los datos. Aquí es donde un modelo local gana aunque su calidad sea menor: si el contrato con el cliente exige que la información nunca salga de su infraestructura, ningún proveedor de nube —por bueno que sea— cumple esa condición. Ollama sí, porque el prompt jamás sale de la máquina donde corre.

Profundidad de razonamiento. Para tareas acotadas y bien definidas —clasificar, resumir, redactar un borrador corto— un modelo local de 3B a 7B suele alcanzar. Para razonamiento en varios pasos, contexto extenso o ambigüedad real, los modelos de nube de última generación siguen ganando con margen. La elección de modelo, en el fondo, sigue el mismo criterio que viste en la lección 2 —solo que ahora "vigente" también significa "cabe en tu hardware".

Errores comunes

Usar localhost como Base URL de la credencial Ollama. Qué pasa: la prueba de conexión de la credencial falla con algo como "connection refused", aunque curl http://localhost:11434 funcione perfecto desde tu terminal. Por qué: tu terminal corre sobre el sistema operativo anfitrión, donde Ollama sí publica el puerto 11434 en localhost. Pero n8n corre dentro de su propio contenedor, con su propio namespace de red —ahí, localhost solo se refiere a sí mismo—. Cómo detectarlo: el error aparece únicamente al probar la credencial desde la interfaz de n8n, nunca al probar desde tu máquina. Cómo corregirlo: usa el nombre del servicio dentro de la red de Docker Compose (ollama-cpu, ollama-gpu o ollama-gpu-amd, según el perfil que levantaste), o host.docker.internal si Ollama corre nativo fuera de Docker.

Probar el workflow antes de que termine la descarga inicial del modelo. Qué pasa: el nodo Ollama Chat Model devuelve un error de modelo no encontrado, o la ejecución se queda colgada sin responder. Por qué: el servicio ollama-pull-llama-* descarga llama3.2 en paralelo al arranque de n8n, y esos 2.0 GB pueden tardar varios minutos con una conexión lenta —n8n puede quedar disponible en el puerto 5678 antes de que la descarga termine—. Cómo detectarlo: revisa los logs de docker compose, busca la línea del contenedor ollama-pull-llama-cpu (o su equivalente de GPU). Cómo corregirlo: espera a que el log confirme la descarga completa, o córrela manualmente y confirma con ollama list como en el paso 2 del ejemplo.

Asumir que "todo modelo local sirve para todo lo que hacía el de nube". Qué pasa: conectas mistral:latest a un agente pensando en darle herramientas más adelante, y el agente falla en invocarlas —o inventa que las ejecutó—. Por qué: como viste arriba, no todos los modelos que corren en Ollama emiten el formato tool_calls que el AI Agent necesita para disparar una herramienta real, y el Mistral 7B base no está entre los que Ollama documenta con ese soporte. Cómo detectarlo: en el log de ejecución del workflow, el nodo de la herramienta nunca se dispara aunque el agente "narre" en su respuesta que la usó. Cómo corregirlo: verifica el soporte de tool calling del modelo en su ficha de ollama.com/library antes de construir un agente que dependa de herramientas sobre él.

Ejercicios

1. Levanta el stack con docker compose --profile cpu up y, una vez arriba, confirma con un comando de Docker que ollama list muestra llama3.2:latest descargado. Escribe el comando exacto que usarías.

Ver solución
docker exec -it $(docker ps -qf "name=ollama-cpu") ollama list

Funciona porque docker exec abre una terminal dentro del contenedor ollama-cpu que ya está corriendo, y desde ahí el binario ollama habla directo con su propio servidor local —sin depender de la red de Docker Compose ni de ninguna credencial de n8n—.

2. Levantaste el stack con docker compose --profile gpu-nvidia up y estás armando la credencial Ollama en n8n. ¿Qué valor va en Base URL, y por qué no localhost?

Ver solución

http://ollama-gpu:11434. El perfil gpu-nvidia levanta el servicio de Ollama con el nombre ollama-gpu (no ollama-cpu, que solo existe con el perfil cpu). Como n8n corre en su propio contenedor, necesita el nombre del servicio dentro de la red de Docker Compose para resolverlo —localhost dentro del contenedor de n8n solo apunta a sí mismo, nunca a un contenedor vecino—.

3. Corre la misma pregunta contra llama3.2:latest y mistral:latest en tu AI Agent. Anota una diferencia de fondo —no solo de redacción— entre las dos respuestas.

Ver solución

No hay una única respuesta correcta —depende de tu prompt exacto—, pero una diferencia real y medible que deberías poder registrar es la latencia: en CPU, Llama 3.2 (3B, 2.0 GB) suele responder más rápido que Mistral (7B, 4.4 GB), simplemente porque tiene menos parámetros que multiplicar en cada token generado. Si la única diferencia que notaste fue de redacción, corre el mismo prompt un par de veces más contra el mismo modelo: el muestreo hace que la forma varíe aunque el modelo sea idéntico.

4. Un cliente te pide un agente que resuma contratos internos, y por regulación esos documentos no pueden salir del servidor de la empresa bajo ninguna circunstancia. ¿Nube o local? Justifica con lo que viste en esta cápsula.

Ver solución

Local. La restricción no es de calidad de respuesta, es de dónde viajan los datos: cualquier proveedor de nube —Anthropic, OpenAI, Google— recibe el contrato en su propio servidor así sea solo para procesarlo una vez. Ollama, corriendo dentro del Self-Hosted AI Starter Kit v2, nunca envía el texto fuera de la máquina donde está instalado —es la única de las dos opciones que cumple la restricción, incluso si un modelo de nube diera, en promedio, un resumen mejor redactado—.

Resumen y siguiente paso

Antes de avanzar deberías poder levantar el Self-Hosted AI Starter Kit v2 con el perfil correcto para tu hardware, conectar la credencial Ollama usando el nombre del servicio —no localhost—, armar un AI Agent con el nodo Ollama Chat Model, y explicar con un caso concreto cuándo un modelo local alcanza y cuándo te conviene volver a la nube.

Ya tienes resuelto el motor del agente —nube o local, según lo que viste en la lección 3 y en esta—. Lo que falta es decirle a ese motor quién es y qué no debe hacer, sin importar qué modelo corra detrás: eso es el system prompt, y es exactamente lo que armas en la siguiente cápsula.

Recursos