🎁 Novo Cadastre-se grátis, 10 chamadas por nossa conta. Até US$ 1, sem cartão.
Claude Fable 5 para agentes: recusas no meio da tool-call, custo vs GLM 5.2

Claude Fable 5 para agentes: recusas no meio da tool-call, custo vs GLM 5.2

Conteúdo
  1. Verifique o stop_reason antes de executar tool calls
  2. Quanto custam cinco formatos de agente
  3. Mantendo a conta de um agente baixa
  4. Duas surpresas de custo que a documentação não avisa
  5. O que mudou na superfície de request
  6. Conclusão
  7. FAQ

Na nossa avaliação, o Claude Fable 5 recusou no meio da tool-call em 11 de 44 turnos de agente de código, em tarefas tão banais quanto corrigir um valor default de config. A recusa chega como stop_reason: "refusal" no meio da geração dos argumentos da tool, os argumentos truncados ainda são JSON válido, e um loop de agente que executa tool calls sem checar o stop reason vai tranquilamente gravar em disco um arquivo pela metade. Esse comportamento, e não o preço, é a primeira coisa que você precisa contornar ao colocar o Fable 5 num agente.

TL;DR

  • O Claude Fable 5 retornou stop_reason: "refusal" no meio da tool-call em tarefas banais de agente (corrigir um default de config, reservar uma sala de reunião); os argumentos truncados do write_file ainda foram parseados, então um loop que não checa o stop reason executa arquivos escritos pela metade.
  • O thinking do Fable 5 é adaptativo e não tem como desligar: enabled e disabled são ambos rejeitados; o controle é output_config.effort.
  • O sobrecusto do Fable 5 depende do formato: uma tarefa de código de quatro turnos custou $0,045 contra $0,003 no glm-5.2 (15x), mas só 5x o sonnet-5 em trabalho de batch quente.
  • O Fable 5 exige retenção de dados por 30 dias.

Tudo abaixo foi medido em 2026-07-05 através do gateway Synthorai, com um pequeno harness de cenários: cinco formatos de workload de agente (um loop de código usando tools, question answering com RAG, orquestração pesada em tools, classificação em batch e uma conversa de 15 turnos), rodados contra claude-fable-5, claude-opus-4-8, claude-sonnet-5 e glm-5.2, três execuções por tarefa onde a variância importa. As tarefas são propositalmente triviais; as taxas de sucesso são um teste de sanidade, não um benchmark de capacidade. Os custos são o usage.cost faturado pelo gateway.

Verifique o stop_reason antes de executar tool calls

Essa é a falha que a documentação não avisa, e ela corrompe o estado. O agente lê app.py, decide escrever a correção e começa a emitir uma chamada write_file. No meio do conteúdo do arquivo, o stream para:

{
  "stop_reason": "refusal",
  "content": [{
    "type": "tool_use",
    "name": "write_file",
    "input": {
      "path": "app.py",
      "content": "DEFAULTS = {\n    \"timeout_s\": 30,\n    "
    }
  }]
}

O objeto input é um JSON completo e parseável. Nada nele diz “parei antes da hora”. Se o contrato do seu loop é “recebi tool calls, então execute”, você acabou de sobrescrever app.py com um fragmento de 38 caracteres que termina no meio de um dicionário e não é mais Python válido. O turno seguinte também é um refusal, e o loop termina com o workspace corrompido.

Três coisas dá para afirmar a partir dos dados:

  • Dispara em trabalho trivial. As tarefas que geraram refusals foram: corrigir um KeyError em uma busca de config, implementar uma função de slugify, reservar uma sala de reunião e criar um rascunho de fatura. Nada de uso duplo, nada sensível.
  • É reprodutível, não aleatório. Uma tarefa de código gerou refusal nas três execuções, com e sem streaming. Outras tarefas nunca geraram. Entre as condições, 58-75% dos nossos episódios triviais de código passaram no Fable 5, contra 100% no claude-opus-4-8, claude-sonnet-5 e glm-5.2, e toda falha vem de um refusal, não de código errado.
  • Uma vez que o refusal entra na conversa, o episódio acabou. Os turnos seguintes retornaram stop_reason: "refusal" com saída vazia. Tentar de novo dentro do mesmo contexto não recuperou.

