The breaking change
If you wrote any cost control around extended thinking in the last year, you probably reached for budget_tokens. It was the obvious knob: cap how much the model was allowed to think, cap the cost.
It no longer works. Anthropic’s current documentation states it plainly: “On Claude 4.7 and later models, setting budget_tokens returns a 400 error. Prefer lowering the effort setting or using max_tokens.”
Not deprecated-with-a-warning. A 400. So this is a real migration with a real failure mode, and it will not show up until a request actually runs.
Find every use first
Search this repository for every use of budget_tokens.
Include code, config files, environment files, notebooks and documentation.
For each hit, show the file, the line, and the model that call targets.
Do not change anything yet.Check the boring places as well as the code: environment files, deployment configs, notebooks, the internal wiki page someone will copy from next month.
The replacement
# Before - returns a 400 error on Claude 4.7 and later
thinking = { "type": "enabled", "budget_tokens": 4000 }
# After - cap the work with effort, cap the output with max_tokens
effort = "medium"
max_tokens = 2000The two replacements are not interchangeable, and choosing correctly is the whole job:
- effort governs how hard the model works on the problem. Lower it when the task is routine and the extra reasoning is not buying you anything.
- max_tokens caps what comes back. Use it when the risk is a runaway response rather than runaway reasoning.
Most budget_tokens uses I have seen were reaching for the first and settling for a proxy. Adaptive thinking now handles the allocation for you; effort tells it how ambitious to be.
The thing budget_tokens was actually solving
Worth being honest about the underlying problem, because the migration does not fix it by itself. People capped the thinking budget because the model overthinks: it explores three approaches, compares them, changes its mind, and you pay for all of it in tokens and in latency.
The same documentation gives two remedies for that. One is lowering effort. The other is a prompt that tells the model to commit:
Commit to one approach before you start.
State the approach in a single sentence, then implement it.
Do not enumerate alternatives, do not compare options, do not revisit the decision mid-task.
If the approach fails, stop and tell me why. Do not silently try a second one.“Do not revisit the decision mid-task” is the line that does the work. Wandering is what made the thinking expensive, not thinking itself.
The migration in order
- Find every
budget_tokensreference, including config and docs. - For each one, decide what it was protecting against: expensive reasoning, or a long answer.
- Replace with
effortfor the first,max_tokensfor the second. Some calls want both. - Add the commit-to-an-approach instruction to the prompts where overthinking was the real complaint.
- Run one live call per changed path. A 400 is not something a unit test with a mocked client will catch.
The lesson underneath
The old knob controlled a mechanism. The new controls describe an intent — work this hard, answer at most this long — and let the platform decide the mechanism. That is the direction of travel across the whole API surface, and it is the right one, because the mechanism keeps changing and your intent does not.
Which is also the argument for writing your standing instructions as intent rather than as procedure. But that is a different post.
Sources
From idea to operation
Make the next AI decision concrete.
NavAIgate helps leadership teams identify high-value AI opportunities, prove them safely and turn the winners into working systems.
