Function Calling vs. Tool Use: aclaración de conceptos e implementaciones
Function Calling y Tool Use designan la misma función central: un LLM no devuelve texto libre, sino una llamada estructurada y conforme a un esquema a una función definida externamente. OpenAI acuñó «Function Calling»; Anthropic usa «Tool Use». Técnicamente, ambos se basan en JSON Schema y son casi idénticos, con diferencias en los nombres de los campos y en la mecánica de la API.
De un vistazo
- Function Calling (OpenAI) y Tool Use (Anthropic) son en gran medida sinónimos: ambos hacen que el LLM genere JSON estructurado en lugar de texto libre, y después un código determinista se encarga de ejecutarlo.
- La diferencia de implementación más visible está en los nombres de los campos: OpenAI usa 'parameters' en el esquema de la herramienta y Anthropic, 'input_schema'. Por debajo, ambos se basan en JSON Schema. Además, difieren el formato de respuesta y el de devolución de las llamadas a herramientas.
- El LLM no ejecuta nada por sí mismo: entrega una llamada a una herramienta, tu código la ejecuta y devuelve el resultado. En Anthropic, el stop_reason 'tool_use' indica que hay una llamada pendiente.
- Las llamadas paralelas a herramientas son el comportamiento por defecto y se pueden desactivar (Anthropic: disable_parallel_tool_use). Los errores deben volver al modelo como tool_result estructurado con is_error, no como excepción.
- La selección de herramientas no escala de forma ilimitada: pocas herramientas bien delimitadas son más fiables que muchas que se solapan. Las definiciones de herramientas son a la vez presupuesto de prompt y objetivo de caché.
- Regla práctica: lee siempre los inputs de las herramientas con un parser JSON, nunca mediante comparación de cadenas, porque el escapado puede variar entre versiones del modelo.
Function Calling y Tool Use designan, en esencia, la misma capacidad: en un punto concreto, un Large Language Model no devuelve texto libre, sino una llamada estructurada y conforme a un esquema a una función definida externamente, con los argumentos adecuados. OpenAI introdujo el término «Function Calling»; Anthropic habla de «Tool Use». Técnicamente, ambos se basan en JSON Schema y son casi idénticos. Las diferencias están en el nombre de los campos del esquema y en algunas mecánicas de la API, no en el principio básico.
Este artículo forma parte del clúster en torno al pilar «Fundamentos de LLM para agentes» y profundiza en lo que se esboza en el artículo hermano sobre los fundamentos del tool calling. Todos los datos técnicos corresponden al estado de 2026.
- Sinónimos con matices: «Tool Use» es el término algo más amplio, porque en Anthropic una herramienta también puede ser un servicio del lado del servidor (búsqueda web, ejecución de código) o un servidor MCP. «Function Calling», en sentido estricto, se refiere a la llamada a una función pura.
- El modelo no ejecuta nada: solo entrega la llamada. Tu código valida los argumentos, ejecuta la función y devuelve el resultado. Solo entonces el LLM formula la respuesta.
- La diferencia de implementación más visible: OpenAI usa en el esquema de la herramienta el campo
parameters; Anthropic,input_schema. Por debajo, ambos se basan en JSON Schema.
Cómo genera un LLM llamadas estructuradas a herramientas
El mecanismo está construido de la misma forma en ambos ecosistemas. Además de la petición del usuario, le pasas al modelo una lista de definiciones de herramientas. Cada definición incluye un nombre, una descripción (cuándo usar la herramienta y cuándo no) y un esquema de entrada con parámetros tipados, algunos de ellos obligatorios.
A partir de las definiciones de herramientas, la configuración de herramientas y tu system prompt, la API de Anthropic construye un prompt propio de tool use. Según la documentación de Anthropic, sigue aproximadamente este patrón:
```
In this environment you have access to a set of tools you can use to answer the user's question.
{{ FORMATTING INSTRUCTIONS }}
String and scalar parameters should be specified as is, while lists and objects should use JSON format.
Here are the functions available in JSONSchema format:
{{ TOOL DEFINITIONS IN JSON SCHEMA }}
{{ USER SYSTEM PROMPT }}
{{ TOOL CONFIGURATION }}
```
De ahí se deriva una consecuencia económica que a menudo se pasa por alto: cada herramienta cuesta tokens de forma permanente como esquema (normalmente en torno a 100–300 por herramienta, según la complejidad del esquema), porque el modelo lee las definiciones en cada turno de inferencia. Un catálogo de diez herramientas ronda así los 1.000–3.000 tokens por llamada. Con 100.000 llamadas al mes, son 100–300 millones de tokens de pura carga de esquema, algo que solo resulta viable económicamente con Prompt Caching.
Por eso, en el enfoque 12-Factor Agents de Dex Horthy rige este principio: las herramientas no son más que outputs estructurados. Lo que produce el LLM es JSON conforme a un esquema; lo que se ejecuta es código determinista que tú mismo posees y controlas.
Definición del esquema: JSON Schema como lenguaje común
Ambos proveedores se apoyan internamente en JSON Schema como lingua franca. Herramientas code-first como Pydantic (Python) o Zod (TypeScript) generan este esquema automáticamente a partir de definiciones de tipos.
Una definición de herramienta sólida vive de su descripción, tanto a nivel de herramienta como de campo. Un parámetro recipient_email con la descripción «Dirección de correo electrónico del destinatario conforme a RFC 5321; debe corresponder a un registro de cliente existente» es mucho más fiable que el mismo campo sin descripción. Una regla práctica contrastada: la descripción no solo debe decir qué hace una herramienta, sino sobre todo cuándo debe llamarse y cómo deben construirse los argumentos. Es el contrato de interfaz permanente entre el modelo y la API, y en los modelos más recientes, más reservados a la hora de recurrir a herramientas, resulta mediblemente más eficaz que una simple descripción de la función.
Consejo para empresas en Europa: mantén en inglés los nombres de las herramientas y los identificadores de parámetros (interoperabilidad con bibliotecas, logs, OpenAPI), pero redacta las descripciones en el idioma en el que opera el agente. Los catálogos multilingües funcionan con modelos frontier, pero son una fuente evitable de inconsistencias.
Diferencias de implementación: OpenAI vs. Anthropic
La siguiente tabla resume las diferencias relevantes en la práctica (estado de 2026). Importante: predominan las similitudes. En producción, muchos equipos usan una capa de abstracción (por ejemplo, LiteLLM o el Vercel AI SDK) para encapsular las diferencias en los nombres de los campos.
Aspecto | OpenAI (Function Calling) | Anthropic (Tool Use) |
|---|---|---|
Término | Function Calling | Tool Use |
Campo del esquema para los parámetros | | |
Estándar de esquema | JSON Schema | JSON Schema |
Señal de llamada a herramienta | Entrada | |
Control de la selección | | |
Llamadas paralelas | Activas por defecto | Activas por defecto |
Desactivar el paralelismo | Parámetro | |
Devolución del resultado | | Bloque |
Señalizar errores | error estructurado en el resultado | |
Herramientas del lado del servidor | entre otras, Code Interpreter y búsqueda web | Ejecución de código, búsqueda web/web fetch |
Cumplimiento estricto del esquema | Structured Outputs / | |
En Anthropic hay cuatro modos disponibles para tool_choice: {"type": "auto"} (decide el modelo, valor por defecto), {"type": "any"} (hay que usar al menos una herramienta), {"type": "tool", "name": "..."} (se fuerza una herramienta concreta) y {"type": "none"} (sin herramientas). Con auto, disable_parallel_tool_use: true limita la respuesta a una llamada como máximo; con any y tool, a exactamente una. Según la documentación de Anthropic, Claude Opus 5.5, Sonnet 5.5, Fable 5.1 y Mythos 5.1 no admiten any ni tool. Lo mismo ocurre, según la documentación de Tool Use, cuando el Extended Thinking está activado manualmente. En ambos casos solo quedan auto y none.
Llamadas paralelas a herramientas y el bucle de agente
Los modelos frontier pueden solicitar varias llamadas a herramientas a la vez en una sola respuesta, por ejemplo «obtener perfil», «cargar últimos pedidos» y «comprobar stock» en paralelo. Esto reduce de forma notable las idas y vueltas y la latencia. Tu harness tiene que procesar todas las llamadas solicitadas y devolver los resultados juntos en un único mensaje de seguimiento.
El bucle de agente manual en Anthropic sigue este patrón: llamar a la API y comprobar la respuesta. Mientras stop_reason sea igual a tool_use, se ejecutan los bloques de tool use, se añaden al historial de mensajes la respuesta completa del modelo y los bloques tool_result (cada uno con su tool_use_id correspondiente) y se lanza la siguiente llamada a la API. El bucle termina cuando stop_reason es igual a end_turn. Como alternativa, los SDK oficiales ofrecen un «Tool Runner» automático que encapsula este bucle; el bucle manual se usa cuando hace falta un control más fino, por ejemplo para puntos de aprobación o un logging propio.
Gestión de errores: robusta en lugar de frágil
La segunda causa más frecuente de agentes inestables en producción, después de las definiciones de herramientas ambiguas, es una mala gestión de errores. Hay tres principios que valen en todos los sectores:
- Devolver los errores como tool result estructurado, en lugar de lanzar una excepción que interrumpa el bucle. Un
{ "error": "code", "message": "...", "retry_after_seconds": 30 }condensado permite al modelo decidir si corrige los argumentos, elige otra estrategia o escala el problema. En Anthropic, además, establecesis_error: trueen el bloquetool_result. - Mantener compacto el contexto del error. No vuelques stack traces en bruto en la ventana de contexto. Eso contamina el contexto y empeora las respuestas siguientes. Resume antes los stack traces.
- Limitar los reintentos. Tres intentos es lo habitual. Distingue según el tipo de error: los errores de herramienta (500/timeout) se reintentan con backoff; los errores de validación (400), con argumentos ajustados; los errores de permisos (403) se escalan a una persona sin reintentar; los rate limits (429), con backoff y, si hace falta, cambiando de modelo.
Un antipatrón persistente es la supresión silenciosa de errores: las llamadas a herramientas fallan, pero el agente sigue funcionando como si todo estuviera bien. Devuelve siempre los errores al modelo de forma explícita.
Una segunda regla práctica: lee siempre los inputs de las herramientas con un parser JSON, nunca mediante comparación de cadenas sobre el input serializado. Los modelos Claude pueden gestionar el escapado JSON de forma distinta según la versión, por ejemplo en el escapado de Unicode o de barras. Quien compara cadenas en bruto se fabrica un bug difícil de localizar.
Ejemplo concreto en pseudocódigo
El siguiente ejemplo en pseudocódigo muestra una definición de herramienta y un bucle manual con la notación de Anthropic. En OpenAI, input_schema se llamaría parameters. El bucle también sería distinto: en la Responses API, los argumentos llegan como cadena JSON en una entrada function_call con call_id, y el resultado vuelve como function_call_output con el mismo call_id, como muestra la guía de Function Calling de OpenAI.
```
tool = {
"name": "fetch_recent_orders",
"description": "Carga los últimos pedidos de un cliente. "
"Úsala cuando el usuario pregunte por el historial, el estado "
"o las entregas de sus pedidos. NO la uses para una simple "
"búsqueda de productos; para eso, usa search_products. "
"Returns: lista de {id, total, status, items}.",
"input_schema": {
"type": "object",
"properties": {
"user_id": {"type": "string", "description": "ID interno del cliente"},
"limit": {"type": "integer", "description": "Número máx. (por defecto 10)"}
},
"required": ["user_id"]
}
}
messages = [{"role": "user", "content": "¿Dónde está mi último pedido?"}]
while True:
response = client.messages.create(
model="claude-opus-5-5", # modelo de ejemplo
max_tokens=1024,
tools=[tool],
messages=messages,
)
if response.stop_reason != "tool_use":
break # end_turn -> listo
messages.append({"role": "assistant", "content": response.content})
results = []
for block in response.content:
if block.type == "tool_use": # puede haber varios -> en paralelo
try:
data = run_tool(block.name, block.input) # código propio
results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": to_json(data),
})
except ToolError as e:
results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": str(e),
"is_error": True,
})
messages.append({"role": "user", "content": results})
```
Ejemplo de cálculo de la carga de herramientas: supongamos que este agente funciona con cinco herramientas de ~200 tokens de esquema cada una (1.000 tokens) más 800 tokens de system prompt. Con 100.000 llamadas al mes, solo el prefijo estable genera unos 180 millones de tokens de entrada. Con el Prompt Caching de Anthropic, una lectura de caché cuesta en la mayoría de los modelos el 10 % de la tarifa de entrada estándar, por ejemplo 0,30 en lugar de 3,00 dólares estadounidenses por millón de tokens en Sonnet 4.6. En Opus 5.5 y Sonnet 5.5 es el 5 %, y en Fable 5.1 y Mythos 5.1, el 2,5 %. El requisito es un catálogo de herramientas estable. Cualquier cambio en las definiciones de herramientas, aunque solo afecte al orden, invalida la caché por completo. De ahí sale el patrón de producción: desplegar los catálogos de herramientas en releases planificadas, sin hotfixes en las definiciones de herramientas.
Cuántas herramientas tienen sentido y por qué el problema es el solapamiento
La precisión en la selección de herramientas no escala de forma ilimitada. Ha dado buen resultado cargar de forma permanente solo un núcleo pequeño y añadir otras herramientas de forma dinámica mediante una tool search tool. Eso mantiene pequeño el contexto fijo y protege la caché, porque los esquemas se añaden en lugar de sustituirse. Sin embargo, el verdadero cuello de botella no es la cantidad, sino el solapamiento: un puñado de herramientas bien delimitadas se gestiona sin problemas, mientras que unas pocas que se solapan llevan al modelo a adivinar una y otra vez.
Dos herramientas que podrían responder de forma plausible a la misma petición, como search_documents y search_knowledge_base, son un problema que ningún prompt, por bueno que sea, resuelve. Ante «Encuentra información sobre X», el modelo adivina. La contramedida más eficaz, y la que más se olvida, es la cláusula de cuándo no usarla en cada descripción. Como referencia pública de benchmark para la precisión de selección sirve el Berkeley Function-Calling Leaderboard (BFCL); sus valores, sin embargo, fluctúan y conviene volver a medirlos con tu propio conjunto de evaluación, no compararlos con un post de marketing.
Para agencias y directivos B2B
Function Calling, o Tool Use, es el puente entre el modelo de lenguaje y tus sistemas reales: CRM, contabilidad, envíos, base de conocimiento. La confusión de términos no tiene importancia; la disciplina en la implementación, sí. Que un agente funcione de forma fiable en producción depende de definiciones de herramientas bien delimitadas, de una gestión de errores sólida mediante resultados estructurados, de condiciones de terminación controladas y de una estrategia de catálogo pensada para la caché, no de elegir entre OpenAI y Anthropic.
Como agencia de Viena especializada en agentes de IA, acompañamos a empresas de toda Europa desde el diseño del esquema de herramientas y la abstracción del proveedor hasta un bucle de agente listo para producción y auditable. Si quieres integrar llamadas estructuradas a herramientas de forma fiable en tus procesos de negocio, habla con nosotros.
Abre el chat con un prompt ya preparado.
Preguntas frecuentes
¿Function Calling es lo mismo que Tool Use?
¿En qué se diferencian técnicamente OpenAI y Anthropic?
¿El LLM ejecuta la función por sí mismo?
¿Cómo funcionan las llamadas paralelas a herramientas?
¿Cómo se gestionan correctamente los errores en las llamadas a herramientas?
¿Cuántas herramientas debería tener un agente?
¿Quieres profundizar?
Recibe nuevos análisis directamente en tu bandeja de entrada o descubre cómo aplicamos este conocimiento en empresas.