O gatilho não é o conteúdo da tarefa, e os dados são diretos nisso. A tarefa que recusou em toda execução era uma correção de KeyError de nove linhas em um dicionário de config, sem credenciais, sem exploits. Enquanto isso, o cenário em batch classificou tickets de suporte sobre cryptomining, chaves Stripe vazadas e páginas de phishing sem um único refusal, e o cenário de RAG respondeu sobre docs cheios de segredos AES-256-GCM e procedimentos de resposta a incidentes, também sem problema. Todos os refusals aconteceram nos dois cenários multi-turno que executam tools; os três cenários single-shot nunca recusaram, mesmo carregando conteúdo mais pesado. O padrão está no formato do agent-loop, não nas palavras, o que significa que sanitizar as entradas não vai prevenir.

A correção é uma linha antes do passo de execução das tools:

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")

A Anthropic documenta a mecânica: um refusal que dispara antes de qualquer saída retorna um array content vazio e não é cobrado; um refusal no meio do stream cobra a saída já transmitida, e a orientação é descartar a parte parcial. A resposta também traz um objeto stop_details com uma categoria (como cyber ou bio, ou null) para você distinguir bloqueios do classificador de recusas comuns. O que a documentação não detalha é a interação com o uso de tools que descrevi acima: o refusal pode cair no meio da geração dos argumentos, e os argumentos parciais são indistinguíveis dos completos.

Existe também um caminho oficial de recuperação. Na Claude API, o parâmetro beta fallbacks (betas: ["server-side-fallback-2026-06-01"], fallbacks: [{"model": "claude-opus-4-8"}]) reexecuta uma requisição recusada em um modelo de fallback dentro da mesma chamada, com a recusa não cobrada quando dispara antes da saída. Não está disponível no Amazon Bedrock, Vertex AI ou Microsoft Foundry, onde os SDKs entregam um middleware de fallback no client. Independente do caminho, o guard acima vem primeiro: nunca execute tool calls de um turno cujo stop reason seja um refusal.

Quanto custam cinco formatos de agente

Custo mediano por unidade concluída (tarefa, consulta, item ou conversa), mesmos prompts, mesmo dia:

Cenáriofable-5opus-4-8sonnet-5glm-5.2
Loop de coding (por tarefa, mediana de 4 turnos)$0.045$0.012$0.0059$0.0031
Resposta RAG (por consulta)$0.024$0.0075$0.0036$0.0031
Orquestração de tools (por tarefa)$0.048$0.011$0.0045$0.0027
Classificação em batch (por item, warm)$0.0024$0.0012$0.00046$0.00057
Conversa de 15 turnos (inteira)$0.94$0.34$0.26$0.083

Duas leituras dessa tabela importam mais que qualquer célula isolada:

  • O modelo mais barato muda conforme o formato. O glm-5.2 vence nos loops e na conversa longa, mas o claude-sonnet-5 é o classificador em batch mais barato do conjunto, abaixo do glm-5.2, porque o preço introdutório se apoia numa fatia de 97% de cache-read assim que o prompt de scaffold está warm.
  • O prêmio do Fable 5 também depende do formato: 15x o glm-5.2 no loop de coding, 11x na conversa, mas só 5x o sonnet-5 nos itens de batch warm, onde o cache absorve a maior parte do prompt.

O resto do quadro de custos é sobre controlar esses números, e depois sobre duas coisas que silenciosamente os empurram para cima de novo.

Mantendo a conta de um agente baixa

