El problema
Un asistente de soporte recibe una consulta que requiere dos datos: el estado del pedido y el historial de pagos del cliente. El modelo responde con stop_reason: "tool_use" solicitando dos herramientas en el mismo turno: get_order_status y get_payment_history. El equipo que construye el arnés de ejecución se enfrenta a una decisión de diseño: ejecutar ambas llamadas y devolver los resultados agrupados en un solo párrafo explicativo, o ejecutar cada una por separado y devolver cada resultado vinculado al tool_use_id que lo originó.
La primera opción parece más limpia a simple vista — es solo un texto que sintetiza lo encontrado. Sin embargo, rompe el contrato del protocolo: si una de las llamadas falla, el modelo no tiene forma de saber cuál falló porque la identidad de cada invocación se perdió en el resumen. La segunda opción es ligeramente más detallada, pero es el único patrón arquitectónico que preserva la información necesaria para que el bucle continúe de forma determinista y confiable.
Un bucle de herramientas no es "dejar que el modelo trabaje solo". Es delegación controlada, donde el arnés que desarrollas tiene la responsabilidad de mantener la integridad del protocolo en cada ciclo.
El ciclo de vida sin atajos
El ciclo de una llamada a herramientas sigue una secuencia fija:
- El modelo responde con
stop_reason: "tool_use"y uno o más bloquestool_use, cada uno con unidúnico. - El arnés ejecuta la herramienta correspondiente a cada bloque.
- El arnés devuelve un bloque
tool_resultpor cadatool_use_id, en el mismo turno, como parte del siguiente mensaje del usuario. - El modelo continúa la conversación con estos resultados disponibles en su contexto — pudiendo solicitar nuevas herramientas o concluir con
stop_reason: "end_turn".
El punto que más fallos genera en producción: cuando el modelo solicita múltiples herramientas independientes en el mismo turno, pueden ejecutarse en paralelo (si no hay dependencias entre ellas), pero los resultados deben preservar estrictamente la asociación con el id original. Combinar los resultados en texto libre o entregarlos desordenados sin referencia al identificador es la causa principal de bucles que "olvidan" lo que ya fue consultado.
Dónde puede fallar la decisión de diseño
Un patrón recurrente en los escenarios de examen: cuando una operación es puramente determinista (como calcular un hash o formatear una fecha), la respuesta instintiva suele ser delegarla a otra herramienta o, peor aún, a un subagente completo. Si una operación tiene una implementación algorítmica exacta y sin ambigüedad, debe resolverse en código convencional dentro del propio arnés — no tiene sentido pagar el costo y la latencia de una llamada al modelo, y mucho menos de un subagente, para algo que una función pura resuelve al instante.
Regla práctica: reserva el bucle de herramientas (y con mayor razón los subagentes) para pasos que requieren juicio, resolución de ambigüedad o acceso a sistemas externos. Todo lo demás es código convencional.
Otro fallo crítico es carecer de una condición de parada explícita. Un bucle que continúa invocando herramientas indefinidamente porque cada respuesta intermedia le parece "incompleta" al modelo consume presupuesto y tiempo sin control. El arnés debe imponer un límite estricto de iteraciones y, al alcanzarlo, emitir un estado explícito de "no completado" en lugar de dejar que el bucle se ejecute hasta que expire el tiempo límite de la solicitud.
Errores, límites y cancelación como parte del bucle
En entornos de producción, un arnés robusto de tool use gestiona las anomalías operativas como estados de primera clase:
- Error en la ejecución de la herramienta: el
tool_resultdebe indicar la falla explícitamente (por ejemplo, con un campo de error estructurado), en lugar de silenciar el problema devolviendo una cadena vacía. - Cancelación por el usuario: la solicitud en curso debe abortarse de manera limpia, sin dejar bloques
tool_usependientes sin su respectivotool_result, lo que rompería las llamadas posteriores. - Límites de tiempo o de iteraciones: deben contar con un tope explícito y controlado.
Ponlo en práctica
El laboratorio de esta lección te pide implementar un arnés mínimo de bucle de herramientas en Python: recibe llamadas simuladas (algunas independientes y otras dependientes), ejecuta las independientes preservando la correlación por id, detecta cuándo una operación determinista debió resolverse en código puro e impone un límite de iteraciones. Las pruebas automatizadas verifican que la asociación entre llamada y resultado nunca se pierda, aun cuando el orden de finalización no coincida con el orden de solicitud.