Los LLM no acceden a tu código: te entregan una solicitud y tú ejecutas la función. Ese simple hecho desmiente el mito de que "el modelo llama mágicamente a mi rutina de Python" y obliga a los desarrolladores a replantearse la depuración y la seguridad.
El bucle de despacho, paso a paso
Cuando un modelo de lenguaje (LLM) necesita una herramienta, sigue una secuencia determinista:
- Planificación – el modelo decide que se requiere una acción (p. ej., "reembolsar un pago").
- Generación de una solicitud – genera texto estructurado —normalmente JSON— que nombra la herramienta y proporciona los argumentos.
- Análisis (Parsing) – tu aplicación o un framework de soporte lee ese texto.
- Coincidencia (Matching) – el framework busca el nombre en el registro de las funciones reales que has expuesto.
- Validación – comprueba que los argumentos coincidan con el esquema de la función y que el emisor esté autorizado.
- Ejecución – la función correspondiente se ejecuta en tu entorno, realizando el trabajo.
- Retorno – el resultado se empaqueta y se envía de vuelta al modelo para un razonamiento posterior.
Piensa en el LLM como un planificador, en el framework como un despachador y en la función como el trabajador que realmente mueve datos o dinero.
Por qué persiste el mito de la "magia"
La mayoría de los desarrolladores ven una sola línea de salida del modelo que parece una llamada a una función y asumen que el modelo realizó la operación por sí mismo. El término "tool calling" en la documentación de los proveedores suena como si el modelo estuviera invocando código directamente.
En realidad, el modelo solo produce texto que describe una llamada. Tu proceso realiza el trabajo pesado: la búsqueda, la comprobación de tipos, la aplicación de permisos y el manejo de errores.
Frameworks que ocultan los mecanismos internos
Librerías como PydanticAI y LangChain abstraen el bucle para que puedas centrarte en la lógica de negocio. Ellas automáticamente:
- Validan los argumentos contra un esquema (p. ej., un modelo de Pydantic).
- Aplican permisos, asegurando que el usuario pueda activar la herramienta.
- Reintentan en caso de fallo, volviendo al modelo cuando una herramienta devuelve un error.
- Protegen contra bucles descontrolados, limitando las llamadas consecutivas a herramientas.
- Mantienen el estado de la conversación, integrando los resultados de las herramientas en el diálogo.
Incluso con estos ayudantes, el patrón sigue siendo el mismo: el modelo nunca ejecuta código.
Soporte nativo de tool-calling de los proveedores
Algunos proveedores ofrecen una interfaz de "tool-calling" nativa que estandariza las definiciones de las herramientas y los formatos de solicitud. Esto facilita la integración, pero no elimina el paso de despacho. Tú sigues escribiendo (o importando) el código que realmente ejecuta la operación solicitada.
La depuración es más fácil cuando renombras el problema
En lugar de culpar a un "agente confundido", di que el problema es que "la respuesta del modelo no contenía llamadas a herramientas". La distinción es importante:
- Sin llamada a herramienta (No tool call) – el modelo respondió directamente o no pudo generar una solicitud con el formato correcto.
- Solicitud malformada – el JSON es sintácticamente incorrecto o le faltan campos obligatorios, por lo que el despachador la rechaza.
- Fallo de validación – los argumentos no coinciden con el esquema, lo que provoca un error antes de la ejecución.
Categorizar los fallos te permite registrar cada etapa del bucle y localizar exactamente dónde se desvió el proceso.
Consejos prácticos para un pipeline fiable
- Trata la salida del modelo como una entrada no confiable. Pasa cada solicitud por una validación determinista antes de invocar cualquier código con efectos secundarios.
- Registra la solicitud original (raw request) y el resultado de cada paso de validación. Esto crea un rastro reproducible cuando algo sale mal.
- Establece límites explícitos en las llamadas consecutivas a herramientas; un bucle descontrolado puede agotar los recursos o alcanzar los límites de tasa (rate limits).
- Envuelve cada función en un bloque try/except que devuelva un objeto de error estructurado que el modelo pueda entender, lo que permitirá un reintento o una alternativa controlada (fallback).
- Separa las comprobaciones de permisos de la lógica de negocio. Verifica los derechos del emisor antes de que se ejecute la función, especialmente para acciones privilegiadas como "eliminar usuario".
- Utiliza definiciones basadas en esquemas (p. ej., modelos de Pydantic) para que el framework pueda autogenerar el esquema JSON que el modelo debe seguir.
Qué esperar a continuación
A medida que los proveedores perfeccionen las APIs de tool-calling nativas, se esperan contratos más estrictos en torno a los formatos de solicitud y códigos de error más detallados. Estos cambios facilitarán la validación y permitirán a los desarrolladores construir perímetros de seguridad más estrictos. Mantente atento a las actualizaciones de las librerías; muchas están añadiendo soporte integrado para las funciones más recientes de los proveedores.
Conclusión
El LLM es un generador de texto sofisticado, no un ejecutor. Tu código sigue siendo la única autoridad que realiza acciones, y el despachador que construyas (o importes) es el guardián que valida, autoriza y ejecuta dichas acciones. Replantear el flujo de trabajo elimina el mito de la «magia», facilita la depuración y refuerza la disciplina de seguridad que todo sistema de producción necesita.
