Dominar la llamada a herramientas (Tool Calling) con Ollama y Python
La llamada a herramientas (tool calling) transforma un modelo que se limita a generar texto en un agente capaz de desencadenar la ejecución de código real: llamar a una API meteorológica, consultar una base de datos o realizar un cálculo. Esta guía muestra cómo dominar la llamada a herramientas de Ollama en Python de principio a fin: formato JSON de las herramientas, bucle de ejecución, streaming de las llamadas a herramientas (serie 0.17) y salidas estructuradas restringidas por un JSON Schema aplicado directamente durante la decodificación. Todo se ejecuta en local en http://localhost:11434, sin clave API ni fuga de datos.
#¿Por qué el llamado a herramientas (tool calling)?
Un LLM por sí solo no sabe nada del mundo real después de su entrenamiento: no conoce el tiempo que hace hoy, ni el saldo de una cuenta, ni el contenido de tu base de datos. La llamada a herramientas cubre ese vacío. Le describes al modelo una lista de funciones disponibles, el modelo decide cuáles invocar y con qué argumentos, tu código las ejecuta y luego devuelve el resultado al modelo para que redacte una respuesta informada.
El punto clave que hay que entender: el modelo nunca ejecuta nada por sí mismo. Solo genera una solicitud estructurada: «llama a get_meteo con ville='Lyon'». Es tu programa en Python el que ejecuta la función y mantiene el control total. Esta separación es lo que hace que las llamadas a herramientas sean seguras y predecibles.
- Datos actualizados
- El modelo consulta una API en tiempo real en lugar de adivinar a partir de sus recuerdos de entrenamiento.
- Acciones concretas
- Crear un ticket, enviar un correo, escribir en una base de datos: el LLM coordina, tu código actúa.
- Fiabilidad
- Los cálculos y las búsquedas exactas se delegan a código determinista, en lugar de que el modelo se los invente.
- 100 % local
- Con Ollama, toda la cadena permanece en tu máquina: sin clave API, sin solicitudes salientes y sin facturación por token.
#Cómo funciona la llamada a herramientas en Ollama
Esta guía te lleva al modelo. El kit te lleva al copiloto que programa en tu editor.
- Espacio en línea de por vida
- PDF + archivos
- Actualizaciones de por vida
El ciclo completo consta de cinco pasos. Visualizarlo bien evita la confusión más común: creer que una sola llamada basta. Se necesitan al menos dos: una para obtener la solicitud de uso de una herramienta y otra para obtener la respuesta final.
- 01Envías la pregunta + las herramientasLa solicitud de chat contiene el mensaje del usuario y la lista de herramientas disponibles (parámetro tools).
- 02El modelo devuelve una solicitud de herramientaEn lugar de responder con texto, devuelve uno o varios tool_calls con el nombre de la función y los argumentos.
- 03Tu código ejecuta la funciónRecuperas name y arguments, llamas a la función Python real correspondiente y obtienes un resultado.
- 04Devuelves el resultadoEl resultado se añade al historial como un mensaje con el rol «tool» y luego vuelves a llamar a chat.
- 05El modelo escribe la respuesta finalCon el resultado obtenido, esta vez produce una respuesta en lenguaje natural para el usuario.
#Prerrequisitos
Tres componentes: el demonio de Ollama en ejecución, un modelo que realmente admita herramientas y la biblioteca oficial de Python. Cuidado con el segundo punto: no todos los modelos pueden hacer llamadas a herramientas. Busca familias recientes diseñadas para ello.
- Ollama actualizado
- Serie 0.17 o posterior para aprovechar el streaming de las llamadas a herramientas. El demonio escucha en http://localhost:11434.
- Un modelo compatible con herramientas
- Qwen 3.5, Granite 4.2, Mistral Small, Devstral, gpt-oss. Los modelos marcados « tools » en ollama.com/library.
- Suficiente VRAM
- Un modelo pequeño (Qwen 3.5 4B ≈ 3,4 GB) basta para probar; un Granite 4.2 8B (≈ 5,3 GB) o un Qwen 3.5 9B (≈ 6,6 GB) sigue mejor las instrucciones que implican varias herramientas. RTX 3060 de 12 GB como opción de gama de entrada.
- La biblioteca ollama
- pip install -U ollama. Sabe construir el esquema de una herramienta directamente a partir de una función Python tipada.
#El formato JSON de las herramientas
Una herramienta se describe con un esquema JSON estrictamente alineado con el de OpenAI: un objeto type: "function" que contiene un nombre, una descripción y un objeto parameters en formato JSON Schema. La descripción es sumamente importante: es lo que lee el modelo para decidir cuándo y cómo llamar a la herramienta. Sé explícito.
#Primera llamada a una herramienta en Python
Empecemos por el caso más sencillo: una función, una pregunta, y observamos lo que el modelo decide. Las anotaciones de tipo y la docstring sirven para generar el esquema enviado al modelo.
En este punto, message.content suele estar vacío: el modelo ha devuelto su solicitud en message.tool_calls. Cada tool_call expone function.name (una cadena) y function.arguments (ya deserializado por la biblioteca como un diccionario de Python). Solo queda ejecutar la llamada y devolver el resultado.
#El bucle de ejecución completo
Aquí tienes la estructura reutilizable de un agente con llamadas a herramientas: un diccionario que asocia cada nombre de herramienta con su función, la ejecución de las llamadas solicitadas, la incorporación de los resultados al historial y, después, una segunda llamada para obtener la respuesta final. Lo envolvemos todo en un bucle para gestionar el caso en que el modelo encadene varias herramientas.
El mensaje de resultado tiene el rol tool y un campo tool_name que indica a qué llamada responde. El campo content debe ser una cadena: serializa tus objetos (json.dumps) antes de devolverlos. El modelo vuelve a leer este contenido como si fuera una observación del mundo.
#Paridad con OpenAI: el mismo código con el cliente openai
Ollama expone un endpoint compatible con OpenAI en /v1. Si tu código ya utiliza el cliente openai, apenas tienes que cambiar nada: apunta base_url a Ollama y usa una clave API ficticia. El formato de las herramientas y de tool_calls es idéntico: esa «paridad con OpenAI» hace que la migración sea trivial.
#Streaming de llamadas a herramientas (serie 0.17)
Históricamente, activar el streaming desactivaba las llamadas a herramientas: había que elegir. Desde la serie 0.17, Ollama puede transmitir las llamadas a herramientas en streaming a medida que avanza la generación. En concreto, recibes las tool_calls en los fragmentos (chunks) del flujo, junto con el texto que pueda generarse, lo que permite mostrar una respuesta fluida mientras se activan herramientas.
#Salidas estructuradas: forzar un esquema JSON
La llamada a herramientas sirve para actuar; las salidas estructuradas sirven para garantizar la forma de la respuesta. Con el parámetro format, proporcionas un esquema JSON que Ollama aplica durante la decodificación: el modelo está obligado, token a token, a producir únicamente una salida válida según el esquema. Se acabó el análisis frágil de un JSON aproximado: la estructura queda garantizada por diseño.
Lo más práctico en Python es describir la estructura con un modelo Pydantic, luego obtener el esquema mediante model_json_schema(). Luego obtienes un objeto tipado y validado.
#Gestión de errores y escollos habituales
La llamada a herramientas rara vez falla de forma evidente: la mayoría de las veces, el modelo «se desvía» silenciosamente. A continuación, los fallos frecuentes y cómo solucionarlos.
- Ningún tool_call devuelto
- El modelo respondió con texto cuando era necesario usar una herramienta. Mejora la descripción de la herramienta o cambia de modelo: los modelos pequeños suelen fallar al decidir cuándo llamar a una herramienta.
- Argumentos ausentes o incorrectos
- function.arguments puede omitir un campo required o asignarle un tipo incorrecto. Valida con Pydantic o un try/except antes de llamar a la función real y devuelve el error al modelo como resultado de la herramienta.
- Herramienta inventada
- El modelo inventa un nombre de función inexistente. Por eso se usa OUTILS.get(name) que devuelve un mensaje de error en lugar de fallar — así el modelo puede corregirse en el siguiente turno.
- Bucle infinito de llamadas a herramientas
- Un modelo puede volver a solicitar la misma herramienta indefinidamente. Añade un contador de iteraciones con un máximo (por ejemplo, 5) para interrumpir el bucle y evitar que siga ejecutándose sin avanzar.
- Contexto truncado
- Ollama limita a veces el contexto a 2048 tokens por defecto, lo que borra el historial de herramientas en sesiones largas. Aumenta num_ctx mediante las opciones del modelo.
- Resultado no serializado
- Devolver un objeto Python sin serializar como content hace que falle la solicitud. Serialízalo siempre como una cadena (json.dumps o str) antes de añadirlo a los mensajes.
La idea clave: nunca dejar que un error de una herramienta provoque un fallo que detenga al agente. Devuelve el mensaje de error al modelo como si fuera un resultado. Un buen modelo lee «herramienta desconocida» o «falta un argumento» y ajusta su siguiente llamada por sí mismo.
#Para ir más allá
Ya sabes cómo hacer llamadas a herramientas con Ollama en Python: formato JSON de las herramientas, bucle de ejecución, paridad con OpenAI, streaming y salidas estructuradas restringidas por un esquema. Estas guías profundizan de forma natural en el tema.
- La API REST de Ollama
- «Integrar Ollama en una aplicación Python a través de la API REST» — los fundamentos del endpoint :11434, del streaming y del modo JSON, base de toda esta guía.
- Agentes con LangChain
- «Crear un agente de IA local en Python con LangChain y Ollama» — orquestar varias herramientas y memoria sobre una capa básica de llamadas a herramientas.
- Elegir tu cuantización
- «Elegir la cuantización (Q4, Q5, Q8, FP16)» — para equilibrar la VRAM y la calidad del modelo que controlará tus herramientas.
¿Un comentario, un error, una precisión? Avísanos, eso mejora la guía para todos.