cd /news/large-language-models/claude-fable-5-for-agents-tool-call-… · home topics large-language-models article
[ARTICLE · art-48983] src=dev.to ↗ pub= topic=large-language-models verified=true sentiment=↓ negative

Claude Fable 5 for Agents: Tool-Call Refusals, Cost vs GLM 5.2

Anthropic's Claude Fable 5 model refused mid-tool-call on 11 of 44 coding-agent turns in a Synthorai evaluation, on mundane tasks such as fixing a config default. The refusal truncates tool arguments mid-stream, but the partial JSON remains parseable, causing agent loops that execute tool calls without checking the stop reason to write half-finished files and corrupt state. The issue is not content-dependent but triggered by multi-turn tool-executing scenarios, and the fix is to check stop_reason before executing tool calls.

read9 min views1 publishedJul 7, 2026

Claude Fable 5 refused mid-tool-call on 11 of 44 coding-agent turns in our eval, on tasks as mundane as fixing a config default. The refusal arrives as stop_reason: "refusal"

partway through generating the tool arguments, the truncated arguments still parse as valid JSON, and an agent loop that executes tool calls without checking the stop reason will happily write a half-finished file to disk. That behavior, not the price tag, is the first thing to engineer around when you put Fable 5 in an agent.

TL;DR

stop_reason: "refusal"

mid-tool-call on mundane agent tasks (a config-default fix, a meeting-room booking); the truncated write_file

arguments still parsed, so a loop that doesn't check the stop reason executes half-written files.enabled

and disabled

are both rejected; the control is output_config.effort

.Everything below was measured on 2026-07-05 through the Synthorai gateway with a small scenario harness: five agent workload shapes (a tool-using coding loop, RAG question answering, tool-heavy orchestration, batch classification, and a 15-turn conversation), run against claude-fable-5

, claude-opus-4-8

, claude-sonnet-5

, and glm-5.2

, three runs per task where variance matters. The tasks are deliberately trivial; pass rates are a sanity gate, not a capability benchmark. Costs are the gateway's billed usage.cost

.

This is the failure the docs don't warn you about, and it corrupts state. The agent reads app.py

, decides to write the fix, and starts emitting a write_file

call. Partway through the file content, the stream stops:

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

The input

object is complete, parseable JSON. Nothing about it says "I stopped early." If your loop's contract is "got tool calls, run them," you just overwrote app.py

with a 38-character fragment that ends mid-dictionary and no longer parses as Python, and the next turn is a refusal too, so the loop ends with the workspace corrupted.

Three things we can say from the data:

KeyError

in a config lookup, implementing a slugify function, booking a meeting room, and creating a draft invoice. Nothing dual-use, nothing sensitive.stop_reason: "refusal"

with empty output. Retrying within the same context did not recover.The trigger is not the task content, and the data is blunt about it. The task that refused every run was a nine-line KeyError

fix in a config dictionary, no credentials, no exploits. Meanwhile the batch scenario classified support tickets about cryptomining, leaked Stripe keys, and phishing pages without a single refusal, and the RAG scenario answered over docs full of AES-256-GCM secrets and breach-response procedures, also clean. Every refusal landed in the two multi-turn, tool-executing scenarios; the three single-shot scenarios never refused once, even carrying heavier content. The pattern is the agent-loop shape, not the words, which means sanitizing your inputs won't prevent it.

The fix is one line before your tool-execution step:

if response.stop_reason == "refusal":
    raise AgentInterrupted("model refused; restart episode or escalate")

Anthropic documents the mechanics: a refusal that fires before any output returns an empty content

array and is not billed; a mid-stream refusal bills the already-streamed output, and the guidance is to discard the partial. The response also carries a stop_details

object with a category (such as cyber

or bio

, or null) so you can tell classifier blocks from ordinary declines. What the documentation doesn't spell out is the interaction with tool use we hit above: the refusal can land inside argument generation, and the partial arguments are indistinguishable from complete ones.

There is also an official recovery path. On the Claude API, the beta fallbacks

parameter (betas: ["server-side-fallback-2026-06-01"]

, fallbacks: [{"model": "claude-opus-4-8"}]

) re-runs a declined request on a fallback model inside the same call, with the decline itself unbilled when it fired pre-output. It is not available on Amazon Bedrock, Vertex AI, or Microsoft Foundry, where the SDKs ship a client-side fallback middleware instead. Whichever path applies, the guard above still comes first: never execute tool calls from a turn whose stop reason is a refusal.

Median cost per completed unit (task, query, item, or conversation), same prompts, same day:

Scenario fable-5 opus-4-8 sonnet-5 glm-5.2
Coding loop (per task, 4 turns median) $0.045 $0.012 $0.0059 $0.0031
RAG answer (per query) $0.024 $0.0075 $0.0036 $0.0031
Tool orchestration (per task) $0.048 $0.011 $0.0045 $0.0027
Batch classification (per item, warm) $0.0024 $0.0012 $0.00046
$0.00057
15-turn conversation (whole) $0.94 $0.34 $0.26 $0.083

Two readings of that table matter more than any single cell:

The rest of the cost picture is about controlling those numbers, and then about two things that quietly push them back up.

Caching is the single biggest lever, and on Fable 5 its contract is unchanged. The agent data shows what it is worth: with cache_control

markers removed, the same coding task cost 2.0x more, and warm batch items 6.8x more. On opus-4-8 the same ablation reads 3.8x and 6.9x. In a loop, the sliding-marker pattern is not an optimization, it is the difference between a viable bill and not.

