OpenAI Function Calling: Ejemplos para Empezar
Updated on

En el panorama en constante evolución de la inteligencia artificial (AI), el function calling de OpenAI (ahora expuesto mediante tools) se ha convertido en uno de los bloques de construcción más importantes para aplicaciones reales. Te permite conectar modelos de lenguaje potentes como gpt-4.1 y gpt-4.1-mini con tus propias APIs, bases de datos y lógica de negocio.
En lugar de pedirle al modelo que “escriba algo de JSON” y esperar que siga tu formato, describes funciones en JSON Schema, y el modelo devuelve una llamada de función estructurada que puedes ejecutar de forma segura en tu código.
En esta guía aprenderás:
- Qué es OpenAI function calling y cómo funciona hoy
- Cómo definir tools/functions con JSON Schema
- Ejemplos prácticos: programar reuniones, obtener precios de acciones, reservar viajes
- Cómo usar funcionalidades modernas como Structured Outputs para hacer el function calling más fiable
- Buenas prácticas, errores comunes y preguntas frecuentes
¿Qué es OpenAI Function Calling (Tools)?
Function calling permite que un modelo responda con llamadas de función legibles por máquina en lugar de texto plano. En la API moderna, estas se representan como tools:
- Defines tools con:
type: "function"function.name,function.descriptionfunction.parameters(un JSON Schema que describe los argumentos)
- Envías estos tools junto con tu prompt.
- El modelo decide si debe llamar a un tool y devuelve una tool call con un nombre de función y argumentos JSON.
- Tu aplicación:
- Analiza (parsea) la tool call,
- Ejecuta la función correspondiente en tu backend,
- Opcionalmente envía el resultado de vuelta al modelo para generar una respuesta final orientada al usuario.
Internamente, function calling está disponible en:
- La Responses API (
POST /v1/responses) – la forma recomendada para aplicaciones nuevas. - La clásica Chat Completions API (
POST /v1/chat/completions) – aún muy utilizada y soportada.
Históricamente, function calling usaba los parámetros functions y function_call. Estos ahora están obsoletos (deprecated) en favor de tools y tool_choice, así que todo el código nuevo debería usar el estilo moderno.
Ejemplo Básico: Programar una Reunión (Chat Completions API)
Empecemos con un ejemplo sencillo usando Chat Completions API. Pediremos al modelo que programe una reunión y le permitiremos devolver argumentos estructurados para una función schedule_meeting.
Petición JSON (conceptual)
{
"model": "gpt-4.1-mini",
"messages": [
{
"role": "user",
"content": "Schedule a meeting with John Doe next Tuesday at 3 PM."
}
],
"tools": [
{
"type": "function",
"function": {
"name": "schedule_meeting",
"description": "Schedule a meeting in the calendar.",
"parameters": {
"type": "object",
"properties": {
"attendee": {
"type": "string",
"description": "Name of the attendee for the meeting."
},
"date": {
"type": "string",
"description": "Date of the meeting in ISO 8601 format."
},
"time": {
"type": "string",
"description": "Time of the meeting, including time zone."
}
},
"required": ["attendee", "date", "time"],
"additionalProperties": false
},
"strict": true
}
}
],
"tool_choice": "auto"
}La respuesta del modelo contendrá algo como:
{
"role": "assistant",
"tool_calls": [
{
"id": "call_123",
"type": "function",
"function": {
"name": "schedule_meeting",
"arguments": "{\"attendee\":\"John Doe\",\"date\":\"2025-11-18\",\"time\":\"15:00 Europe/Berlin\"}"
}
}
]
}Tu backend puede parsear arguments, llamar a tu función real schedule_meeting (por ejemplo, usando Google Calendar u Outlook) y, opcionalmente, enviar el resultado de vuelta al modelo para que genere un mensaje de confirmación amigable.
Ejemplo: Consulta de Precio de Acciones
Aquí tienes un ejemplo más “tipo API”: llamar a una función get_stock_price a partir de lenguaje natural.
Petición con un tool get_stock_price
{
"model": "gpt-4.1-mini",
"messages": [
{
"role": "user",
"content": "What's the current price of Apple stock?"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_stock_price",
"description": "Get the current stock price for a ticker symbol.",
"parameters": {
"type": "object",
"properties": {
"ticker_symbol": {
"type": "string",
"description": "Ticker symbol of the stock, e.g. AAPL."
},
"currency": {
"type": "string",
"enum": ["USD", "EUR", "GBP"],
"description": "Currency for the price."
}
},
"required": ["ticker_symbol"],
"additionalProperties": false
},
"strict": true
}
}
],
"tool_choice": "auto"
}Cuando el usuario pregunta “What’s the current price of Apple stock?”, el modelo producirá una tool call como:
{
"type": "function",
"function": {
"name": "get_stock_price",
"arguments": "{\"ticker_symbol\":\"AAPL\",\"currency\":\"USD\"}"
}
}Luego tú:
- Llamas a tu API real de precios de acciones.
- Devuelves el resultado al modelo en una petición posterior.
- Dejas que el modelo genere una explicación amigable para el usuario.
Ejemplo: Reserva de Viajes con Function Calling
Function calling brilla cuando los prompts son desordenados y humanos, pero tu backend necesita parámetros limpios y estructurados.
Considera esta frase:
“I need to book a trip from Bonn to Amsterdam for my wife, mother, my two sons, my daughter, and me. The airline must fly direct.”
Queremos que el modelo extraiga:
departuredestinationnumber_peopletravel_mode(por ejemplo, plane / train)
Definición de tool para book_travel
{
"model": "gpt-4.1-mini",
"messages": [
{
"role": "user",
"content": "I need to book a trip from Bonn to Amsterdam for my wife, mother, my two sons and daughter, and me. The airline must fly direct."
}
],
"tools": [
{
"type": "function",
"function": {
"name": "book_travel",
"description": "Search or book transportation for a group of travelers.",
"parameters": {
"type": "object",
"properties": {
"departure": {
"type": "string",
"description": "City or airport you are traveling from."
},
"destination": {
"type": "string",
"description": "City or airport you are traveling to."
},
"number_people": {
"type": "integer",
"description": "How many people are traveling."
},
"travel_mode": {
"type": "string",
"enum": ["plane", "train", "bus", "car"],
"description": "Preferred mode of travel."
},
"non_stop_only": {
"type": "boolean",
"description": "Whether only non-stop options are allowed."
}
},
"required": ["departure", "destination", "number_people"],
"additionalProperties": false
},
"strict": true
}
}
],
"tool_choice": "auto"
}El modelo podría generar:
{
"name": "book_travel",
"arguments": "{\"departure\":\"Bonn\",\"destination\":\"Amsterdam\",\"number_people\":6,\"travel_mode\":\"plane\",\"non_stop_only\":true}"
}A partir de aquí puedes conectar esto directamente con tu servicio de búsqueda de vuelos.
Uso de los SDKs Modernos de OpenAI (Python y JavaScript)
Normalmente no enviarás JSON crudo a mano. En su lugar, usarás los SDK oficiales y trabajarás con respuestas tipadas.
Ejemplo en Python (Chat Completions + tools)
from openai import OpenAI
client = OpenAI()
tools = [
{
"type": "function",
"function": {
"name": "schedule_meeting",
"description": "Schedule a meeting in the calendar.",
"parameters": {
"type": "object",
"properties": {
"attendee": {"type": "string"},
"date": {"type": "string"},
"time": {"type": "string"},
},
"required": ["attendee", "date", "time"],
"additionalProperties": False,
},
"strict": True,
},
}
]
completion = client.chat.completions.create(
model="gpt-4.1-mini",
messages=[
{
"role": "user",
"content": "Schedule a meeting with John Doe next Tuesday at 3 PM.",
}
],
tools=tools,
tool_choice="auto",
)
tool_calls = completion.choices[0].message.tool_calls
if tool_calls:
call = tool_calls[0]
args = client.responses._client._utils.json.loads(call.function.arguments)
# Your real implementation:
# result = schedule_meeting(**args)Ejemplo en JavaScript (Node.js)
import OpenAI from "openai";
const client = new OpenAI();
const tools = [
{
type: "function",
function: {
name: "get_stock_price",
description: "Get the current price for a given ticker symbol.",
parameters: {
type: "object",
properties: {
ticker_symbol: {
type: "string",
description: "Stock ticker symbol, e.g. AAPL",
},
},
required: ["ticker_symbol"],
additionalProperties: false,
},
strict: true,
},
},
];
const response = await client.chat.completions.create({
model: "gpt-4.1-mini",
messages: [
{ role: "user", content: "What's the current price of Apple stock?" },
],
tools,
tool_choice: "auto",
});
const toolCalls = response.choices[0].message.tool_calls;Structured Outputs: Function Calling Más Fiable
JSON Mode garantiza que el modelo devuelva JSON válido, pero no necesariamente JSON que cumpla tu esquema. Structured Outputs es una funcionalidad más reciente que refuerza esto aplicando tu JSON Schema cuando el modelo llama tools:
- Establece
"strict": trueen la definiciónfunctionde tu tool. - Entonces se garantiza que los argumentos del modelo se ajusten a tu esquema (tipos, campos requeridos, sin propiedades extra), reduciendo drásticamente los errores de parseo y validación.
Esto es especialmente útil cuando:
- Extraes datos complejos y anidados a partir de texto no estructurado
- Construyes flujos de trabajo multi-paso donde cada paso depende de datos estructurados precisos
- Generas parámetros para sistemas posteriores como SQL, pipelines de analítica o visualizaciones de datos
Incluso con Structured Outputs, deberías seguir tratando los valores como input no confiable (por ejemplo, revisar rangos, manejar IDs ausentes, validar reglas de negocio).
Patrones de Diseño y Buenas Prácticas
1. Mantén los tools pequeños y enfocados
En lugar de una enorme función do_everything, define tools pequeños y componibles:
get_user_profileget_user_orderscreate_support_ticketschedule_meeting
Esto hace que los schemas sean más fáciles de mantener y mejora la capacidad del modelo para elegir el tool adecuado.
2. Usa nombres y descripciones claros
- Los nombres de funciones deberían ser verbos:
create_invoice,fetch_weather,book_travel. - Las descripciones deberían indicar cuándo usar la función, no solo qué hace.
Mal:
“Get data from the system.”
Bien:
“Use this function whenever the user asks about their recent orders or order history.”
3. Sé estricto con los schemas
- Usa campos
requiredyadditionalProperties: false. - Usa enums para opciones conocidas (
"enum": ["plane", "train"]). - Añade restricciones simples donde sea útil (formatos de cadena, enteros mínimos, etc.).
4. Valida y registra (log) todo
- Valida siempre los argumentos de tools del lado del servidor antes de ejecutarlos.
- Registra las tool calls y los prompts en lenguaje natural para depurar.
- Considera reintentos (posiblemente con un breve mensaje de sistema correctivo) cuando la validación falle.
5. Encadena tools cuando sea necesario
Para flujos de trabajo más complejos (por ejemplo, obtener usuario → obtener pedidos → resumir), puedes:
- Dejar que el modelo llame a múltiples tools en una sola respuesta (tool calls en paralelo), o
- Orquestar paso a paso desde tu backend, alimentando los resultados previos de tools de vuelta al modelo.
Un Ejemplo Concreto Multi-paso: Matemáticas con Formatos Mixtos
Veamos de nuevo un ejemplo clásico que muestra por qué function calling es más que una curiosidad.
“What’s the result of 22 plus 5 in decimal added to the hexadecimal number A?”
Podemos resolverlo definiendo dos tools:
add_decimal(a: number, b: number)add_hex(a: string, b: string)
El flujo de trabajo:
- El modelo llama a
add_decimalcon los argumentos{ "a": 22, "b": 5 }→ tu código devuelve27. - Envías el resultado y la pregunta original de vuelta al modelo.
- El modelo luego llama a
add_hexcon argumentos{ "a": "27", "b": "A" }. - Tu código devuelve
31, y el modelo explica el resultado final al usuario.
Este patrón se generaliza a cualquier dominio: finanzas, analítica, data viz, DevOps, dashboards de BI, etc. Function calling + tus propios tools = un asistente de AI flexible y consciente del dominio.
¿Quieres Generar Cualquier Tipo de Gráfico Fácilmente con el Poder de ChatGPT? Prueba VizGPT (opens in a new tab): describe tus datos y el gráfico en lenguaje natural y obtén gráficos bonitos sin código.
Actualizaciones Relacionadas de OpenAI (Visión General)
OpenAI ha seguido mejorando la experiencia de function calling y tools con:
- Context windows más grandes en los modelos modernos, lo que facilita trabajar con conversaciones largas, documentos o schemas extensos.
- Structured Outputs para tools y formatos de respuesta, garantizando que la salida del modelo cumpla tu JSON Schema.
- Una Responses API y un ecosistema de tools más ricos (búsqueda web, file search, ejecución de código y más), que facilitan construir flujos de trabajo agentic completos con los mismos conceptos de function calling.
Para precios y la lista más reciente de modelos, consulta siempre la documentación oficial de OpenAI y la página de pricing.
Conclusión
Function calling es una de las formas más potentes de convertir LLMs en componentes prácticos y fiables de tu stack:
- Describes lo que tus funciones pueden hacer en JSON Schema.
- El modelo decide cuándo y cómo llamarlas.
- Tu backend ejecuta las llamadas y, junto con el modelo, construye experiencias ricas para tus usuarios.
Ya sea que estés programando reuniones, consultando precios de acciones, reservando viajes o impulsando un dashboard de BI completo con herramientas como PyGWalker y VizGPT, function calling es el pegamento entre el lenguaje natural y las acciones reales.
Empieza de forma sencilla con una sola función, valida todo y luego evoluciona hacia flujos de trabajo agentic multi-paso a medida que tu aplicación madura.
Preguntas Frecuentes
-
¿Qué es la funcionalidad de function calling de OpenAI?
Function calling te permite describir funciones (tools) con JSON Schema para que el modelo pueda devolver una llamada de función estructurada en lugar de texto plano. El modelo no ejecuta nada por sí mismo; tu aplicación parsea la tool call y ejecuta la función real.
-
¿Qué modelos soportan function calling?
Los modelos modernos GPT-4, GPT-4.1, GPT-4o, GPT-4o-mini y los modelos más recientes de la serie GPT-5/o soportan tools/function calling a través de las APIs de Chat Completions y Responses. Consulta la documentación de OpenAI para ver la lista actualizada de modelos compatibles.
-
¿Debería usar los parámetros antiguos
functions/function_call?No. Esos fueron la primera generación de parámetros para function calling y ahora se consideran legacy. El código nuevo debería usar
toolsytool_choice, que son más flexibles y funcionan con los modelos y APIs más recientes. -
¿En qué se diferencia esto de JSON Mode o Structured Outputs?
- JSON Mode (
response_format: { "type": "json_object" }) garantiza que el modelo devuelva JSON válido, pero no aplica tu schema. - Function calling con Structured Outputs (
strict: trueen la definición del tool) garantiza que los argumentos cumplan el JSON Schema que proporcionaste. - Puedes combinar function calling con JSON Mode para tener un control aún mayor.
- JSON Mode (
-
¿Cuáles son algunos casos de uso comunes?
- Chatbots que llaman APIs externas (clima, CRM, ticketing, herramientas internas)
- Lenguaje natural → llamadas a APIs, consultas SQL, filtros de búsqueda
- Pipelines de extracción de datos que convierten texto no estructurado en registros estructurados
- Flujos de trabajo “agent” multi-paso para automatización, analítica y BI

