Claude Fable 5 per gli agent: rifiuti durante le tool call e costi rispetto a GLM 5.2
Indice
Nella nostra valutazione Claude Fable 5 ha interrotto con un rifiuto 11 dei 44 turni di un coding agent, anche su attività banali come correggere il valore predefinito di una configurazione. Il rifiuto arriva come stop_reason: "refusal" mentre il modello sta ancora generando gli argomenti della tool call. Gli argomenti troncati restano JSON valido, quindi un agent loop che esegue le tool call senza controllare lo stop reason può tranquillamente scrivere su disco un file incompleto. Quando si usa Fable 5 in un agente, questo comportamento va gestito prima ancora dei costi.
TL;DR
- Claude Fable 5 ha restituito
stop_reason: "refusal"durante una tool call su attività agentiche banali, come correggere una configurazione predefinita o prenotare una sala riunioni. Gli argomenti troncati diwrite_fileerano comunque validi, quindi un loop che non controlla lo stop reason finisce per scrivere file incompleti. - Il thinking di Fable 5 è adattivo e non può essere disattivato: sia
enabledsiadisabledvengono rifiutati. L’unico controllo disponibile èoutput_config.effort. - Il sovrapprezzo di Fable 5 dipende dal tipo di workload: un’attività di coding in quattro turni è costata $0.045 contro $0.003 su glm-5.2, cioè 15 volte tanto, ma sui batch a cache calda il costo è stato solo 5 volte quello di sonnet-5.
- Fable 5 richiede una conservazione dei dati di 30 giorni.
Tutti i dati riportati di seguito sono stati raccolti il 2026-07-05 tramite il gateway Synthorai, usando un piccolo harness con cinque tipi di workload agentico: un loop di coding con tool, un sistema RAG per rispondere a domande, un’orchestrazione con molte tool call, una classificazione batch e una conversazione di 15 turni. I test sono stati eseguiti su claude-fable-5, claude-opus-4-8, claude-sonnet-5 e glm-5.2, con tre esecuzioni per attività nei casi in cui la variabilità è rilevante. Le attività sono volutamente semplici: il tasso di successo serve solo come controllo di base, non come benchmark delle capacità. I costi corrispondono al valore usage.cost fatturato dal gateway.
Controllare stop_reason prima di eseguire le tool call
È un caso di errore non segnalato nella documentazione e può corrompere lo stato. L’agente legge app.py, decide di applicare la correzione e inizia a generare una chiamata a write_file. A metà del contenuto del file, lo stream si interrompe:
{
"stop_reason": "refusal",
"content": [{
"type": "tool_use",
"name": "write_file",
"input": {
"path": "app.py",
"content": "DEFAULTS = {\n \"timeout_s\": 30,\n "
}
}]
}
L’oggetto input è JSON completo e valido. Non contiene alcuna indicazione che la generazione si sia interrotta in anticipo. Se il contratto del loop è «ho ricevuto delle tool call, quindi le eseguo», app.py viene sovrascritto con un frammento di 38 caratteri che termina a metà di un dizionario e non è più Python valido. Anche il turno successivo termina con un rifiuto, quindi il loop si chiude lasciando il workspace corrotto.
Dai dati emergono tre punti:
- Succede anche su attività banali. I rifiuti si sono verificati durante la correzione di un
KeyErrornella lettura di una configurazione, l’implementazione di una funzione slugify, la prenotazione di una sala riunioni e la creazione di una fattura in bozza. Nessuna attività dual-use o sensibile. - È ripetibile, non casuale. Un’attività di coding è stata rifiutata in tutte e tre le esecuzioni, sia in streaming sia senza streaming. Altre attività non hanno mai prodotto un rifiuto. A seconda delle condizioni, Fable 5 ha completato il 58-75% dei nostri semplici episodi di coding, contro il 100% di claude-opus-4-8, claude-sonnet-5 e glm-5.2. Tutti gli errori sono riconducibili a un rifiuto, non a codice errato.
- Dopo un rifiuto, l’episodio è sostanzialmente concluso. I turni successivi hanno restituito
stop_reason: "refusal"senza output. Riprovare nello stesso contesto non ha permesso di recuperare.
Il contenuto dell’attività non sembra essere il fattore scatenante. L’attività rifiutata in tutte le esecuzioni consisteva in una correzione di nove righe a un KeyError in un dizionario di configurazione, senza credenziali né exploit. Lo scenario batch, invece, ha classificato ticket di assistenza relativi a cryptomining, chiavi Stripe esposte e pagine di phishing senza produrre un solo rifiuto. Anche lo scenario RAG ha risposto usando documenti pieni di segreti AES-256-GCM e procedure di risposta alle violazioni, sempre senza problemi. Tutti i rifiuti si sono verificati nei due scenari multi-turno che eseguivano tool; i tre scenari single-shot non ne hanno prodotto nessuno, pur trattando contenuti più delicati. Il pattern dipende quindi dalla struttura dell’agent loop, non dalle parole usate. Ripulire gli input non basta a prevenirlo.
La correzione richiede una sola riga prima dell’esecuzione delle tool call:
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 il funzionamento generale: se il rifiuto scatta prima che venga generato qualsiasi output, la risposta contiene un array content vuoto e non viene fatturata. Se avviene durante lo streaming, l’output già trasmesso viene fatturato e va scartato. La risposta include anche un oggetto stop_details con una categoria, per esempio cyber, bio o null, che permette di distinguere i blocchi del classificatore dai normali rifiuti. La documentazione non chiarisce però l’interazione con l’uso dei tool osservata nei test: il rifiuto può arrivare durante la generazione degli argomenti e gli argomenti parziali sono indistinguibili da quelli completi.
Esiste anche un meccanismo ufficiale di recupero. Nella Claude API, il parametro beta fallbacks (betas: ["server-side-fallback-2026-06-01"], fallbacks: [{"model": "claude-opus-4-8"}]) riesegue nello stesso ciclo una richiesta rifiutata usando un modello di fallback. Il rifiuto non viene fatturato se è avvenuto prima dell’output. La funzione non è disponibile su Amazon Bedrock, Vertex AI o Microsoft Foundry, dove gli SDK forniscono invece un middleware di fallback lato client. In ogni caso, il controllo precedente resta obbligatorio: non bisogna mai eseguire le tool call di un turno il cui stop reason è un rifiuto.
Quanto costano cinque tipi di workload agentico
Costo mediano per unità completata, cioè attività, query, elemento o conversazione, con gli stessi prompt e nello stesso giorno:
| Scenario | fable-5 | opus-4-8 | sonnet-5 | glm-5.2 |
|---|---|---|---|---|
| Loop di coding (per attività, mediana di 4 turni) | $0.045 | $0.012 | $0.0059 | $0.0031 |
| Risposta RAG (per query) | $0.024 | $0.0075 | $0.0036 | $0.0031 |
| Orchestrazione di tool (per attività) | $0.048 | $0.011 | $0.0045 | $0.0027 |
| Classificazione batch (per elemento, cache calda) | $0.0024 | $0.0012 | $0.00046 | $0.00057 |
| Conversazione di 15 turni (completa) | $0.94 | $0.34 | $0.26 | $0.083 |
Da questa tabella emergono due aspetti più importanti dei singoli valori:
- Il modello più economico cambia in base al workload. glm-5.2 vince nei loop e nella conversazione lunga, ma claude-sonnet-5 è il classificatore batch più economico del gruppo, anche rispetto a glm-5.2. Il suo prezzo di lancio sfrutta una quota di cache read del 97% una volta che il prompt di scaffold è in cache.
- Anche il sovrapprezzo di Fable 5 dipende dal workload: costa 15 volte glm-5.2 nel loop di coding e 11 volte nella conversazione, ma solo 5 volte sonnet-5 sugli elementi batch con cache calda, perché la cache assorbe gran parte del prompt.
Il resto dell’analisi dei costi riguarda come tenere sotto controllo questi valori e due fattori che possono farli risalire senza troppo rumore.
Come ridurre i costi di un agente
La cache è la leva principale e su Fable 5 il relativo contratto non è cambiato. I dati degli agenti ne mostrano l’impatto: rimuovendo i marker cache_control, la stessa attività di coding è costata 2.0 volte di più e gli elementi batch con cache calda 6.8 volte di più. Su opus-4-8 lo stesso test ha prodotto aumenti rispettivamente di 3.8 e 6.9 volte. In un loop, il pattern con marker scorrevoli non è una semplice ottimizzazione: determina se il costo è sostenibile oppure no.
L’ordine del prompt è la seconda leva e ha dato risultati coerenti su tutti i modelli testati. Inserire le regole stabili prima del contesto specifico della query, anziché dopo, ha ridotto del 26-37% il costo delle query RAG su tutti e quattro i modelli. Sui modelli Claude, l’ordine errato aggiunge inoltre il sovrapprezzo di 1.25 volte per la scrittura in cache a ogni chiamata. Il funzionamento è descritto nell’articolo sulla cache con LangChain; questi dati confermano che vale senza modifiche anche per Fable 5.
Fable 5 aggiunge inoltre due leve specifiche. La prima è che la soglia minima per accedere alla cache è scesa a 2,048 token, la metà dei 4,096 di Opus 4.8. Non è un dettaglio marginale: il risparmio di un agente deriva dalla parte ripetuta dello scaffold, cioè system prompt, definizioni dei tool e prefisso scorrevole della conversazione. Questa parte viene memorizzata in cache solo se supera la soglia. Un agente con molti tool e un prefisso per turno compreso tra 2,048 e 4,096 token non otteneva alcun vantaggio dalla cache su Opus 4.8. Con Fable 5 inizia invece a usarla, trasformando un prefisso a prezzo pieno in una cache read che costa circa il 10% a ogni turno successivo. Vale anche il contrario: un prefisso riempito artificialmente per superare la vecchia soglia di 4,096 token potrebbe ora contenere peso inutile. Conviene leggere cache_read_input_tokens da una risposta reale anziché fare supposizioni, perché su Fable 5 lo sconto parte prima.
La seconda leva sono i task budget (beta, header task-budgets-2026-03-13), pensati per il problema che emerge chiaramente da questo confronto: un loop su Fable 5 può accumulare costi molto rapidamente e max_tokens non risolve il problema. max_tokens è un limite rigido per risposta che il modello non conosce. Il modello pianifica quindi come se avesse spazio illimitato e viene poi interrotto a metà del ragionamento. Un task budget funziona diversamente. Si assegna al loop un tetto di token, con un minimo di 20,000, che il modello vede come un conto alla rovescia e usa per regolare il ritmo, arrivando alla conclusione invece di essere troncato. Il budget include ciò che il modello genera e i risultati dei tool letti durante il turno, non l’intera cronologia reinviata a ogni richiesta. Su un modello il cui turno di coding costa 15 volte quello di glm-5.2, un budget che il modello gestisce autonomamente è il guardrail più economico da aggiungere.
Due sorprese sui costi che la documentazione non segnala
Anche dopo aver configurato queste leve, due aspetti meno evidenti hanno inciso sulla fattura in modi non anticipati dalla documentazione.
L’effort “Low” non è risultato più economico. Su Fable 5 la profondità del thinking viene controllata tramite output_config.effort e verrebbe naturale aspettarsi un costo inferiore con low. Nei test non è successo. Con effort: "low" il loop di coding è costato $0.0478 per attività, contro $0.0451 con il valore predefinito, generando più token di output anziché meno. Abbiamo osservato lo stesso pattern su GLM 5.2, dove anche i nomi dei livelli di effort non corrispondono al numero di token. Su entrambe le famiglie di modelli, la configurazione va misurata sul proprio workload prima di supporre che “low” significhi “meno”. Il valore è difficile da prevedere anche perché la quota di token di output usata dall’adaptive thinking è variata dal 2% nel loop di coding al 30% nelle risposte RAG, fino al 52% nella classificazione batch, con lo stesso modello e nello stesso giorno. I token di output vanno preventivati per tipo di workload, non per modello.
Non reinviare mai reasoning_content. Nei modelli compatibili con OpenAI, il campo del reasoning non fa parte della cronologia della conversazione. L’API di DeepSeek richiede di rimuoverlo; su GLM 5.2 è consentito reinviarlo, ma viene fatturato. Reinserirlo nella cronologia dei messaggi ha aumentato di circa il 28% il costo del nostro loop GLM, finché non lo abbiamo rimosso. I thinking block nativi di Anthropic funzionano diversamente: sullo stesso modello devono essere reinviati senza modifiche. Se però un thinking block di Fable 5 viene inoltrato a un modello diverso, per esempio passando a Opus tramite fallback, viene rimosso automaticamente dal prompt e non viene fatturato. Non c’è quindi nulla da eliminare manualmente.
Modifiche al formato delle richieste
Fable 5 condivide gran parte del formato delle richieste con Opus 4.7/4.8 e Sonnet 5. Secondo la documentazione, sono state rimosse queste funzioni:
thinking: {type: "enabled", budget_tokens: N}restituisce un 400. L’extended thinking con un budget di token, usato da Claude 3.7 Sonnet fino alla famiglia 4.5, è stato ritirato su tutta la linea 4.7+ in favore dell’adaptive thinking.thinking: {type: "disabled"}restituisce un 400 e questa limitazione è specifica di Fable 5. Opus 4.7/4.8 e Sonnet 5 permettono ancora di disattivare il thinking; Fable 5 no.temperature,top_petop_kvengono rifiutati per qualsiasi valore diverso da quello predefinito.- I prefill dei messaggi assistant, cioè un turno
assistantfinale, restituiscono un 400.
La rimozione di temperature/top_p/top_k e dei prefill è quella che crea più spesso problemi quando si porta una richiesta esistente. Le modifiche al thinking e alla conservazione dei dati sono già descritte sopra e nell’articolo sulla conservazione dei dati per 30 giorni.
In sintesi
Con Fable 5, in un agente i problemi di progettazione vengono prima di quelli di budget. Bisogna gestire stop_reason: "refusal" prima di eseguire le tool call, altrimenti una scrittura troncata può corrompere lo stato anche durante un’attività banale come correggere una configurazione. Il costo va poi governato in base alla struttura del workload: la cache è la leva principale; la soglia minima è ora di 2,048 token, quindi conviene ricontrollare il prefisso; un task budget evita che il loop accumuli il costo per turno più alto di questo confronto; effort: "low" non offre lo sconto suggerito dal nome. Anche il budget va definito per tipo di workload: lo stesso modello costa 15 volte glm-5.2 in un loop di coding e 5 volte sonnet-5 sui batch con cache calda. Questi risultati non dicono se usare o meno Fable 5. Mostrano che le impostazioni predefinite non sono neutre e che sia i costi sia le modalità di errore dipendono dalla struttura dell’agente.
FAQ
Fable 5 rifiuta spesso le tool call?
I rifiuti si sono concentrati su attività specifiche: un’attività di correzione della configurazione è stata rifiutata in ogni esecuzione, mentre altre non lo sono mai state. Gli stessi risultati si sono ripetuti con e senza streaming. Non è quindi un evento casuale e raro che si possa superare con un semplice retry. I tassi varieranno in base al workload, ma la soluzione tecnica resta la stessa: controllare stop_reason prima di eseguire le tool call.
Posso disattivare il thinking di Fable 5?
No. Sia thinking.type.disabled sia enabled vengono rifiutati. Il thinking è adattivo per impostazione predefinita e output_config.effort è l’unico controllo disponibile. Nel nostro loop, l’effort low non ha ridotto il costo.
Fable 5 è mai l’opzione economica? Non in questo gruppo. Il sovrapprezzo più basso si osserva nei batch con cache calda e molto utilizzata: circa 5 volte sonnet-5, perché la cache assorbe gran parte del prompt. Nei loop e nella conversazione lunga è stato il modello più costoso tra quelli testati.
Verifica: tutti i dati sono stati misurati il 2026-07-05 su https://synthorai.io/ (/v1/messages nativo Anthropic per i modelli Claude, /v1/chat/completions per glm-5.2), per un totale di 505 episodi e 1,022 chiamate su cinque tipi di scenario, con tre esecuzioni per attività nei casi in cui la variabilità è rilevante. I costi corrispondono al valore usage.cost riportato dal gateway; sono indicate le mediane. Le attività sono volutamente semplici, quindi i tassi di successo servono come controllo di base, non come benchmark delle capacità; non pubblichiamo conclusioni sulle capacità che non abbiamo misurato. Il comportamento relativo ai rifiuti è stato riprodotto sia in modalità streaming sia senza streaming. I risultati possono variare in base a prompt, regione e carico.