Prompt order is the second lever, and it held up across every model we ran. Putting stable rules before per-query context (instead of after it) made RAG queries 26-37% cheaper on all four models; on the Claude line, the wrong order additionally pays the 1.25x cache-write premium on every call. The mechanics are in the LangChain caching post; the numbers here just confirm they apply unchanged to Fable 5.

Fable 5 also adds two levers of its own. The first is that the cache-eligibility floor dropped to 2,048 tokens, half of Opus 4.8's 4,096. That reads like trivia until you remember where an agent's savings come from: the repeated scaffold (system prompt, tool definitions, the sliding conversation prefix) is what caches, and only if it clears the floor. A tool-heavy agent whose per-turn prefix sat between 2,048 and 4,096 tokens got no caching at all on Opus 4.8, and starts caching on Fable 5, turning a full-price prefix into a roughly 10%-of-price cache read on every subsequent turn. It cuts the other way too: a prefix padded to clear the old 4,096 floor may now be carrying dead weight. Read cache_read_input_tokens

off a live response rather than assuming, because on Fable 5 the discount begins earlier.

The second is task budgets (beta, header task-budgets-2026-03-13

), which address the exact problem this comparison keeps surfacing: a Fable 5 loop runs up a bill fast, and max_tokens

does not help. It is a hard per-response cap the model cannot see, so the model plans as if it has unlimited room, then gets cut off mid-thought. A task budget is different. You give the loop a token ceiling (minimum 20,000) that the model sees as a running countdown and paces itself against, wrapping up gracefully instead of being truncated. It counts what the model generates plus the tool results it reads on the turn, not the full history you resend each request. On a model whose coding-loop turn costs 15x glm-5.2, a budget the model self-moderates toward is the cheapest guardrail you can bolt on.

With the levers set, two smaller things still moved our bill in directions the documentation doesn't warn you about.

"Low" effort was not cheaper. Fable 5's thinking depth is controlled by output_config.effort

, and the intuition is that low

costs less. It didn't. Setting effort: "low"

ran our coding loop at $0.0478 per task versus $0.0451 at the default, with more output tokens, not fewer. We saw the same pattern on GLM 5.2, where the effort names don't track token counts either. On both model lines, measure the knob on your own workload before assuming "low" means "less." One reason the number is hard to predict: adaptive thinking's share of output tokens swung from 2% on the coding loop to 30% on RAG answers to 52% on batch classification, same model, same day. Budget output tokens per workload shape, not per model.

Never replay reasoning_content. On OpenAI-compatible models, the reasoning field is not conversation history. DeepSeek's API requires stripping it; on

Fable 5 shares most of its request surface with Opus 4.7/4.8 and Sonnet 5. What's gone, per the docs:

thinking: {type: "enabled", budget_tokens: N}

returns a 400. thinking: {type: "disabled"}

returns a 400, and this one is unique to Fable 5. Opus 4.7/4.8 and Sonnet 5 still let you switch thinking off; Fable 5 does not.temperature

, top_p

, and top_k

are rejected at any non-default value.assistant

turn) return a 400.The temperature

/top_p

/top_k

and prefill removals are the two that most often bite a ported request; the thinking and retention changes are covered above and in the retention post.

Fable 5 in an agent is an engineering problem before it is a budget problem. Handle stop_reason: "refusal"

before executing tool calls, or a truncated write will corrupt state on a task as boring as a config fix. Then treat the cost as something you shape: caching is the biggest lever, the eligibility floor is now 2,048 tokens so re-check your prefix, a task budget keeps a loop from running up the highest per-turn bill in this comparison, and effort: "low"

is not the discount its name implies. Budget by workload shape, too: the same model is 15x the cost of glm-5.2 on a coding loop and 5x sonnet-5 on warm batch work. None of this says use it or don't; it says the defaults are not neutral, and the bill and the failure modes both depend on how your agent is shaped.

Does Fable 5 refuse tool calls often?

It concentrated on specific tasks: one config-fix task refused on every run, others never did, and the same tasks reproduced under both streaming and non-streaming calls. So it is not a rare flake you can retry past. Rates on your workload will differ; the engineering answer is the same either way: check stop_reason

before executing tool calls.

Can I turn Fable 5's thinking off?

No. thinking.type.disabled

and enabled

are both rejected. Thinking is adaptive by default and output_config.effort

is the only control; in our loop, low

effort did not reduce cost.

Is Fable 5 ever the cheap option?

Not in this set. Its smallest premium is on warm cache-heavy batch work, about 5x sonnet-5, where a warm cache absorbs most of the prompt. On the loops and the long conversation it is the most expensive model we ran.

Verification: all figures measured 2026-07-05 against https://synthorai.io/ (Anthropic-native /v1/messages for the Claude line, /v1/chat/completions for glm-5.2), 505 episodes and 1,022 calls across five scenario shapes, three runs per task where variance matters. Costs are the gateway-reported usage.cost; medians shown. Tasks are deliberately simple, so pass rates are a sanity gate, not a capability benchmark; we don't publish capability claims we haven't measured. Refusal behavior reproduced in both streaming and non-streaming modes. Your numbers will vary with prompts, region, and load.

── more in #large-language-models 4 stories · sorted by recency
── more on @anthropic 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/claude-fable-5-for-a…] indexed:0 read:9min 2026-07-07 ·