El problema
Un desarrollador implementa un bucle de llamadas para la Messages API inspeccionando el campo content de la respuesta con una expresión regular, buscando patrones que parezcan una solicitud de herramienta en texto libre. Funciona en las pruebas manuales. En producción, el comportamiento se vuelve errático: a veces el bucle continúa cuando debería detenerse y a veces se interrumpe antes de concluir la tarea. El fallo no está en la expresión regular — está en tratar a la API como un generador de texto libre cuando en realidad es una máquina de estados con señales explícitas que estaban siendo ignoradas.
stop_reason es una señal de control, no texto para interpretar
Toda respuesta de la Messages API incluye un campo stop_reason que especifica exactamente por qué el modelo detuvo la generación. Este campo no es un detalle secundario — es la instrucción de control que determina la siguiente transición de estado en la aplicación:
tool_use: el modelo solicita ejecutar una o más herramientas. La aplicación debe ejecutarlas y devolver los resultados en bloques estructurados de tipotool_resultantes de continuar el turno. Esto jamás debe inferirse buscando texto en la respuesta — el SDK entrega bloques de contenido tipados de tipotool_use, con el nombre de la herramienta, su identificador único y los argumentos ya procesados.end_turn: el modelo finalizó su turno normalmente. Es el camino feliz principal, pero no el único estado final válido.max_tokens: la respuesta se truncó al alcanzar el límite de tokens de salida antes de completar el razonamiento. Tratar esto como unend_turnnormal entrega silenciosamente respuestas incompletas o corruptas.- Existen otros estados para secuencias de parada personalizadas o filtros de seguridad. Una implementación de producción debe manejar todos estos estados de forma diferenciada — no solo los dos más comunes.
Tratar stop_reason como una señal de control estructurada en lugar de intentar adivinar la intención del modelo mediante texto libre es la diferencia entre un bucle de agentes confiable y un script inestable.
Preservar el estado de la conversación entre solicitudes
La Messages API no almacena estado entre llamadas HTTP — cada solicitud debe incluir el historial completo acumulado hasta ese punto. La aplicación anfitriona es responsable de preservar la estructura exacta de los bloques de contenido: el mensaje del asistente que solicitó la herramienta (tool_use), seguido inmediatamente por el turno del usuario con los bloques tool_result asociados al tool_use_id correspondiente.
Un antipatrón perjudicial consiste en "resumir" la respuesta previa del asistente en texto libre antes de reenviarla con la intención de ahorrar tokens. Esto destruye la estructura de bloques que la API exige, eliminando metadatos y degradando la coherencia conversacional. Si se requiere reducir tokens, la técnica adecuada es extraer hechos duraderos hacia un almacenamiento externo (como se vio en la lección de contexto y memoria), nunca alterar el protocolo estructural que exige la API.
Errores, límites y cancelación como estados de primera clase
Una arquitectura que únicamente gestiona el flujo ideal — donde stop_reason siempre es end_turn o tool_use — no está lista para producción. Al menos tres categorías de estados operativos requieren manejo explícito:
- Errores de red o de la API: tiempos de espera agotados (timeouts), errores 5xx del servidor y límites de tasa 429 (rate limits). Cada uno exige una estrategia distinta — un error 429 requiere reintentos con retroceso exponencial (backoff) y variación aleatoria (jitter), mientras que un error 400 de validación no debe reintentarse a ciegas sin corregir el contenido.
- Límites alcanzados (
max_tokens): cuando la respuesta se corta antes de terminar, el sistema debe activar mecanismos de continuación o registrar la anomalía, nunca asumir que el resultado está completo. - Cancelación: los sistemas reales en producción necesitan mecanismos para abortar solicitudes o bucles de agentes en curso si el usuario cierra la interfaz o se superan los tiempos límite del cliente.
Dónde falla la intuición
- "Puedo detectar llamadas a herramientas analizando el texto de la respuesta con expresiones regulares." La API entrega bloques tipados
tool_useacompañados destop_reason: tool_use— procesar texto libre es una reinvención propensa a fallos de una funcionalidad nativa. - "Resumir el historial en texto libre ahorra tokens sin consecuencias." Rompe el esquema de bloques de contenido y destruye la trazabilidad de las herramientas, degradando la capacidad de razonamiento del modelo.
- "Solo necesito manejar
end_turnytool_use; el resto son casos raros." Caídas de red, límites de tokens y cancelaciones ocurren constantemente en producción a escala — ignorar estos estados posterga fallos inevitables.
Ponlo en práctica
En el laboratorio de esta lección implementarás una máquina de estados para la Messages API: a partir de respuestas simuladas (incluyendo tool_use, end_turn, truncamiento por límite de tokens y errores de red), gestionará las transiciones de forma determinista, respaldada por pruebas automatizadas que verifican la cobertura integral de todos los estados.