🎁 Nuevo Regístrate gratis, 10 llamadas de regalo. Hasta 1 $, sin tarjeta.
Claude Fable 5 para agentes: rechazos a media tool call, coste frente a GLM 5.2

Claude Fable 5 para agentes: rechazos a media tool call, coste frente a GLM 5.2

Contenido
  1. Verifica el stop_reason antes de ejecutar las llamadas a herramientas
  2. Lo que cuestan cinco formas de agente
  3. Cómo mantener baja la factura de un agente
  4. Dos sorpresas de costo que la documentación no menciona
  5. Qué cambió en la superficie de la request
  6. En resumen
  7. Preguntas frecuentes

Claude Fable 5 rechazó la tarea a media tool call en 11 de 44 turnos de nuestro coding agent, en cosas tan triviales como corregir un valor por defecto de configuración. El rechazo llega como stop_reason: "refusal" mientras se generan los argumentos de la tool, los argumentos truncados siguen siendo JSON válido, y un bucle de agente que ejecuta las tool calls sin revisar el stop reason escribirá tan tranquilo un archivo a medias en disco. Ese comportamiento, no el precio, es lo primero que hay que resolver por diseño cuando metes Fable 5 en un agente.

TL;DR

  • Claude Fable 5 devolvió stop_reason: "refusal" a media tool call en tareas de agente triviales (corregir un valor por defecto de configuración, reservar una sala de reuniones); los argumentos truncados de write_file seguían parseando, así que un bucle que no revisa el stop reason ejecuta archivos escritos a medias.
  • El thinking de Fable 5 es adaptativo y no se puede desactivar: enabled y disabled se rechazan; el control es output_config.effort.
  • El sobrecoste de Fable 5 depende de la forma de la tarea: una tarea de coding de cuatro turnos costó $0,045 frente a $0,003 en glm-5.2 (15x), pero solo 5x sonnet-5 en trabajo por lotes en caliente.
  • Fable 5 exige retención de datos de 30 días.

Todo lo que sigue se midió el 2026-07-05 a través del gateway de Synthorai con un pequeño arnés de escenarios: cinco formas de carga de trabajo de agentes (un bucle de coding con tools, question answering con RAG, orquestación intensiva en tools, clasificación por lotes y una conversación de 15 turnos), ejecutadas contra claude-fable-5, claude-opus-4-8, claude-sonnet-5 y glm-5.2, con tres ejecuciones por tarea donde la varianza importa. Las tareas son deliberadamente triviales; las tasas de acierto son un control de cordura, no un benchmark de capacidad. Los costes son el usage.cost que factura el gateway.

Verifica el stop_reason antes de ejecutar las llamadas a herramientas

Este es el fallo del que la documentación no te avisa, y corrompe el estado. El agente lee app.py, decide escribir la corrección y empieza a emitir una llamada write_file. A mitad del contenido del archivo, el stream se corta:

