Intro

La parte más peligrosa del entusiasmo con agentes no siempre está en el modelo. Muchas veces está en la capa de ejecución.

Mientras un agente llama una sola tool, con un input limpio y una salida fácil de interpretar, el sistema parece mucho más sólido de lo que realmente es. La demo sale bien, el flujo luce prolijo y la sensación de confiabilidad aparece demasiado pronto.

El problema empieza cuando ese mismo agente entra en producción y deja de vivir en un ejemplo controlado.

Ahí ya no hay una tool aislada. Hay varias herramientas, contratos desparejos, permisos distintos, estados intermedios, errores parciales, respuestas ambiguas y decisiones encadenadas. En ese escenario, el fallo rara vez se explica solo por “el modelo se equivocó”. Casi siempre se rompe algo en la interfaz entre el modelo y la acción.

Eso es lo que conviene entender mejor cuando se habla de tool calling.

El problema no es invocar una tool, sino operar con ella

En una demo, llamar una herramienta puede parecer trivial. El agente detecta intención, arma parámetros y la tool responde algo razonable. Pero en un entorno real hay varias preguntas más importantes:

  • qué acepta exactamente esa tool;
  • qué pasa si faltan datos;
  • cómo devuelve errores;
  • qué permisos tiene;
  • qué tan verificable es su salida;
  • qué ocurre si una decisión intermedia fue incorrecta;
  • y qué daño puede causar una llamada válida pero mal contextualizada.

El tool calling deja de ser una feature simpática cuando toca sistemas reales. En ese punto se vuelve una interfaz operativa.

Y como cualquier interfaz operativa, importa menos por la elegancia del caso feliz que por la forma en que falla.

Dónde se rompe de verdad

Hay varios patrones que se repiten bastante cuando un agente con tools pasa de laboratorio a workflows reales.

1. Contratos demasiado blandos

Una herramienta que “acepta un JSON” no necesariamente tiene un contrato sano.

Si los campos obligatorios no están claros, si los tipos son laxos, si las enumeraciones quedan abiertas o si la descripción de los parámetros admite demasiada interpretación, el agente tiene más espacio para adivinar de la cuenta.

Eso no siempre termina en un error espectacular. A veces el daño es más sutil:

  • una ruta equivocada pero válida;
  • un identificador incompleto;
  • un flag omitido;
  • una operación ejecutada sobre el recurso correcto pero con el alcance incorrecto.

Ese tipo de falla es incómodo porque parece razonable a primera vista. No es un crash obvio; es una acción equivocada que todavía respeta la sintaxis.

2. Validación insuficiente

Declarar un esquema ayuda, pero no alcanza.

Si el backend de la tool no valida fuerte, el agente puede entregar parámetros ambiguos o inconsistentes y aun así lograr que algo avance. En algunos casos la tool intenta “ser amable”, completa valores por defecto, tolera campos inesperados o interpreta entradas parciales. Eso hace que el sistema parezca más flexible, pero en realidad lo vuelve más opaco.

La tolerancia excesiva es tentadora en demos y peligrosa en producción.

Una validación robusta debería:

  • rechazar tipos inválidos;
  • bloquear campos fuera de contrato;
  • normalizar solo cuando la regla es explícita;
  • y devolver errores claros cuando la entrada no sirve.

Si la tool acepta casi cualquier cosa, el agente aprende que puede improvisar. Y ese es un mal incentivo.

3. Errores difíciles de interpretar

Muchas implementaciones tratan el manejo de errores como un detalle de integración. No lo es.

Si la tool responde con mensajes vagos, estados parciales mal señalados o blobs de texto difíciles de parsear, el agente tiene que inferir qué pasó. Y cuando un sistema obliga al modelo a inferir demasiado sobre la propia ejecución, la confiabilidad baja aunque el modelo sea bueno.

Un error útil para un agente no debería ser solo humano-legible. También debería ser estructurable.

Por ejemplo, no es lo mismo devolver:

  • falló algo;
  • que missing_required_field: targetPath;
  • o permission_denied: publish_external_message.

Cuanto más precisa es la semántica del error, menos espacio queda para una recuperación improvisada.

4. Herramientas con demasiado alcance

Este es uno de los problemas más serios.

Una tool que puede leer, escribir, borrar, publicar y ejecutar con el mismo permiso convierte cualquier error pequeño en un incidente más caro. Incluso si el agente suele comportarse bien, el blast radius del fallo queda mal contenido.

Por eso el punto no es solo si el agente puede equivocarse. El punto es qué tan caro sale cuando se equivoca.

Separar capacidades importa mucho más que tener una sola tool “poderosa” y bien documentada.

En general conviene distinguir, como mínimo:

  • lectura vs escritura;
  • escritura reversible vs irreversible;
  • acción local vs acción externa;
  • operación en staging vs producción;
  • y consulta de estado vs ejecución con efectos.

Ese recorte mejora seguridad, debugging y gobernanza a la vez.

5. Encadenamiento frágil de pasos

En un workflow largo, el error rara vez vive en un único punto.

Un primer paso puede traer datos parciales. El agente resume ese resultado como si fuera suficiente. Después usa ese resumen para decidir qué tool llamar. La siguiente tool ejecuta algo coherente respecto de esa interpretación, pero la premisa inicial ya estaba débil.

Cuando eso pasa, el incidente no siempre se ve como “una tool falló”. Se ve como una secuencia donde todo parecía razonable y, sin embargo, el resultado final fue incorrecto.

