{"id":676,"date":"2026-06-25T12:02:00","date_gmt":"2026-06-25T10:02:00","guid":{"rendered":"https:\/\/atlaszn.com\/blog\/?p=676"},"modified":"2026-06-23T01:44:45","modified_gmt":"2026-06-22T23:44:45","slug":"tool-use","status":"publish","type":"post","link":"https:\/\/atlaszn.com\/blog\/tool-use\/","title":{"rendered":"Tool Use con LLMs: C\u00f3mo los agentes interact\u00faan con el mundo real"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">El problema: Modelos desconectados del mundo<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Un LLM es un generador de texto. Su conocimiento es est\u00e1tico, limitado a los datos de entrenamiento, y no tiene forma de interactuar con sistemas externos. No puede consultar una base de datos, llamar a una API, ejecutar c\u00f3digo, ni acceder a informaci\u00f3n en tiempo real.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Esto lo convierte en un sistema pasivo, responde, pero no act\u00faa. Para tareas que requieren datos frescos, acceso a informaci\u00f3n privada, o interacci\u00f3n con otros sistemas, el modelo por s\u00ed solo es insuficiente.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tool Use cierra esa brecha, permite que el modelo decida cu\u00e1ndo necesita interactuar con el mundo exterior, qu\u00e9 herramienta usar, y con qu\u00e9 par\u00e1metros. Transforma al LLM de un respondedor pasivo en un sistema activo que percibe, razona y act\u00faa.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pero no es tan simple como \u00abconectar herramientas\u00bb. La decisi\u00f3n de qu\u00e9 herramientas exponer, c\u00f3mo describirlas, y c\u00f3mo manejar sus fallos define si el agente funciona o se rompe en producci\u00f3n.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">El ciclo de Tool Use<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">El patr\u00f3n sigue seis etapas:<\/p>\n\n\n\n<ul class=\"wp-block-list\" class=\"wp-block-list\">\n<li><strong>Definici\u00f3n de herramientas<\/strong>: las funciones externas se definen con nombre, descripci\u00f3n, tipos de par\u00e1metro y metadatos visibles para el LLM.<\/li>\n\n\n\n<li><strong>Decisi\u00f3n del LLM<\/strong>: el modelo eval\u00faa la petici\u00f3n del usuario y decide si necesita llamar a una herramienta.<\/li>\n\n\n\n<li><strong>Generaci\u00f3n de la llamada<\/strong>: el LLM produce un output estructurado (JSON) especificando el nombre de la herramienta y los argumentos.<\/li>\n\n\n\n<li><strong>Ejecuci\u00f3n<\/strong>: la capa de orquestaci\u00f3n intercepta la llamada, ejecuta la funci\u00f3n real, y captura el resultado.<\/li>\n\n\n\n<li><strong>Observaci\u00f3n<\/strong>: el resultado de la herramienta se devuelve al agente.<\/li>\n\n\n\n<li><strong>Procesamiento<\/strong>: el modelo incorpora el resultado en su respuesta o decide el siguiente paso (otra llamada, reflection, o respuesta final).<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"683\" height=\"1024\" src=\"https:\/\/atlaszn.com\/blog\/wp-content\/uploads\/2026\/06\/diagrama_tools-683x1024.webp\" alt=\"\" class=\"wp-image-696\" srcset=\"https:\/\/atlaszn.com\/blog\/wp-content\/uploads\/2026\/06\/diagrama_tools-683x1024.webp 683w, https:\/\/atlaszn.com\/blog\/wp-content\/uploads\/2026\/06\/diagrama_tools-200x300.webp 200w, https:\/\/atlaszn.com\/blog\/wp-content\/uploads\/2026\/06\/diagrama_tools-768x1152.webp 768w, https:\/\/atlaszn.com\/blog\/wp-content\/uploads\/2026\/06\/diagrama_tools.webp 1024w\" sizes=\"auto, (max-width: 683px) 100vw, 683px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Nota que la validaci\u00f3n del schema aparece entre la generaci\u00f3n y la ejecuci\u00f3n. Sin ella, una llamada alucinada se traduce en un error de runtime. Con ella, el agente puede recuperar o pedir aclaraci\u00f3n antes de ejecutar algo inv\u00e1lido.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Function Calling vs Tool Use<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Son t\u00e9rminos que se usan como sin\u00f3nimos, pero no lo son.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Function Calling es el mecanismo t\u00e9cnico: el LLM genera un objeto JSON con el nombre de la funci\u00f3n y sus argumentos. Es lo que OpenAI llam\u00f3 \u00abfunction calling\u00bb en su API original, y lo que Anthropic llama \u00abtool use\u00bb. Es el canal de comunicaci\u00f3n entre el modelo y el sistema externo.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tool Use es el concepto m\u00e1s amplio. Una \u00abherramienta\u00bb puede ser:<\/p>\n\n\n\n<ul class=\"wp-block-list\" class=\"wp-block-list\">\n<li>Una funci\u00f3n Python local.<\/li>\n\n\n\n<li>Un endpoint REST de una API externa.<\/li>\n\n\n\n<li>Una consulta a una base de datos.<\/li>\n\n\n\n<li>Un executor de c\u00f3digo en sandbox.<\/li>\n\n\n\n<li>Otro agente especializado (Agent-as-Tool).<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">La distinci\u00f3n importa: afecta c\u00f3mo dise\u00f1as el sistema \u2014 y las consecuencias de hacerlo mal son errores silenciosos que el usuario interpreta como respuestas correctas. Si solo usas funciones locales, el riesgo es bajo. Si expones APIs externas o executores de c\u00f3digo, el riesgo crece y necesitas capas de validaci\u00f3n y seguridad adicionales.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Ejemplo: herramienta b\u00e1sica con LangChain<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>from langchain_core.tools import tool\n\n@tool\ndef buscar_clima(ciudad: str) -&gt; str:\n    \"\"\"Obtiene el clima actual de una ciudad.\n    Usa esta herramienta cuando el usuario pregunta por el tiempo,\n    temperatura o condiciones atmosf\u00e9ricas de un lugar espec\u00edfico.\n    \n    Args:\n        ciudad: nombre de la ciudad en espa\u00f1ol o ingl\u00e9s.\n    \"\"\"\n    # En producci\u00f3n: llamada a API real (OpenWeather, etc.)\n    datos = {\n        \"madrid\": \"Soleado, 28C\",\n        \"london\": \"Nublado, 15C\",\n        \"tokyo\": \"Lluvioso, 22C\",\n    }\n    return datos.get(ciudad.lower(), f\"Sin datos para: {ciudad}\")\n\n@tool\ndef calcular_expresion(expresion: str) -&gt; str:\n    \"\"\"Eval\u00faa una expresi\u00f3n matem\u00e1tica y devuelve el resultado.\n    Usa esta herramienta para c\u00e1lculos precisos: aritm\u00e9tica,\n    conversiones de unidades, operaciones financieras.\n    \n    Args:\n        expresion: expresi\u00f3n matem\u00e1tica en formato Python (ej: \"2 + 2 * 3\").\n    \"\"\"\n    try:\n        resultado = eval(expresion, {\"__builtins__\": {}}, {})\n        return str(resultado)\n    except Exception as e:\n        return f\"Error: {e}\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Nota la estructura de los docstrings: descripci\u00f3n clara del prop\u00f3sito, cu\u00e1ndo usar la herramienta, y documentaci\u00f3n de los par\u00e1metros. El LLM decide qu\u00e9 herramienta llamar bas\u00e1ndose exclusivamente en estos docstrings. Descripciones vagas producen llamadas incorrectas.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Definici\u00f3n de herramientas: el arte invisible<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">La parte m\u00e1s subestimada de Tool Use es la definici\u00f3n de las herramientas. El LLM no ve el c\u00f3digo. Ve la descripci\u00f3n. Si la descripci\u00f3n es ambigua, el modelo elige mal.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Esto es lo que vimos en producci\u00f3n: ten\u00edamos dos herramientas de b\u00fasqueda con descripciones similares (\u00abbuscar informaci\u00f3n\u00bb y \u00abbuscar datos\u00bb). El modelo las confund\u00eda constantemente, llamando a la herramienta de informaci\u00f3n general cuando necesitaba datos estructurados, y viceversa. El resultado: outputs incorrectos que el agente presentaba como ciertos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lo que funcion\u00f3: renombres expl\u00edcitos y descripciones que dejaban claro el caso de uso de cada una. \u00abbuscar_informaci\u00f3n_general\u00bb para consultas abiertas. \u00abconsultar_base_datos\u00bb para datos estructurados con schema conocido. La diferencia no estaba en el c\u00f3digo, estaba en la descripci\u00f3n.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Y esto no fue el \u00fanico problema. Hubo una herramienta de c\u00e1lculo financiero que el modelo usaba para todo: conversiones de moneda, intereses, incluso para pedir \u00abcu\u00e1nto es 15% de 250\u00bb. El problema era que la herramienta usaba <code>eval()<\/code> para los c\u00e1lculos, y en producci\u00f3n recibimos peticiones como \u00abeval\u00faa 1\/0\u00bb o \u00abcalcula len(&#8216;hola&#8217;)\u00bb. No era malicia, era el modelo explorando los l\u00edmites de la herramienta. Lo que hicimos: restringir <code>eval()<\/code> a operaciones aritm\u00e9ticas b\u00e1sicas y a\u00f1adir una lista blanca de funciones permitidas. Funcion\u00f3, pero fue una correcci\u00f3n que deber\u00edamos haber hecho antes de deployar.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Reglas para descripciones efectivas<\/h3>\n\n\n\n<ul class=\"wp-block-list\" class=\"wp-block-list\">\n<li>El nombre de la herramienta debe ser descriptivo y \u00fanico. <code>buscar<\/code> es ambiguo. <code>buscar_productos_inventario<\/code> es claro.<\/li>\n\n\n\n<li>La descripci\u00f3n debe incluir el prop\u00f3sito, los casos de uso, y los par\u00e1metros.<\/li>\n\n\n\n<li>Especifica cu\u00e1ndo NO usar la herramienta. \u00abNo usar para consultas hist\u00f3ricas\u00bb evita llamadas innecesarias.<\/li>\n\n\n\n<li>Si una herramienta requiere permisos o tiene l\u00edmites, menci\u00f3nalo en la descripci\u00f3n.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">El agente en acci\u00f3n<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Con las herramientas definidas, el agente necesita un executor que maneje el ciclo completo: decisi\u00f3n del LLM, ejecuci\u00f3n de la herramienta, retorno del resultado, y procesamiento final.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Ejemplo: agente con Tool Use completo<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>from langchain_core.prompts import ChatPromptTemplate\nfrom langchain.agents import create_tool_calling_agent, AgentExecutor\nfrom langchain_openai import ChatOpenAI\n\nllm = ChatOpenAI(model=\"gpt-4o\", temperature=0)\n\n# Herramientas definidas previamente\ntools = &#91;buscar_clima, calcular_expresion]\n\n# Prompt con placeholder para el historial de tool calls\nprompt = ChatPromptTemplate.from_messages(&#91;\n    (\"system\", \"Eres un asistente t\u00e9cnico. Usa las herramientas disponibles cuando sea necesario.\"),\n    (\"human\", \"{input}\"),\n    (\"placeholder\", \"{agent_scratchpad}\"),\n])\n\n# Crear el agente\nagent = create_tool_calling_agent(llm, tools, prompt)\n\n# Executor con manejo de errores\nexecutor = AgentExecutor(\n    agent=agent,\n    tools=tools,\n    handle_parsing_errors=True,\n    max_iterations=10,\n    verbose=True,\n)\n\n# Ejecutar\nresultado = executor.invoke({\"input\": \"\u00bfCu\u00e1l es el clima en Madrid y cu\u00e1nto es 15% de 250?\"})<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">El <code>agent_scratchpad<\/code> es donde el agente registra cada paso: qu\u00e9 herramienta llam\u00f3, qu\u00e9 resultado obtuvo, y qu\u00e9 decisi\u00f3n tom\u00f3 a continuaci\u00f3n. Sin este historial, el modelo pierde el contexto de sus propias acciones y puede repetir llamadas o entrar en bucles.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El <code>max_iterations=10<\/code> es un l\u00edmite de seguridad. Sin \u00e9l, un agente que no converge puede seguir llamando herramientas indefinidamente hasta agotar el contexto o el rate limit.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Validaci\u00f3n de llamadas: la capa que todos olvidan<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">El LLM puede alucinar el nombre de una herramienta, inventar par\u00e1metros, o pasar tipos incorrectos. En el 5-10% de los casos con descripciones ambiguas, esto ocurre en producci\u00f3n.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La soluci\u00f3n es una capa de validaci\u00f3n entre la generaci\u00f3n de la llamada y su ejecuci\u00f3n:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import json\nimport inspect\nfrom pydantic import BaseModel, ValidationError\n\nclass ToolCall(BaseModel):\n    name: str\n    arguments: dict\n\n# Registry de herramientas v\u00e1lidas\nTOOL_REGISTRY = {t.name: t for t in tools}\n\ndef validate_tool_call(call_json: str) -&gt; ToolCall:\n    \"\"\"Valida que la llamada del LLM sea correcta antes de ejecutarla.\"\"\"\n    try:\n        data = json.loads(call_json)\n        call = ToolCall(**data)\n        \n        # Verificar que la herramienta existe\n        if call.name not in TOOL_REGISTRY:\n            raise ValueError(f\"Herramienta desconocida: {call.name}\")\n        \n        # Verificar schema de par\u00e1metros\n        tool_fn = TOOL_REGISTRY&#91;call.name].func\n        sig_params = list(inspect.signature(tool_fn).parameters.keys())\n        extra = set(call.arguments.keys()) - set(sig_params)\n        if extra:\n            raise ValueError(f\"Par\u00e1metros inv\u00e1lidos: {extra}\")\n        \n        return call\n    except (json.JSONDecodeError, ValidationError, ValueError) as e:\n        return None  # Llamar a fallback<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Sin validaci\u00f3n, una llamada alucinada se traduce en un error de runtime que el agente tiene que manejar. Con validaci\u00f3n, el error se detecta antes de ejecutar y puedes pedir al modelo que intente de nuevo con la informaci\u00f3n correcta.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Errores en herramientas: c\u00f3mo manejarlos<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Las herramientas fallan. Una API externa tiene timeout, una base de datos devuelve un error de conexi\u00f3n, un c\u00e1lculo lanza una excepci\u00f3n. La pregunta no es si fallan, es c\u00f3mo el agente reacciona.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lo que no funciona: devolver el stack trace al usuario. Lo que tampoco funciona: ignorar el error y continuar como si nada pasara.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lo que funciona es una estrategia de tres niveles:<\/p>\n\n\n\n<ul class=\"wp-block-list\" class=\"wp-block-list\">\n<li><strong>Reintento con backoff<\/strong>: para errores transitorios (timeout, rate limit), reintenta con delay exponencial. Un timeout de 3 segundos no es un fallo permanente.<\/li>\n\n\n\n<li><strong>Fallback a herramienta alternativa<\/strong>: si la herramienta principal falla, usa una alternativa. Si \u00abconsultar_base_datos\u00bb falla, \u00abbuscar_informaci\u00f3n_general\u00bb puede ser un fallback aceptable.<\/li>\n\n\n\n<li><strong>Comunicaci\u00f3n clara al usuario<\/strong>: si nada funciona, el agente debe comunicar el fallo de forma \u00fatil. \u00abNo pude consultar el clima actual. Intenta de nuevo en unos minutos\u00bb es mejor que \u00abError 500: Internal Server Error\u00bb.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">En un sistema real, vimos que el 80% de los fallos de herramientas eran transitorios. Un reintento simple resolv\u00eda la mayor\u00eda. El 20% restante eran errores de datos (registro no encontrado, par\u00e1metro inv\u00e1lido) que requer\u00edan que el agente pidiera aclaraci\u00f3n al usuario.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Cu\u00e1ndo Tool Use NO es la respuesta<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Tool Use a\u00f1ade latencia y complejidad. Cada llamada a herramienta es una llamada adicional al modelo m\u00e1s la ejecuci\u00f3n de la funci\u00f3n. No todo requiere una herramienta.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ejemplos donde Tool Use sobra:<\/p>\n\n\n\n<ul class=\"wp-block-list\" class=\"wp-block-list\">\n<li>Preguntas de conocimiento general que el modelo ya sabe responder.<\/li>\n\n\n\n<li>C\u00e1lculos simples que el modelo puede hacer directamente (2 + 2, conversiones b\u00e1sicas).<\/li>\n\n\n\n<li>Generaci\u00f3n de contenido creativo donde no se necesitan datos externos.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">La prueba es simple: ejecuta la petici\u00f3n sin herramientas y mide la tasa de errores. Si el modelo responde correctamente la mayor\u00eda de las veces, las herramientas son overhead innecesario.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Tool Use y los dem\u00e1s patrones<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Tool Use se combina con casi todos los dem\u00e1s patrones. La combinaci\u00f3n m\u00e1s com\u00fan es <strong>Planning \u2192 Tool Use<\/strong>: el agente genera un plan, y cada paso del plan puede invocar herramientas diferentes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Con <strong>Reflection<\/strong>, la combinaci\u00f3n es poderosa: el agente usa herramientas para recopilar datos, y un Critic revisa si los datos son suficientes y correctos antes de generar la respuesta final.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Con <strong>Routing<\/strong>, el router decide si una petici\u00f3n necesita herramientas o puede responderse directamente. Peticiones simples van al modelo directo. Peticiones complejas van al agente con herramientas.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Con <strong>Parallelization<\/strong>, m\u00faltiples herramientas pueden ejecutarse concurrentemente. Si un agente necesita consultar clima, tr\u00e1fico y eventos para responder una pregunta de viaje, las tres llamadas pueden correr en paralelo en lugar de secuencialmente.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Observabilidad<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Un agente con herramientas sin m\u00e9tricas es una caja negra. Estos son los indicadores m\u00ednimos:<\/p>\n\n\n\n<ul class=\"wp-block-list\" class=\"wp-block-list\">\n<li><strong>Tasa de tool calls por petici\u00f3n<\/strong>: cu\u00e1ntas herramientas se llaman en promedio. Si crece sin raz\u00f3n, el agente puede estar perdido.<\/li>\n\n\n\n<li><strong>Tiempo de ejecuci\u00f3n por herramienta<\/strong>: identifica cuellos de botella. Una herramienta que tarda 10 segundos domina la latencia total.<\/li>\n\n\n\n<li><strong>Tasa de error por herramienta<\/strong>: si una herramienta falla m\u00e1s del 5% de las veces, necesita revisi\u00f3n.<\/li>\n\n\n\n<li><strong>Validaciones rechazadas<\/strong>: cu\u00e1ntas llamadas del LLM fallan la validaci\u00f3n de schema. Si supera el 10%, las descripciones de herramientas necesitan mejora.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Un log estructurado con <code>{tool_name, arguments, result_type, duration_ms, error}<\/code> es suficiente para mantener el sistema bajo control.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Anti-patrones<\/h2>\n\n\n\n<ul class=\"wp-block-list\" class=\"wp-block-list\">\n<li><strong>Descripciones vagas<\/strong>: si el LLM no entiende qu\u00e9 hace una herramienta desde su docstring, la llamar\u00e1 incorrectamente. \u00abbuscar\u00bb es ambiguo. \u00abbuscar_productos_inventario\u00bb es claro.<\/li>\n\n\n\n<li><strong>Demasiadas herramientas simult\u00e1neas<\/strong>: presentar 50+ herramientas al LLM aumenta la probabilidad de selecciones incorrectas. Agrupa por dominio o usa routing para seleccionar el subconjunto relevante.<\/li>\n\n\n\n<li><strong>Sin manejo de errores<\/strong>: cuando una herramienta falla, el agente necesita se\u00f1ales claras para recuperarse. Excepciones sin contexto producen respuestas confusas.<\/li>\n\n\n\n<li><strong>Devolver errores crudos al usuario<\/strong>: los fallos de herramientas deben ser capturados y reformulados por el agente, no filtrados como stack traces.<\/li>\n\n\n\n<li><strong>Ignorar la validaci\u00f3n<\/strong>: el LLM puede alucinar nombres de herramientas o valores de par\u00e1metro. Validar antes de ejecutar evita errores de runtime.<\/li>\n\n\n\n<li><strong>Usar Tool Use para todo<\/strong>: si el modelo ya sabe la respuesta, a\u00f1adir una llamada a herramienta desperdicia tiempo y tokens.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfQu\u00e9 es Function Calling?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Es el mecanismo t\u00e9cnico donde el LLM genera una petici\u00f3n estructurada (JSON) para invocar una funci\u00f3n externa. El modelo decide si necesita usar una herramienta, qu\u00e9 herramienta usar, y con qu\u00e9 par\u00e1metros.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfCu\u00e1l es la diferencia entre Tool Use y Function Calling?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Function Calling es el mecanismo t\u00e9cnico (generaci\u00f3n de JSON estructurado). Tool Use es el concepto m\u00e1s amplio: incluye funciones, APIs, bases de datos, y hasta otros agentes como herramientas.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfCu\u00e1ntas herramientas puedo darle a un agente?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">La mayor\u00eda de modelos empiezan a confundirse con m\u00e1s de 10-15 herramientas simult\u00e1neas. Si necesitas m\u00e1s, agr\u00fapalas por dominio o usa un router que seleccione el subconjunto relevante antes de pasarlas al agente.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfQu\u00e9 pasa si el modelo alucina el nombre de una herramienta?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Ocurre en el 5-10% de los casos con descripciones vagas. La soluci\u00f3n es validar la llamada antes de ejecutarla: verificar que el nombre exista, que los par\u00e1metros cumplan el schema, y tener un fallback para llamadas inv\u00e1lidas.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfTool Use funciona con modelos locales?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">S\u00ed, pero depende del modelo. Los modelos de 7B suelen tener dificultades con schemas complejos. Los de 13B+ manejan bien herramientas simples. Los de 30B+ se acercan al rendimiento de modelos comerciales.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfC\u00f3mo evito que un agente entre en bucle llamando herramientas?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Limita el m\u00e1ximo de tool calls por petici\u00f3n (5-10 es razonable). Registra las herramientas ya llamadas para detectar repeticiones. Si el modelo llama a la misma herramienta con los mismos argumentos dos veces, corta el bucle.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Cierre<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Tool Use es lo que convierte a un LLM de un chatbot en un agente. Sin herramientas, el modelo est\u00e1 limitado a lo que sabe. Con herramientas, puede interactuar con el mundo real.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pero cada herramienta que a\u00f1ades es una decisi\u00f3n de dise\u00f1o con consecuencias. Las herramientas mal definidas producen llamadas incorrectas. Las llamadas incorrectas producen outputs err\u00f3neos. Los outputs err\u00f3neos erosionan la confianza del usuario, y recuperar esa confianza es m\u00e1s caro que escribir una buena descripci\u00f3n desde el principio.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El sistema que funciona no es el que tiene m\u00e1s herramientas. Es el que tiene las herramientas correctas, bien descritas, y con manejo de errores que no se rompa cuando algo falla. Todo lo dem\u00e1s es deuda t\u00e9cnica que el modelo pagar\u00e1 con intereses.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Patr\u00f3n Tool Use (Function Calling): definici\u00f3n de herramientas, ciclo de ejecuci\u00f3n, validaci\u00f3n, errores y decisiones de producci\u00f3n.<\/p>\n","protected":false},"author":1,"featured_media":697,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[135,6],"tags":[125,121,139,137,123,82,86,85,138,136],"class_list":["post-676","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-agentes","category-ia-automatizacion","tag-agentes-ia","tag-agentic-patterns","tag-apis","tag-function-calling","tag-google-adk","tag-langchain","tag-langgraph","tag-llm","tag-mcp","tag-tool-use"],"_links":{"self":[{"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/posts\/676","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/comments?post=676"}],"version-history":[{"count":4,"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/posts\/676\/revisions"}],"predecessor-version":[{"id":698,"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/posts\/676\/revisions\/698"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/media\/697"}],"wp:attachment":[{"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/media?parent=676"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/categories?post=676"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/atlaszn.com\/blog\/wp-json\/wp\/v2\/tags?post=676"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}