Ollama agente IA local: tutorial completo 2026
La mayoría de la gente usa ChatGPT o Claude. Pero tus datos van a la nube y dependes de que OpenAI/Anthropic siga abierto. Con Ollama puedes correr modelos LLM localmente y armar agentes completos sin Internet.
TL;DR — Lo que vas a tener al final
- Tiempo de setup: 2-3 horas para el primer LLM funcionando.
- Requisitos: GPU NVIDIA con 12+ GB VRAM (RTX 3060 mínimo).
- Resultado: LLM local con API OpenAI-compatible, integrable con n8n/Open WebUI.
- Troubleshooting: nvidia-smi, ollama ps, OOM con modelos grandes.
¿Qué es Ollama?
Ollama es una herramienta que simplifica correr modelos LLM en tu máquina. Antes necesitabas Python + llama.cpp + config manual. Ollama lo hace con un comando.
¿Qué modelos puedes correr?
| Modelo | Tamaño | RAM mínima | Calidad |
|---|---|---|---|
| Llama 3.2 1B | 1 GB | 2 GB | Baja |
| Llama 3.2 3B | 2 GB | 4 GB | Media |
| Phi-3.5 Mini | 2.3 GB | 4 GB | Media-alta |
| Llama 3.1 8B | 4.7 GB | 8 GB | Alta |
| Mistral 7B | 4.1 GB | 8 GB | Alta |
| Qwen 2.5 14B | 9 GB | 16 GB | Muy alta |
| Llama 3.1 70B | 40 GB | 48 GB | Excelente |
| DeepSeek V3 671B | 400 GB | 512 GB | State-of-the-art |
Para empezar, te recomiendo: llama3.2:3b (cualquier laptop moderna lo corre).
Instalación
Linux
curl -fsSL https://ollama.com/install.sh | sh
macOS
brew install ollama
# O bajar de ollama.com
Verificar
ollama --version
Tu primer chat
ollama run llama3.2:3b
Te aparece el prompt interactivo. prueba:
>>> ¿Cuál es la capital de Francia?
La capital de Francia es París.
>>> ¿Y de Canadá?
Ottawa.
>>> /bye
Models: cómo gestionar
Bajar un modelo
ollama pull llama3.2:3b
ollama pull phi3.5:3.8b
ollama pull mistral:7b
Listar descargados
ollama list
Borrar
ollama rm llama3.2:3b
Modelos custom
puedes crear tu propio modelo con un Modelfile:
mkdir mi-modelo
cat > mi-modelo/Modelfile <<'EOF'
FROM llama3.2:3b
SYSTEM """eres un experto en Linux y DevOps.
Respondés en español rioplatense, con ejemplos concretos y comandos."""
PARAMETER temperature 0.7
PARAMETER top_p 0.9
EOF
ollama create linux-expert -f mi-modelo/Modelfile
ollama run linux-expert
HTTP API
Ollama expone una API REST en http://localhost:11434:
Chat completion
curl http://localhost:11434/api/chat -d '{
"model": "llama3.2:3b",
"messages": [
{"role": "user", "content": "Explicame Docker en una frase"}
]
}'
Generate
curl http://localhost:11434/api/generate -d '{
"model": "llama3.2:3b",
"prompt": "Cuál es la diferencia entre SQL y NoSQL?"
}'
Streaming
Por defecto la API responde con NDJSON (un JSON por línea). Para streaming en una línea continua y mostrar tokens a medida que se generan, agregá "stream": true explícito y procesá cada JSON line en el cliente. Ejemplo con curl + jq:
curl -N http://localhost:11434/api/generate -d '{
"model": "llama3.2:3b",
"prompt": "Contame un chiste corto",
"stream": true
}' | jq -r '.response // empty'
Function calling (tools)
Esto es lo que hace que un agente funcione. El modelo puede llamar funciones externas.
1. Definí las tools
import requests
import json
def get_weather(city: str) -> str:
"""Obtiene el clima actual de una ciudad"""
return f"En {city} hace 22°C y está soleado"
def get_news(topic: str) -> str:
"""Obtiene las últimas noticias sobre un tema"""
return f"Noticias sobre {topic}: hay 3 resultados relevantes"
# Schema para Ollama
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Obtiene el clima de una ciudad",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "Nombre de la ciudad"}
},
"required": ["city"]
}
}
},
{
"type": "function",
"function": {
"name": "get_news",
"description": "Obtiene noticias sobre un tema",
"parameters": {
"type": "object",
"properties": {
"topic": {"type": "string", "description": "Tema"}
},
"required": ["topic"]
}
}
}
]
available_functions = {
"get_weather": get_weather,
"get_news": get_news,
}
2. Loop del agente
import ollama
MAX_ITER = 8 # tope de iteraciones para evitar loops infinitos
def run_agent(user_message: str, model: str = "llama3.2:3b"):
messages = [{"role": "user", "content": user_message}]
for _ in range(MAX_ITER):
# Llamar al modelo
response = ollama.chat(
model=model,
messages=messages,
tools=tools,
)
# Agregar response a messages
messages.append(response['message'])
# ¿El modelo quiere llamar tools?
if response['message'].get('tool_calls'):
for tool_call in response['message']['tool_calls']:
function_name = tool_call['function']['name']
function_args = tool_call['function']['arguments']
print(f"🔧 Llamando {function_name}({function_args})")
# Si el modelo inventó una tool que no existe, no rompemos
fn = available_functions.get(function_name)
if fn is None:
messages.append({
'role': 'tool',
'content': f"Error: función {function_name} no existe",
})
continue
# Ejecutar la función
function_response = fn(**function_args)
# Agregar el resultado
messages.append({
'role': 'tool',
'content': str(function_response),
})
print(f"📋 Resultado: {function_response}")
else:
# El modelo respondió con texto
return response['message']['content']
# Si llegamos acá, el modelo entró en loop o se quedó en tools
return response['message'].get('content') or "(sin respuesta tras agotar iteraciones)"
# Probar
result = run_agent("¿Qué clima hace en Buenos Aires y dame noticias de tecnología?")
print(result)
3. Modelos con buen tool support
No todos los modelos siguen tools de forma confiable. Para producción recomiendo:
- qwen2.5:7b o qwen2.5:14b — el mejor tool-calling open source en su tamaño (Excelente seguimiento de schema JSON).
- llama3.1:8b — buen balance calidad/recursos.
- mistral-nemo:12b — alternativa sólida con buen soporte de tools.
- nemotron-mini:4b — sorprendentemente bueno para tool calling en tamaño chico.
Evitar para tools: llama3.2:1b, phi3.5:3.8b — siguen instrucciones JSON de forma inconsistente.
MCP (Model Context Protocol): el estándar 2026
MCP es el protocolo abierto que Anthropic lanzó a fines de 2024 y que se convirtió en el estándar de facto para conectar LLMs a herramientas externas (lectura de archivos, búsqueda web, bases de datos, GitHub, etc.). Ollama 0.4+ lo soporta nativamente.
¿Qué cambia con MCP?
En vez de escribir un loop de function calling a mano (sección anterior), Ollama puede conectarse a servidores MCP que exponen tools automáticamente. tú escribís el server MCP una vez y cualquier modelo compatible los usa.
Instalación
Ollama ya trae cliente MCP integrado. Solo necesitas instalar servidores. Los más populares:
- filesystem — leer/escribir archivos locales.
- fetch — hacer requests HTTP desde el agente.
- git — inspeccionar repos git, diff, history.
- github — search de issues, crear PRs, leer código.
- postgres / sqlite — queries SQL sobre bases de datos.
Ejemplo con el servidor oficial filesystem
# 1. Instalar uv (gestor de paquetes Python moderno)
curl -LsSf https://astral.sh/uv/install.sh | sh
# 2. Agregar el server MCP filesystem al config de Ollama
mkdir -p ~/.config/ollama
cat > ~/.config/ollama/mcp.json <<'EOF'
{
"mcp_servers": {
"filesystem": {
"command": "uvx",
"args": ["mcp-server-filesystem", "/home/tu-usuario"]
}
}
}
EOF
# 3. Reiniciar Ollama
systemctl --user restart ollama
# 4. Ahora tu agente puede leer archivos locales automáticamente.
Cliente MCP en Python
Si quieres controlar el flujo tú mismo, usa el cliente MCP oficial. Acá un ejemplo de agente que combina Ollama + tools MCP remotas:
import asyncio
import ollama
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def run_mcp_agent():
# Conectar a un server MCP (ejemplo: filesystem)
server_params = StdioServerParameters(
command="uvx",
args=["mcp-server-filesystem", "/home/tu-usuario"],
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
# Listar tools que expone el server MCP
tools_resp = await session.list_tools()
mcp_tools = [
{
"type": "function",
"function": {
"name": t.name,
"description": t.description,
"parameters": t.inputSchema,
}
}
for t in tools_resp.tools
]
# Combinar MCP tools + tus tools locales
all_tools = mcp_tools + tools
messages = [{"role": "user", "content": "Listame los archivos en mi home"}]
while True:
response = ollama.chat(
model="qwen2.5:7b",
messages=messages,
tools=all_tools,
)
messages.append(response["message"])
if not response["message"].get("tool_calls"):
print(response["message"]["content"])
return
for tc in response["message"]["tool_calls"]:
fn_name = tc["function"]["name"]
fn_args = tc["function"]["arguments"]
print(f"🔧 MCP: {fn_name}({fn_args})")
# Si la tool viene de MCP, despachar por JSON-RPC
if any(t["function"]["name"] == fn_name for t in mcp_tools):
result = await session.call_tool(fn_name, fn_args)
content = str(result.content)
else:
# Si es local, usar tu diccionario de funciones
content = str(available_functions[fn_name](**fn_args))
messages.append({"role": "tool", "content": content})
asyncio.run(run_mcp_agent())
Por qué MCP importa: es el protocolo que estandarizó la integración agente-herramientas. La mayoría de los proveedores (Anthropic, OpenAI, Google, Mistral, Ollama) ya lo soportan. Si vas a construir un agente serio, MCP es el camino.
Caso real: agente que controla tu homelab
import subprocess
import ollama
def run_command(cmd: str) -> str:
"""Ejecuta un comando en el server y devuelve output"""
try:
result = subprocess.run(
cmd, shell=True, capture_output=True, text=True, timeout=30
)
return result.stdout[:2000] or "(sin output)"
except Exception as e:
return f"Error: {e}"
def restart_service(service: str) -> str:
"""Reinicia un servicio systemd"""
result = subprocess.run(
f"sudo systemctl restart {service}",
shell=True, capture_output=True, text=True
)
return f"Servicio {service} reiniciado. Output: {result.stdout[:500]}"
def check_disk() -> str:
"""Verifica uso de disco"""
result = subprocess.run("df -h", shell=True, capture_output=True, text=True)
return result.stdout
tools = [
{
"type": "function",
"function": {
"name": "run_command",
"description": "Ejecuta un comando shell y devuelve output",
"parameters": {
"type": "object",
"properties": {
"cmd": {"type": "string"}
},
"required": ["cmd"]
}
}
},
{
"type": "function",
"function": {
"name": "restart_service",
"description": "Reinicia un servicio systemd",
"parameters": {
"type": "object",
"properties": {
"service": {"type": "string"}
},
"required": ["service"]
}
}
},
{
"type": "function",
"function": {
"name": "check_disk",
"description": "Verifica el espacio en disco",
"parameters": {"type": "object", "properties": {}}
}
}
]
functions = {
"run_command": run_command,
"restart_service": restart_service,
"check_disk": check_disk,
}
SYSTEM = """eres un agente DevOps que controla un servidor Linux.
- usa las tools cuando haga falta.
- Si el usuario pide reiniciar nginx, usa restart_service("nginx").
- Si pide info de disco, usa check_disk().
- Si pide algo más, usa run_command().
- Respondés en español."""
MAX_ITER = 10
def devops_agent(message: str):
messages = [
{"role": "system", "content": SYSTEM},
{"role": "user", "content": message}
]
for _ in range(MAX_ITER):
response = ollama.chat(
model="llama3.1:8b", # 8B para tareas más complejas
messages=messages,
tools=tools,
)
messages.append(response['message'])
if not response['message'].get('tool_calls'):
return response['message']['content']
for tc in response['message']['tool_calls']:
fn = functions[tc['function']['name']]
args = tc['function'].get('arguments', {})
result = fn(**args) if args else fn()
messages.append({'role': 'tool', 'content': str(result)})
# Uso interactivo
while True:
user = input("tú: ")
if user.lower() in ['exit', 'quit']:
break
response = devops_agent(user)
print(f"Bot: {response}")
UI para usar el agente
Si quieres algo gráfico, hay opciones:
Open WebUI (recomendado)
docker run -d -p 3000:8080
-e OLLAMA_BASE_URL=http://host.docker.internal:11434
--name open-webui
--restart always
ghcr.io/open-webui/open-webui:main
Accedés a http://localhost:3000. UI tipo ChatGPT, conectada a tu Ollama.
Otros
- Page Assist — extensión de Chrome.
- LibreChat — UI completa con multi-modelo.
Performance tips
Cuánta RAM necesitas
| Modelo | RAM mínima | RAM recomendada |
|---|---|---|
| 3B | 4 GB | 8 GB |
| 7B | 8 GB | 16 GB |
| 14B | 16 GB | 24 GB |
| 70B | 48 GB | 64 GB |
GPU acceleration
Ollama detecta automáticamente tu GPU NVIDIA/AMD. verifica:
ollama run llama3.2:3b
# Output: "loaded in X.Xs" - si ves CUDA/Metal/ROCm, está usando GPU
Modelos cuantizados
Por default Ollama descarga el modelo cuantizado a q4_0 (4-bit). Si quieres más calidad, puedes pedir un quant específico — Ollama 0.4+ soporta la familia q2_K, q3_K, q4_0, q4_K_M, q5_K_M, q6_K, q8_0 y f16. Ejemplo:
ollama pull llama3.1:8b-instruct-q6_K # 6-bit, mejor calidad
Configuración del server
/etc/systemd/system/ollama.service.d/override.conf:
[Service]
Environment="OLLAMA_NUM_PARALLEL=2"
Environment="OLLAMA_MAX_LOADED_MODELS=2"
Environment="OLLAMA_KEEP_ALIVE=10m"
OLLAMA_KEEP_ALIVE controla cuánto tiempo se mantiene el modelo cargado en RAM después de usarlo.
Casos de uso reales
1. Asistente de código local
ollama run codellama:13b
>>> #include <stdio.h>
... int main() {
... printf("Hello, World!n");
... return 0;
... }
Explicame este código
2. Resumir documentos largos
import ollama
def summarize(text):
response = ollama.chat(
model='llama3.1:8b',
messages=[{
'role': 'user',
'content': f'Resumí este documento en 3 párrafos:nn{text}'
}]
)
return response['message']['content']
with open('documento.txt') as f:
text = f.read()
print(summarize(text))
3. Clasificar emails / tickets
def classify_email(subject, body):
response = ollama.chat(
model='llama3.2:3b',
messages=[{
'role': 'user',
'content': f'''Clasificá este email en una de estas categorías:
- bug
- feature_request
- question
- spam
Subject: {subject}
Body: {body}
Respondé SOLO con la categoría, sin explicación.'''
}]
)
return response['message']['content'].strip()
4. Análisis de logs
def analyze_logs(log_lines):
response = ollama.chat(
model='llama3.1:8b',
messages=[{
'role': 'user',
'content': f'''Analizá estos logs y decime:
1. ¿Hay errores críticos?
2. ¿Hay patrones sospechosos?
3. Recomendación inmediata
Logs:
{chr(10).join(log_lines[:100])}'''
}]
)
return response['message']['content']
Limitaciones
- Modelos chicos son menos precisos. Un 7B local no compite con GPT-4.
- No tienes multimodal (imágenes) out-of-the-box — para eso está
llavaollama3.2-visionen Ollama. - Setup inicial requiere tiempo.
- No hay historial de búsqueda web sin tools adicionales (o MCP servers como
fetch).
Para tareas críticas (medicina, legal, financiero), no confíes solo en modelos locales sin verificar.
Preguntas frecuentes
¿Por qué Ollama agente IA local: tutorial completo 2026 es relevante para sysadmins Linux?
Forma parte del flujo diario de administración. Los conceptos explicados se aplican directamente a servidores en producción y resuelven problemas reales que enfrentan sysadmins hispanohablantes.
¿Qué necesito para empezar con Ollama agente IA local: tutorial?
Distribución Linux actualizada (Debian, Ubuntu, RHEL, Fedora o Arch), acceso root, y conexión a internet. Para producción: entorno de staging separado antes de aplicar cambios.
¿Cuáles son los errores más comunes con Ollama agente IA local: tutorial?
Los tres más frecuentes: (1) saltar la lectura de logs, (2) aplicar cambios directos en producción sin probar, (3) olvidar permisos y ownership. La documentación y un plan de rollback siempre.
¿Cuándo usar Ollama agente IA local: tutorial y cuándo una alternativa?
Esta solución es ideal para el caso descrito. Alternativas como Docker, Ansible o configuración manual pueden ser mejores según contexto: portabilidad, escala y reproducibilidad son los factores clave.
¿Cómo migro desde una configuración previa a Ollama agente IA local: tutorial?
Documentar el estado actual, probar la nueva configuración en staging, validar funcionalmente, y aplicar en producción con rollback plan listo. Los posts de SoyLinux incluyen troubleshooting para los problemas más comunes.
Lee también
- Guía Fedora 44: Novedades, Instalación y Upgrade para Sysadmins Linux
- Configura VLANs en Linux con nmcli: Guía paso a paso para sysadmins
- Protege tu SSH: Guía esencial para configurar Fail2ban en Linux
- Guía Definitiva: Configura Kubernetes con kubeadm en Ubuntu para Sysadmins Linux
- Configura Prometheus y Grafana: Guía DevOps para SysAdmins Linux

Pingback: FineParser: el OCR CPU-only de ABBYY para tus pipelines RAG en Linux - Soy Linux