O cache é a maior alavanca isolada, e no Fable 5 o seu contrato não mudou. Os dados dos agentes mostram quanto isso vale: sem os marcadores cache_control, a mesma tarefa de coding custou 2.0x mais, e os itens de batch warm 6.8x mais. No opus-4-8 a mesma ablação dá 3.8x e 6.9x. Num loop, o padrão de sliding marker não é uma otimização, é a diferença entre uma conta viável e uma que não é.

A ordem do prompt é a segunda alavanca, e se manteve em todos os modelos que rodamos. Colocar as regras estáveis antes do contexto por consulta (em vez de depois dele) deixou as consultas RAG 26-37% mais baratas nos quatro modelos; na linha Claude, a ordem errada ainda paga o prêmio de 1.25x de cache-write em cada chamada. A mecânica está no post sobre caching no LangChain; os números aqui só confirmam que ela vale sem alterações no Fable 5.

O Fable 5 também traz duas alavancas próprias. A primeira é que o piso de elegibilidade para cache caiu para 2.048 tokens, metade dos 4.096 do Opus 4.8. Isso parece trivialidade até você lembrar de onde vêm as economias de um agente: o scaffold repetido (system prompt, definições de tools, o prefixo deslizante da conversa) é o que cacheia, e só se ultrapassar o piso. Um agente com muitas tools cujo prefixo por turno ficava entre 2.048 e 4.096 tokens não tinha cache nenhum no Opus 4.8, e passa a cachear no Fable 5, transformando um prefixo a preço cheio numa cache-read de cerca de 10% do preço em cada turno seguinte. O contrário também vale: um prefixo inflado para ultrapassar o antigo piso de 4.096 pode estar carregando peso morto agora. Leia cache_read_input_tokens de uma resposta real em vez de supor, porque no Fable 5 o desconto começa antes.

A segunda são os task budgets (beta, header task-budgets-2026-03-13), que resolvem exatamente o problema que essa comparação não para de expor: um loop no Fable 5 dispara a conta rápido, e o max_tokens não ajuda. Ele é um teto rígido por resposta que o modelo não enxerga, então o modelo planeja como se tivesse espaço ilimitado e depois é cortado no meio do raciocínio. Um task budget é diferente. Você dá ao loop um teto de tokens (mínimo de 20.000) que o modelo vê como uma contagem regressiva em andamento e usa para se autorregular, encerrando de forma limpa em vez de ser truncado. Ele conta o que o modelo gera mais os resultados de tools que ele lê no turno, não o histórico completo que você reenvia a cada request. Num modelo cujo turno de loop de coding custa 15x o glm-5.2, um budget para o qual o próprio modelo se modera é a proteção mais barata que dá para acoplar.

Duas surpresas de custo que a documentação não avisa

Depois de ajustar os controles principais, duas coisas menores ainda mexeram na nossa conta em direções que a documentação não menciona.

O esforço “low” não saiu mais barato. A profundidade de raciocínio do Fable 5 é controlada por output_config.effort, e a intuição diz que low custa menos. Não foi o caso. Rodar nosso loop de código com effort: "low" custou $0,0478 por tarefa contra $0,0451 no valor padrão, com mais output tokens, não menos. Vimos o mesmo padrão no GLM 5.2, onde os nomes de esforço também não correspondem à contagem de tokens. Nas duas famílias de modelo, meça esse controle no seu próprio workload antes de assumir que “low” significa “menos”. Um dos motivos pelos quais o número é difícil de prever: a fatia de output tokens do adaptive thinking variou de 2% no loop de código para 30% em respostas de RAG e 52% em classificação em batch — mesmo modelo, mesmo dia. Faça o orçamento de output tokens por formato de workload, não por modelo.

Nunca reenvie reasoning_content. Em modelos compatíveis com OpenAI, o campo de reasoning não é histórico de conversa. A API da DeepSeek exige remover esse campo; no GLM 5.2 reenviá-lo é permitido, mas é cobrado. Realimentar o histórico de mensagens com ele inflou o custo do nosso loop no GLM em cerca de 28% até que passamos a removê-lo. Os thinking blocks da própria Anthropic funcionam de outro jeito: no mesmo modelo você precisa reenviá-los sem alterações, mas um thinking block do Fable 5 roteado para um modelo diferente (digamos, num fallback para o Opus) é descartado do prompt automaticamente e não é cobrado, então não há o que remover.