{
  "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 parseable. Nada indica que “me detuve antes de tiempo”. Si el contrato de tu bucle es “llegaron llamadas a herramientas, ejecútalas”, acabas de sobrescribir app.py con un fragmento de 38 caracteres que termina a mitad de un diccionario y que ya no parsea como Python. Y el siguiente turno también es un rechazo, así que el bucle termina con el workspace corrupto.

Tres cosas que se pueden afirmar a partir de los datos:

  • Se dispara en tareas triviales. Las tareas que provocaron rechazos fueron arreglar un KeyError en una búsqueda de configuración, implementar una función slugify, reservar una sala de reuniones y crear un borrador de factura. Nada de doble uso, nada sensible.
  • Es reproducible, no aleatorio. Una tarea de código provocó un rechazo en las tres ejecuciones, tanto en streaming como sin él. Otras tareas nunca lo provocaron. Entre las distintas condiciones, entre el 58 % y el 75 % de nuestros episodios triviales de código pasaron en Fable 5, frente al 100 % de claude-opus-4-8, claude-sonnet-5 y glm-5.2, y cada fallo se debe a un rechazo, no a código incorrecto.
  • Una vez que hay un rechazo en la conversación, el episodio está muerto. Los turnos posteriores devolvieron stop_reason: "refusal" con salida vacía. Reintentar dentro del mismo contexto no lo recuperó.

El disparador no es el contenido de la tarea, y los datos lo dejan claro. La tarea que se rechazó en cada ejecución era un arreglo de nueve líneas de un KeyError en un diccionario de configuración: sin credenciales, sin exploits. En cambio, el escenario de batch clasificó tickets de soporte sobre criptominería, claves de Stripe filtradas y páginas de phishing sin un solo rechazo, y el escenario de RAG respondió sobre documentos llenos de secretos AES-256-GCM y procedimientos de respuesta a brechas, también limpio. Todos los rechazos cayeron en los dos escenarios multi-turno con ejecución de herramientas; los tres escenarios de una sola pasada nunca rechazaron ni una vez, aun con contenido más pesado. El patrón es la forma del bucle del agente, no las palabras, lo que significa que sanear tus entradas no lo evitará.

La corrección es una línea antes del paso de ejecución de 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 la mecánica: un rechazo que salta antes de devolver salida deja un array content vacío y no se factura; un rechazo a mitad de stream factura la salida ya emitida, y la recomendación es descartar el fragmento parcial. La respuesta también incluye un objeto stop_details con una categoría (como cyber o bio, o null) para distinguir los bloqueos del clasificador de los rechazos normales. Lo que la documentación no detalla es la interacción con el uso de herramientas que vimos arriba: el rechazo puede caer dentro de la generación de argumentos, y los argumentos parciales son indistinguibles de los completos.

También existe una ruta de recuperación oficial. En la API de Claude, el parámetro beta fallbacks (betas: ["server-side-fallback-2026-06-01"], fallbacks: [{"model": "claude-opus-4-8"}]) reejecuta una petición rechazada sobre un modelo de fallback dentro de la misma llamada, sin facturar el rechazo cuando saltó antes de la salida. No está disponible en Amazon Bedrock, Vertex AI ni Microsoft Foundry, donde los SDK incluyen en su lugar un middleware de fallback del lado del cliente. Sea cual sea la ruta, el guard de arriba sigue yendo primero: nunca ejecutes llamadas a herramientas de un turno cuyo stop reason sea un rechazo.

Lo que cuestan cinco formas de agente

Coste mediano por unidad completada (tarea, consulta, ítem o conversación), mismos prompts, mismo día:

Escenariofable-5opus-4-8sonnet-5glm-5.2
Bucle de coding (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 tools (por tarea)$0.048$0.011$0.0045$0.0027
Clasificación por lotes (por ítem, en caliente)$0.0024$0.0012$0.00046$0.00057
Conversación de 15 turnos (completa)$0.94$0.34$0.26$0.083

De esa tabla hay dos lecturas que importan más que cualquier celda concreta:

  • El modelo más barato cambia según la forma. glm-5.2 gana en los bucles y en la conversación larga, pero claude-sonnet-5 es el clasificador por lotes más barato del conjunto, por debajo de glm-5.2, porque su precio de lanzamiento monta sobre un 97% de lecturas de caché una vez que el prompt de scaffold está en caliente.
  • El sobreprecio de Fable 5 también depende de la forma: 15x glm-5.2 en el bucle de coding, 11x en conversación, pero solo 5x sonnet-5 en ítems de lote en caliente, donde el caché absorbe la mayor parte del prompt.

El resto del panorama de costes va de controlar esos números, y luego de dos cosas que los vuelven a empujar hacia arriba sin hacer ruido.

Cómo mantener baja la factura de un agente

El caché es la palanca más grande, y en Fable 5 su contrato no cambia. Los datos de los agentes muestran lo que vale: al quitar los marcadores cache_control, la misma tarea de coding costó 2,0x más, y los ítems de lote en caliente 6,8x más. En opus-4-8 la misma ablación da 3,8x y 6,9x. En un bucle, el patrón de marcador deslizante no es una optimización, es la diferencia entre una factura viable y una que no lo es.

El orden del prompt es la segunda palanca, y se sostuvo en todos los modelos que probamos. Poner las reglas estables antes del contexto por consulta (en vez de después) abarató las consultas RAG entre un 26 y un 37% en los cuatro modelos; en la línea Claude, el orden equivocado además paga el sobreprecio de escritura de caché de 1,25x en cada llamada. La mecánica está en el post de caching con LangChain; los números de aquí solo confirman que aplican igual en Fable 5.

Fable 5 suma además dos palancas propias. La primera es que el umbral mínimo para caché bajó a 2.048 tokens, la mitad de los 4.096 de Opus 4.8. Suena a dato trivial hasta que recuerdas de dónde salen los ahorros de un agente: lo que se cachea es el scaffold repetido (system prompt, definiciones de tools, el prefijo deslizante de la conversación), y solo si supera el umbral. Un agente con muchas tools cuyo prefijo por turno quedaba entre 2.048 y 4.096 tokens no obtenía ningún caché en Opus 4.8, y empieza a cachear en Fable 5, convirtiendo un prefijo a precio completo en una lectura de caché de aproximadamente el 10% del precio en cada turno posterior. El corte va también en el otro sentido: un prefijo rellenado para superar el antiguo umbral de 4.096 puede estar cargando peso muerto ahora. Lee cache_read_input_tokens de una respuesta real en vez de dar por hecho, porque en Fable 5 el descuento empieza antes.

La segunda son los presupuestos de tarea (beta, header task-budgets-2026-03-13), que atacan justo el problema que esta comparación no deja de sacar a la luz: un bucle de Fable 5 dispara la factura rápido, y max_tokens no ayuda. Es un tope duro por respuesta que el modelo no ve, así que el modelo planifica como si tuviera espacio ilimitado y luego lo cortan a mitad de razonamiento. Un presupuesto de tarea es distinto. Le das al bucle un techo de tokens (mínimo 20.000) que el modelo ve como una cuenta atrás en marcha y contra la que se autorregula, cerrando de forma ordenada en vez de quedar truncado. Cuenta lo que el modelo genera más los resultados de tools que lee en el turno, no el historial completo que reenvías en cada request. En un modelo cuyo turno de bucle de coding cuesta 15x glm-5.2, un presupuesto hacia el que el modelo se autolimita es la barrera más barata que puedes atornillarle.

Dos sorpresas de costo que la documentación no menciona

Con las palancas ya ajustadas, dos detalles menores movieron nuestra factura en direcciones sobre las que la documentación no advierte.

El esfuerzo “low” no salió más barato. La profundidad de razonamiento de Fable 5 se controla con output_config.effort, y la intuición dice que low cuesta menos. No fue así. Poner effort: "low" dejó nuestro loop de coding en $0.0478 por tarea frente a $0.0451 con el valor por defecto, y con más output tokens, no menos. Vimos el mismo patrón en GLM 5.2, donde los nombres de effort tampoco se corresponden con el conteo de tokens. En ambas líneas de modelos, mide la palanca con tu propio workload antes de asumir que “low” significa “menos”. Una razón por la que el número es difícil de predecir: la porción de output tokens del razonamiento adaptativo osciló entre el 2% en el loop de coding, el 30% en respuestas RAG y el 52% en clasificación por lotes, mismo modelo, mismo día. Presupuesta los output tokens según la forma del workload, no según el modelo.

Nunca reenvíes reasoning_content. En los modelos compatibles con OpenAI, el campo de reasoning no es historial de conversación. La API de DeepSeek exige quitarlo; en GLM 5.2 reenviarlo es válido pero se factura. Devolverlo al historial de mensajes infló el costo de nuestro loop con GLM en torno a un 28% hasta que lo eliminamos. Los thinking blocks propios de Anthropic funcionan distinto: con el mismo modelo tienes que reenviarlos sin cambios, pero un thinking block de Fable 5 dirigido a otro modelo (por ejemplo, en un fallback a Opus) se descarta automáticamente del prompt y no se factura, así que no hay nada que quitar.

Qué cambió en la superficie de la request

Fable 5 comparte la mayor parte de su superficie de request con Opus 4.7/4.8 y Sonnet 5. Lo que desaparece, según la documentación:

  • thinking: {type: "enabled", budget_tokens: N} devuelve un 400. El extended thinking con presupuesto de tokens, el mecanismo desde Claude 3.7 Sonnet hasta la familia 4.5, se retira en toda la línea 4.7+ en favor del adaptive thinking.
  • thinking: {type: "disabled"} devuelve un 400, y esto es exclusivo de Fable 5. Opus 4.7/4.8 y Sonnet 5 todavía permiten desactivar el thinking; Fable 5 no.
  • temperature, top_p y top_k se rechazan en cualquier valor distinto del por defecto.
  • Los prefills de mensaje del assistant (un turno assistant al final) devuelven un 400.

La eliminación de temperature/top_p/top_k y de los prefills son las dos que más suelen romper una request portada; los cambios en thinking y retención están cubiertos arriba y en el post sobre retención.

En resumen

Fable 5 dentro de un agente es un problema de ingeniería antes que un problema de presupuesto. Maneja stop_reason: "refusal" antes de ejecutar tool calls, o una escritura truncada corromperá el estado en una tarea tan trivial como arreglar un config. Luego trata el costo como algo que tú modelas: el caching es la palanca más grande, el mínimo de elegibilidad ahora es de 2,048 tokens así que revisa de nuevo tu prefijo, un presupuesto por tarea evita que un loop dispare la factura por turno más alta de esta comparación, y effort: "low" no es el descuento que su nombre sugiere. Presupuesta también según la forma del workload: el mismo modelo cuesta 15x lo de glm-5.2 en un loop de coding y 5x lo de sonnet-5 en trabajo por lotes en caliente. Nada de esto dice úsalo o no lo uses; dice que los valores por defecto no son neutrales, y que tanto la factura como los modos de fallo dependen de cómo esté modelado tu agente.

Preguntas frecuentes

¿Fable 5 rechaza llamadas a herramientas con frecuencia? Se concentró en tareas concretas: una tarea de arreglo de config rechazó en todas las ejecuciones, otras nunca lo hicieron, y las mismas tareas se reprodujeron tanto en llamadas con streaming como sin él. No es un fallo esporádico que puedas superar reintentando. Las tasas variarán según tu carga de trabajo; la respuesta de ingeniería es la misma en cualquier caso: revisa stop_reason antes de ejecutar las llamadas a herramientas.

¿Puedo desactivar el thinking de Fable 5? No. Tanto thinking.type.disabled como enabled son rechazados. El thinking es adaptativo por defecto y output_config.effort es el único control; en nuestro loop, el effort low no redujo el coste.

¿Fable 5 es alguna vez la opción barata? No en este conjunto. Su menor sobrecoste está en el trabajo por lotes con mucha cache caliente, unas 5 veces sonnet-5, donde una cache caliente absorbe la mayor parte del prompt. En los loops y en la conversación larga es el modelo más caro que ejecutamos.


Verificación: todas las cifras medidas el 2026-07-05 contra https://synthorai.io/ (/v1/messages nativo de Anthropic para la línea Claude, /v1/chat/completions para glm-5.2), 505 episodios y 1.022 llamadas en cinco formas de escenario, tres ejecuciones por tarea donde la varianza importa. Los costes son el usage.cost reportado por el gateway; se muestran las medianas. Las tareas son deliberadamente simples, así que las tasas de aprobación son un control de cordura, no un benchmark de capacidad; no publicamos afirmaciones de capacidad que no hayamos medido. El comportamiento de rechazo se reprodujo tanto en modo streaming como sin él. Tus números variarán según los prompts, la región y la carga.

← Volver al blog