Claude Fable 5 para agentes: rechazos de tool calls, coste vs GLM 5.2
Contenido
Claude Fable 5 rechazó la petición durante una tool call en 11 de los 44 turnos de agentes de código de nuestra evaluación, incluso en tareas tan simples como corregir el valor predeterminado de una configuración. El rechazo llega como stop_reason: "refusal" mientras aún se están generando los argumentos de la herramienta. Los argumentos truncados siguen siendo JSON válido, por lo que un bucle de agente que ejecute tool calls sin comprobar el motivo de parada escribirá tranquilamente un archivo incompleto en disco. Al integrar Fable 5 en un agente, este comportamiento es lo primero que hay que resolver, antes incluso que el precio.
TL;DR
- Claude Fable 5 devolvió
stop_reason: "refusal"en mitad de una tool call durante tareas rutinarias de agentes, como corregir un valor predeterminado de configuración o reservar una sala de reuniones. Los argumentos truncados dewrite_fileseguían siendo válidos, así que un bucle que no compruebe el motivo de parada ejecutará la escritura de archivos incompletos. - El razonamiento de Fable 5 es adaptativo y no se puede desactivar: tanto
enabledcomodisabledse rechazan. Se controla medianteoutput_config.effort. - El sobrecoste de Fable 5 depende del tipo de carga: una tarea de programación de cuatro turnos costó $0.045, frente a $0.003 con glm-5.2, una diferencia de 15x; en procesamiento batch con caché caliente, solo costó 5x más que sonnet-5.
- Fable 5 exige conservar los datos durante 30 días.
Todas las mediciones siguientes se realizaron el 2026-07-05 a través del gateway de Synthorai con un pequeño banco de escenarios: cinco tipos de carga para agentes, un bucle de programación con herramientas, respuestas RAG, orquestación intensiva de herramientas, clasificación batch y una conversación de 15 turnos, ejecutados con claude-fable-5, claude-opus-4-8, claude-sonnet-5 y glm-5.2. Cuando la variabilidad era relevante, repetimos cada tarea tres veces. Las tareas son deliberadamente sencillas; la tasa de aciertos sirve como control básico, no como benchmark de capacidad. Los costes corresponden al usage.cost facturado por el gateway.
Comprueba stop_reason antes de ejecutar tool calls
Este fallo no aparece advertido en la documentación y puede corromper el estado. El agente lee app.py, decide escribir la corrección y empieza a generar una llamada a write_file. A mitad del contenido del archivo, el stream se detiene:
{
"stop_reason": "refusal",
"content": [{
"type": "tool_use",
"name": "write_file",
"input": {
"path": "app.py",
"content": "DEFAULTS = {\n \"timeout_s\": 30,\n "
}
}]
}
El objeto input es JSON completo y válido. Nada indica que la generación se haya interrumpido. Si el contrato del bucle es «si hay tool calls, ejecútalas», acabas de sobrescribir app.py con un fragmento de 38 caracteres que termina a mitad del diccionario y ya no es Python válido. Además, el siguiente turno también se rechaza, por lo que el bucle termina con el workspace corrupto.
Los datos permiten extraer tres conclusiones:
- Ocurre en tareas rutinarias. Los rechazos aparecieron al corregir un
KeyErroren una consulta de configuración, implementar una función de slugify, reservar una sala de reuniones y crear un borrador de factura. Ninguna era una tarea de doble uso ni trataba contenido sensible. - Es reproducible, no aleatorio. Una tarea de programación fue rechazada en las tres ejecuciones, tanto con streaming como sin él. Otras tareas nunca se rechazaron. Según la configuración, Fable 5 completó correctamente entre el 58% y el 75% de nuestros episodios sencillos de programación, frente al 100% de claude-opus-4-8, claude-sonnet-5 y glm-5.2. Todos los fallos se debieron a rechazos, no a código incorrecto.
- Una vez que aparece un rechazo en la conversación, el episodio está acabado. Los turnos siguientes devolvieron
stop_reason: "refusal"sin contenido. Reintentar dentro del mismo contexto no permitió recuperarlo.
El contenido de la tarea no es el desencadenante, y los datos no dejan mucho margen de duda. La tarea rechazada en todas las ejecuciones consistía en corregir un KeyError en un diccionario de configuración de nueve líneas, sin credenciales ni exploits. En cambio, el escenario batch clasificó tickets de soporte sobre criptominería, claves de Stripe filtradas y páginas de phishing sin un solo rechazo. El escenario RAG también respondió sin problemas a partir de documentación llena de secretos AES-256-GCM y procedimientos de respuesta a brechas. Todos los rechazos ocurrieron en los dos escenarios multiturno que ejecutaban herramientas. Los tres escenarios de una sola petición no sufrieron ninguno, aunque manejaban contenido más delicado. El patrón depende de la forma del bucle del agente, no de las palabras, así que sanear los inputs no lo evitará.
La solución es añadir una línea antes de ejecutar las herramientas:
if response.stop_reason == "refusal":
# do NOT execute tool calls from this turn: arguments may be truncated
raise AgentInterrupted("model refused; restart episode or escalate")
Anthropic documenta el funcionamiento: si el rechazo se produce antes de generar contenido, la respuesta contiene un array content vacío y no se factura; si ocurre durante el stream, se factura el contenido ya generado y se recomienda descartar el fragmento. La respuesta también incluye un objeto stop_details con una categoría, como cyber, bio o null, que permite distinguir los bloqueos del clasificador de los rechazos normales. La documentación no explica el caso que encontramos con el uso de herramientas: el rechazo puede producirse mientras se generan los argumentos, y los argumentos parciales no se distinguen de unos completos.
También existe una vía oficial de recuperación. En la API de Claude, el parámetro beta fallbacks (betas: ["server-side-fallback-2026-06-01"], fallbacks: [{"model": "claude-opus-4-8"}]) vuelve a ejecutar una petición rechazada con un modelo alternativo dentro de la misma llamada. Si el rechazo ocurrió antes de generar contenido, no se factura. Esta opción no está disponible en Amazon Bedrock, Vertex AI ni Microsoft Foundry, cuyos SDK incluyen en su lugar middleware de fallback del lado del cliente. En cualquier caso, primero debe aplicarse la comprobación anterior: nunca ejecutes tool calls de un turno cuyo motivo de parada sea un rechazo.
Cuánto cuestan cinco tipos de agentes
Coste mediano por unidad completada, tarea, consulta, elemento o conversación, con los mismos prompts y el mismo día:
| Escenario | fable-5 | opus-4-8 | sonnet-5 | glm-5.2 |
|---|---|---|---|---|
| Bucle de programación (por tarea, mediana de 4 turnos) | $0.045 | $0.012 | $0.0059 | $0.0031 |
| Respuesta RAG (por consulta) | $0.024 | $0.0075 | $0.0036 | $0.0031 |
| Orquestación de herramientas (por tarea) | $0.048 | $0.011 | $0.0045 | $0.0027 |
| Clasificación batch (por elemento, caché caliente) | $0.0024 | $0.0012 | $0.00046 | $0.00057 |
| Conversación de 15 turnos (completa) | $0.94 | $0.34 | $0.26 | $0.083 |
Hay dos conclusiones más importantes que cualquier cifra aislada de la tabla:
- El modelo más barato cambia según el tipo de carga. glm-5.2 gana en los bucles y en la conversación larga, pero claude-sonnet-5 es el clasificador batch más barato del grupo, por debajo de glm-5.2. Su precio de lanzamiento se combina con un 97% de lecturas desde caché cuando el prompt base ya está caliente.
- El sobrecoste de Fable 5 también depende del tipo de carga: 15x frente a glm-5.2 en el bucle de programación y 11x en conversación, pero solo 5x frente a sonnet-5 en elementos batch con caché caliente, donde la caché absorbe casi todo el prompt.
Para completar el análisis de costes, primero hay que ver cómo controlar estas cifras y después revisar dos factores que vuelven a incrementarlas sin hacer mucho ruido.
Cómo reducir la factura de un agente
La caché es el factor con mayor impacto, y en Fable 5 su contrato no ha cambiado. Los datos de agentes muestran cuánto aporta: al eliminar los marcadores cache_control, la misma tarea de programación costó 2.0x más y los elementos batch con caché caliente, 6.8x más. En opus-4-8, la misma eliminación produjo aumentos de 3.8x y 6.9x. En un bucle, el patrón de marcadores deslizantes no es una simple optimización: determina si el coste es viable.
El segundo factor es el orden del prompt, y el resultado se mantuvo en todos los modelos probados. Colocar las reglas estables antes del contexto específico de cada consulta, en vez de después, redujo el coste de las consultas RAG entre un 26% y un 37% en los cuatro modelos. En los modelos Claude, el orden incorrecto añade además el recargo de 1.25x por escritura en caché en cada llamada. El funcionamiento se explica en el artículo sobre caché con LangChain; estas cifras confirman que también se aplica a Fable 5 sin cambios.
Fable 5 añade dos controles propios. El primero es que el mínimo necesario para usar la caché bajó a 2,048 tokens, la mitad de los 4,096 de Opus 4.8. Parece un dato menor, pero el ahorro de un agente procede precisamente de lo que se repite: el prompt del sistema, las definiciones de herramientas y el prefijo deslizante de la conversación. Ese contenido solo se almacena si supera el mínimo. Un agente con muchas herramientas cuyo prefijo por turno estuviera entre 2,048 y 4,096 tokens no obtenía ninguna ventaja de caché en Opus 4.8. Con Fable 5 empieza a usarla y sustituye un prefijo a precio completo por una lectura de caché que cuesta aproximadamente el 10% en cada turno posterior. También puede ocurrir lo contrario: un prefijo rellenado para superar el antiguo mínimo de 4,096 quizá siga arrastrando contenido innecesario. Consulta cache_read_input_tokens en una respuesta real en lugar de darlo por hecho, porque con Fable 5 el descuento empieza antes.
El segundo control son los presupuestos de tarea (beta, header task-budgets-2026-03-13), que resuelven exactamente el problema que aparece una y otra vez en esta comparación: un bucle con Fable 5 acumula costes rápidamente y max_tokens no ayuda. max_tokens impone un límite estricto por respuesta que el modelo desconoce. El modelo planifica como si dispusiera de espacio ilimitado y después se corta a mitad del razonamiento. Un presupuesto de tarea funciona de otra forma. Se asigna al bucle un límite de tokens, como mínimo, 20,000, que el modelo ve como una cuenta atrás y administra durante la ejecución, de modo que puede terminar correctamente en lugar de quedar truncado. Cuenta lo que genera el modelo más los resultados de herramientas que lee durante el turno, no todo el historial que vuelves a enviar en cada petición. En un modelo cuyo turno de programación cuesta 15x más que glm-5.2, un presupuesto que el propio modelo intenta respetar es la protección de costes más barata que puedes añadir.
Dos costes inesperados que la documentación no advierte
Incluso con esos controles bien configurados, dos detalles menores movieron la factura en direcciones que la documentación no anticipa.
El esfuerzo “Low” no resultó más barato. La profundidad de razonamiento de Fable 5 se controla mediante output_config.effort, y cabría esperar que low costara menos. No fue así. Con effort: "low", nuestro bucle de programación costó $0.0478 por tarea, frente a $0.0451 con el valor predeterminado, y generó más tokens de salida, no menos. Vimos el mismo patrón en GLM 5.2, donde los nombres de los niveles de esfuerzo tampoco se corresponden con el número de tokens. En ambas familias de modelos, mide este parámetro con tu propia carga antes de asumir que “low” significa “menos”. Una de las razones por las que resulta difícil predecir el coste es que la proporción de tokens de salida dedicada al razonamiento adaptativo varió del 2% en el bucle de programación al 30% en las respuestas RAG y al 52% en la clasificación batch, con el mismo modelo y el mismo día. Presupuesta los tokens de salida por tipo de carga, no por modelo.
Nunca reenvíes reasoning_content. En modelos compatibles con OpenAI, el campo de razonamiento no forma parte del historial de la conversación. La API de DeepSeek exige eliminarlo; en GLM 5.2 se puede reenviar, pero se factura. Incluirlo de nuevo en el historial aumentó aproximadamente un 28% el coste de nuestro bucle con GLM hasta que lo eliminamos. Los bloques de razonamiento de Anthropic funcionan de otra manera: al seguir usando el mismo modelo, debes reenviarlos sin cambios. Si un bloque de razonamiento de Fable 5 se envía a un modelo distinto, por ejemplo al cambiar a Opus mediante fallback, se elimina automáticamente del prompt y no se factura, así que no hay nada que quitar.
Cambios en la interfaz de petición
Fable 5 comparte la mayor parte de su interfaz de petición con Opus 4.7/4.8 y Sonnet 5. Según la documentación, se han retirado estas opciones:
thinking: {type: "enabled", budget_tokens: N}devuelve un 400. El razonamiento extendido con presupuesto de tokens, usado desde Claude 3.7 Sonnet hasta la familia 4.5, se ha retirado en toda la línea 4.7+ y se ha sustituido por el razonamiento adaptativo.thinking: {type: "disabled"}devuelve un 400, algo exclusivo de Fable 5. Opus 4.7/4.8 y Sonnet 5 todavía permiten desactivar el razonamiento; Fable 5 no.temperature,top_pytop_kse rechazan si tienen cualquier valor distinto del predeterminado.- Los prefills de mensajes del asistente, un turno final
assistant, devuelven un 400.
La eliminación de temperature/top_p/top_k y de los prefills es lo que más suele romper una petición migrada. Los cambios de razonamiento y retención se explican más arriba y en el artículo sobre la retención de datos durante 30 días.
Conclusión
Usar Fable 5 en un agente plantea primero un problema de ingeniería y después uno de presupuesto. Comprueba stop_reason: "refusal" antes de ejecutar tool calls; de lo contrario, una escritura truncada puede corromper el estado incluso en una tarea tan rutinaria como corregir una configuración. Después, controla el coste según la forma de la carga: la caché es el factor con mayor impacto; el mínimo ahora es de 2,048 tokens, así que conviene revisar el prefijo; un presupuesto de tarea evita que el bucle acumule el mayor coste por turno de esta comparación; y effort: "low" no ofrece el descuento que su nombre sugiere. También hay que presupuestar por tipo de carga: el mismo modelo cuesta 15x más que glm-5.2 en un bucle de programación y 5x más que sonnet-5 en batch con caché caliente. Esto no implica que debas usarlo o descartarlo. Significa que los valores predeterminados no son neutros, y tanto la factura como los modos de fallo dependen de la arquitectura del agente.
Preguntas frecuentes
¿Fable 5 rechaza tool calls con frecuencia?
Los rechazos se concentraron en tareas concretas: una corrección de configuración se rechazó en todas las ejecuciones, mientras que otras nunca fallaron. Las mismas tareas reprodujeron el comportamiento tanto con streaming como sin él. Por tanto, no es un fallo esporádico que se resuelva reintentando. La frecuencia será distinta con tu carga, pero la respuesta de ingeniería no cambia: comprueba stop_reason antes de ejecutar tool calls.
¿Puedo desactivar el razonamiento de Fable 5?
No. Tanto thinking.type.disabled como enabled se rechazan. El razonamiento es adaptativo de forma predeterminada y output_config.effort es el único control; en nuestro bucle, usar el esfuerzo low no redujo el coste.
¿Fable 5 es alguna vez la opción barata? No en este conjunto. Su menor sobrecoste aparece en procesamiento batch con mucho uso de caché caliente, donde cuesta aproximadamente 5x más que sonnet-5 porque la caché absorbe casi todo el prompt. En los bucles y en la conversación larga fue el modelo más caro que probamos.
Verificación: todas las cifras se midieron el 2026-07-05 contra https://synthorai.io/ (/v1/messages nativo de Anthropic para los modelos Claude y /v1/chat/completions para glm-5.2), con 505 episodios y 1,022 llamadas repartidos entre cinco tipos de escenarios. Cuando la variabilidad era relevante, se hicieron tres ejecuciones por tarea. Los costes corresponden al usage.cost informado por el gateway y se muestran las medianas. Las tareas son deliberadamente sencillas, por lo que las tasas de acierto sirven como control básico, no como benchmark de capacidad; no publicamos afirmaciones sobre capacidades que no hayamos medido. El comportamiento de rechazo se reprodujo tanto con streaming como sin él. Tus cifras variarán según los prompts, la región y la carga.