Contenido
Tutorial de llamadas a herramientas en Ollama: cómo conectar modelos con funciones
Los modelos de lenguaje no saben qué tiempo hace hoy ni qué hay en tu base de datos, y tampoco son buenos haciendo cálculos precisos. Las llamadas a herramientas (tool calling, también llamadas function calling) permiten que el modelo «pida a tu programa que ejecute una función» y después responda según el resultado.
Solo se pueden usar con modelos compatibles con herramientas. En la página del modelo en ollama.com aparecerá tools; por ejemplo, qwen3, llama3.1, gpt-oss y mistral.
Cómo funciona
1. Tú: pregunta + descripción de las herramientas disponibles ──────────▶ modelo
2. Modelo: «Llama a get_weather(city="Taipéi")»◀──
3. Tu programa ejecuta get_weather("Taipéi") → "24°C, parcialmente nublado"
4. Tú: envías el resultado de vuelta ─────────────────────▶ modelo
5. Modelo: «En Taipéi hay ahora 24 grados y está parcialmente nublado. Te recomiendo llevar una chaqueta ligera.»
El modelo no ejecuta ningún programa por sí mismo; solo decide qué herramienta llamar y con qué parámetros. Tu programa es quien la ejecuta, así que tienes el control total sobre lo que puede hacer.
Ejemplo en Python
El paquete de Python de Ollama permite pasar funciones de Python directamente como herramientas. Genera automáticamente su descripción a partir de las anotaciones de tipos y la docstring de cada función:
from ollama import chat
def get_weather(city: str) -> str:
"""
Consulta el tiempo actual de una ciudad.
Args:
city: Nombre de la ciudad, por ejemplo, «Taipéi»
Returns:
Descripción del tiempo
"""
fake_data = {"Taipéi": "24°C, parcialmente nublado", "Kaohsiung": "29°C, soleado"}
return fake_data.get(city, "No hay datos")
tools = {"get_weather": get_weather}
messages = [{"role": "user", "content": "¿Qué tiempo hace ahora en Taipéi y Kaohsiung?"}]
response = chat(model="qwen3:8b", messages=messages, tools=[get_weather])
messages.append(response.message)
# El modelo puede solicitar varias llamadas a herramientas a la vez
for call in response.message.tool_calls or []:
fn = tools[call.function.name]
result = fn(**call.function.arguments)
print(f"Llamada a {call.function.name}({call.function.arguments}) → {result}")
messages.append({"role": "tool", "tool_name": call.function.name, "content": str(result)})
final = chat(model="qwen3:8b", messages=messages)
print(final.message.content)
Puntos clave:
- Añade a
messagesla respuesta del modelo (que incluyetool_calls). - Añade el resultado de cada herramienta con
role: "tool". - Llama a
chatotra vez para que el modelo responda según los resultados.
Deja que el modelo decida cuántas llamadas hacer
Algunas preguntas requieren llamar a varias herramientas seguidas, por ejemplo: «Consulta primero el tipo de cambio y luego calcula el importe». Usa un bucle hasta que el modelo deje de solicitar llamadas a herramientas:
from ollama import chat
def get_exchange_rate(currency: str) -> float:
"""Obtiene el tipo de cambio de una unidad de moneda extranjera a nuevos dólares taiwaneses. currency puede ser USD, JPY, por ejemplo."""
return {"USD": 32.1, "JPY": 0.21}.get(currency.upper(), 0.0)
def multiply(a: float, b: float) -> float:
"""Multiplica a por b."""
return a * b
tools = {f.__name__: f for f in [get_exchange_rate, multiply]}
messages = [{"role": "user", "content": "¿A cuántos nuevos dólares taiwaneses equivalen aproximadamente 350 dólares estadounidenses?"}]
while True:
response = chat(model="qwen3:8b", messages=messages, tools=list(tools.values()))
messages.append(response.message)
if not response.message.tool_calls:
break
for call in response.message.tool_calls:
result = tools[call.function.name](**call.function.arguments)
messages.append({"role": "tool", "tool_name": call.function.name, "content": str(result)})
print(response.message.content)
En la práctica, limita el número máximo de llamadas para evitar que el modelo entre en un bucle infinito.
Define herramientas con la API REST
Si no usas el paquete de Python, describe las herramientas con JSON Schema:
curl http://localhost:11434/api/chat -d '{
"model": "qwen3:8b",
"messages": [{ "role": "user", "content": "¿Qué tiempo hace en Taipéi?" }],
"stream": false,
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Consulta el tiempo actual de una ciudad",
"parameters": {
"type": "object",
"properties": {
"city": { "type": "string", "description": "Nombre de la ciudad" }
},
"required": ["city"]
}
}
}]
}'
En la respuesta, message.tool_calls:
"tool_calls": [
{ "function": { "name": "get_weather", "arguments": { "city": "Taipéi" } } }
]
Después de ejecutar la herramienta, añade el resultado a messages con {"role": "tool", "tool_name": "get_weather", "content": "24°C, parcialmente nublado"} y vuelve a enviarlo.
Escribe buenas descripciones para las herramientas
El modelo decide cuándo usar una herramienta y cómo completar sus parámetros basándose por completo en el nombre y la descripción:
- Elige un nombre de función que indique claramente su propósito:
search_orderses mejor quequery1. - Explica claramente en qué casos debe usarse, así como el formato y ejemplos de los parámetros.
- Procura que haya pocos parámetros y que sus tipos estén bien definidos. Usa una enumeración (
enum) cuando sea posible. - No incluyas demasiadas herramientas: los modelos pequeños pueden confundirse al elegir entre una docena.
Consideraciones de seguridad
- El modelo activa las herramientas a partir de la entrada del usuario. Si el usuario puede controlar esa entrada, también puede llamar indirectamente a tus herramientas.
- No proporciones herramientas que permitan ejecutar código arbitrario o SQL arbitrario, ni borrar datos.
- Para las operaciones con efectos secundarios (pagos, envío de correos, eliminaciones), pide confirmación al usuario antes de ejecutarlas.
- Valida los parámetros que proporciona el modelo; no confíes en ellos directamente.
Actualizado 12 de octubre de 2026