Ese patrón importa porque vuelve más difícil auditar el origen real del problema.

Señales de que el sistema está operando con más fe que evidencia

Hay varios síntomas que suelen anticipar problemas más serios.

Variabilidad rara entre corridas

Si un mismo caso usa tools distintas según la corrida, o cambia mucho la secuencia de llamadas sin que el contexto haya cambiado, la ejecución probablemente es más frágil de lo que parece.

Fallos intermitentes difíciles de reproducir

Cuando el sistema “a veces anda” pero cuesta explicar exactamente por qué, suele haber mezcla de contratos ambiguos, validaciones pobres y respuestas poco deterministas.

Éxitos imposibles de verificar

Este punto es peligrosísimo. El agente devuelve algo plausible, todos siguen avanzando y nadie puede demostrar fácilmente si el paso intermedio fue correcto.

Una respuesta convincente no es evidencia.

Calls fuera de contexto

Si el agente intenta herramientas que no encajan con la tarea o propone acciones con más alcance del necesario, hay un problema de permisos, de routing o de diseño del set de tools.

Recuperaciones improvisadas

Cuando una tool falla y el agente “adapta” demasiado sin una política clara, muchas veces lo que se ve como resiliencia es en realidad acumulación silenciosa de riesgo.

Qué controles ayudan de verdad

No hay una librería mágica que elimine este problema, pero sí hay controles bastante concretos que mejoran mucho la situación.

1. Esquemas estrictos de entrada y salida

El modelo necesita menos libertad de interpretación en la capa de ejecución que en la capa de redacción.

Cada tool debería tener:

  • tipos claros;
  • campos obligatorios bien definidos;
  • enums cerrados cuando corresponda;
  • descripciones concretas;
  • y salidas lo bastante estructuradas como para evitar inferencias frágiles.

El objetivo no es volver rígido todo el sistema. Es sacar ambigüedad justo donde más cara sale.

2. Validación dura antes de ejecutar

La tool no debería confiar en que el agente “más o menos entendió”. Debería verificar.

Eso incluye:

  • schema validation real;
  • coerción mínima y explícita;
  • mensajes de error útiles;
  • y rechazo temprano cuando una acción no está bien formada.

Validar bien hace algo importante: evita que el agente convierta una mala interpretación en un efecto real.

3. Permisos finos por tool y por contexto

No todas las tools deberían estar disponibles siempre, ni con el mismo alcance.

El set de capacidades debería depender del contexto operativo:

  • usuario;
  • entorno;
  • tipo de tarea;
  • recurso objetivo;
  • y nivel de sensibilidad.

Ese recorte no solo mejora seguridad. También reduce el espacio de decisión del agente y, por lo tanto, baja la probabilidad de llamadas innecesarias o peligrosas.

4. Sandboxing donde el impacto lo exige

Cuando una tool puede ejecutar comandos, tocar archivos sensibles, navegar sistemas externos o modificar recursos críticos, el aislamiento deja de ser opcional.

El sandboxing no resuelve todos los errores, pero limita cuánto daño puede producir una acción equivocada. Y eso cambia muchísimo el perfil de riesgo.

Este punto conversa bastante con Por qué el sandboxing importa en agentes con acceso a shell, browser y código y con Cómo diseñar un sandbox eficiente y seguro para agentes de IA y MCPs.

5. Approvals para bordes sensibles

No hace falta frenar cada paso para estar en control. Pero sí conviene detener al agente cuando está por cruzar un borde relevante:

  • publicación externa;
  • escritura irreversible;
  • acceso a datos sensibles;
  • cambios en producción;
  • gasto económico;
  • o acciones con alto impacto reputacional.

La clave es que el approval aparezca donde agrega control real, no como peaje universal. Ese equilibrio lo desarrollamos mejor en Cómo diseñar approvals en agentes sin frenar la operación ni abrir riesgos.

6. Logs y trazabilidad por paso

Si después de una corrida no podés responder con precisión:

  • qué tool eligió el agente;
  • con qué parámetros;
  • qué devolvió;
  • qué validaciones se aplicaron;
  • y por qué se tomó el siguiente paso,

entonces no tenés suficiente evidencia para confiar ni suficiente material para depurar.

La observabilidad no debería arrancar recién cuando hay un incidente.

Qué no conviene prometer

Hay varias promesas flojas que conviene pinchar rápido.

“Con un framework bueno, esto ya viene resuelto”

No. Un framework puede ayudar con abstractions, tracing o adapters, pero no reemplaza decisiones de contrato, permisos y validación.

“Si mejoramos el prompt, el problema baja mucho”

A veces mejora algo. Pero si la tool acepta demasiado, devuelve mal o tiene demasiado alcance, el prompt no arregla la arquitectura.

“La demo funciona, así que estamos cerca”

La demo puede demostrar capacidad. No demuestra estabilidad, ni seguridad, ni gobernanza, ni recuperabilidad.

La idea importante

El tool calling no se vuelve confiable porque el agente haya invocado una tool correctamente tres veces seguidas. Se vuelve más confiable cuando la capa de ejecución está diseñada para tolerar ambigüedad limitada, rechazar entradas malas, contener el blast radius y dejar evidencia útil.

Dicho más directo: en agentes, la discusión no termina en “qué tan bien razona el modelo”. También importa qué tan bien está cercada la acción.

Esa diferencia separa una demo linda de un sistema operable.

Y cuando un agente toca herramientas de verdad, esa separación importa muchísimo más de lo que suele admitirse al principio.