O que mudou na superfície de request

O Fable 5 compartilha a maior parte da superfície de request com o Opus 4.7/4.8 e o Sonnet 5. O que sumiu, segundo a documentação:

  • thinking: {type: "enabled", budget_tokens: N} retorna 400. O extended thinking com orçamento de tokens, o mecanismo que existia do Claude 3.7 Sonnet até a família 4.5, foi aposentado em toda a linha 4.7+ em favor do adaptive thinking.
  • thinking: {type: "disabled"} retorna 400, e essa é exclusiva do Fable 5. O Opus 4.7/4.8 e o Sonnet 5 ainda permitem desligar o thinking; o Fable 5 não.
  • temperature, top_p e top_k são rejeitados em qualquer valor diferente do padrão.
  • Prefills de mensagem do assistant (um turno assistant no final) retornam 400.

A remoção de temperature/top_p/top_k e dos prefills são as duas que mais pegam um request portado; as mudanças de thinking e retenção estão cobertas acima e no post sobre retenção.

Conclusão

O Fable 5 num agente é um problema de engenharia antes de ser um problema de orçamento. Trate o stop_reason: "refusal" antes de executar as tool calls, ou uma escrita truncada vai corromper o estado numa tarefa tão banal quanto corrigir um config. Depois, encare o custo como algo que você molda: o cache é o maior controle, o piso de elegibilidade agora é 2.048 tokens (revise seu prefixo), um orçamento por tarefa impede que um loop acumule a maior conta por turno desta comparação, e effort: "low" não é o desconto que o nome sugere. Faça o orçamento por formato de workload também: o mesmo modelo custa 15x o glm-5.2 num loop de código e 5x o sonnet-5 em trabalho de batch com cache quente. Nada disso diz para usar ou não usar; diz que os defaults não são neutros, e que tanto a conta quanto os modos de falha dependem de como o seu agente está estruturado.

FAQ

O Fable 5 recusa tool calls com frequência? Ele se concentrou em tarefas específicas: uma tarefa de correção de config recusou em toda execução, outras nunca recusaram, e as mesmas tarefas se reproduziram tanto em chamadas com streaming quanto sem streaming. Ou seja, não é uma falha rara que você contorna com retry. As taxas na sua carga de trabalho vão ser diferentes; a resposta de engenharia é a mesma nos dois casos: verifique o stop_reason antes de executar tool calls.

Dá para desligar o thinking do Fable 5? Não. Tanto thinking.type.disabled quanto enabled são rejeitados. O thinking é adaptativo por padrão e output_config.effort é o único controle; no nosso loop, o effort low não reduziu o custo.

O Fable 5 chega a ser a opção barata? Não neste conjunto. O menor prêmio dele é em trabalho de batch com cache quente, cerca de 5x o sonnet-5, onde um cache quente absorve a maior parte do prompt. Nos loops e na conversa longa, é o modelo mais caro que rodamos.


Verificação: todos os números medidos em 2026-07-05 contra https://synthorai.io/ (/v1/messages nativo da Anthropic para a linha Claude, /v1/chat/completions para o glm-5.2), 505 episódios e 1.022 chamadas em cinco formatos de cenário, três execuções por tarefa onde a variância importa. Os custos são o usage.cost reportado pelo gateway; medianas exibidas. As tarefas são propositalmente simples, então as taxas de acerto são uma verificação de sanidade, não um benchmark de capacidade; não publicamos alegações de capacidade que não medimos. O comportamento de recusa se reproduziu tanto em modo streaming quanto não-streaming. Seus números vão variar conforme prompts, região e carga.

← Voltar ao blog