Skip to content
← all articles
Daniel Dewhurst15 min read

Migrating to Claude Opus 5.5: a cheat sheet for the API and Claude Code

Effort defaults, the four breaking changes, silent progress updates, and the prompt and CLAUDE.md lines worth changing when you move from Opus 5 to 5.5.

Anthropic released Claude Opus 5.5 today. It costs $4 per million input tokens and $20 per million output, down from $5 and $25 on Opus 5. Cache reads drop to $0.20 per million. Anthropic says it generates output more than 30% faster than Opus 5 and usually finishes the same task in fewer tokens.

The prompting guide says existing Opus 5 prompts “should perform well without changes”, and for the prose of your prompts that’s mostly true. The trouble is in the defaults and the shape of the response. Some requests now return a 400. A few things fail without any error at all: an agent UI that goes quiet, a Claude Code effort setting that stops applying, a reply cut off by a max_tokens value that used to be plenty.

This is the reference I wanted while reading the docs. Skim the table, then jump to whichever section matches what broke.

The cheat sheet

Opus 5Opus 5.5
Model IDclaude-opus-5claude-opus-5-5
Price (in / out, per M tokens)$5 / $25$4 / $20
Cache read$0.50$0.20
Default efforthighmedium
Thinkingcould be disabled at high or belowalways on; disabled and enabled return 400
tool_choice any / toolsupported400; use auto or none
Text between tool callstext blocksthinking blocks, empty by default
Computer use (Claude API, Google Cloud)computer_20251124 or computer_toolset_20260801computer_toolset_20260801 only
Refusal categoriesno bio classifieradds bio; docs list reasoning_extraction as new
Context / max output1M / 128K1M / 128K

The rest of the post explains the rows that cause trouble.

Effort is the only dial now

On Opus 5.5 thinking is always on, and output_config.effort decides how much of it happens. The levels are low, medium, high, xhigh and max. The default is now medium; every other model that supports effort defaults to high.

Level names don’t mean the same thing across models. The prompting guide says that in Anthropic’s testing Opus 5.5 at medium matches or beats Opus 5 at high on coding and knowledge-work evals, and on several coding evals low comes close. At a given level, 5.5 also thinks more per turn than Opus 5 did, especially at xhigh and max. If you carry your Opus 5 setting across unchanged, expect longer turns and bigger bills.

typescript
const response = await client.messages.create({
  model: "claude-opus-5-5",
  max_tokens: 4096,
  messages: [{ role: "user", content: "Analyze the trade-offs between microservices and monolithic architectures" }],
  output_config: { effort: "medium" },
});

Three adjustments from the guide:

  • Raise max_tokens. Thinking counts towards it even when you never see the thinking text. A limit sized for Opus 5 with thinking off can cut replies short. For long agentic coding turns, Anthropic found 128,000 (the model’s maximum) worked well. The SDKs want streaming at values that large.
  • Keep xhigh and max for work where you’ve measured a gain.
  • To get less thinking, lower effort rather than adding prompt instructions. It’s more reliable.

The early Hacker News reports line up with this. Simon Willison ran his pelican SVG test at max and it ran out of the 128,000-token budget while still reasoning. The failed attempt cost him $2.56. Commenters who mentioned effort mostly used medium or high, and one in a related thread put it as “High is the highest I go.”

If you need a different level for one turn, don’t change the top-level effort: that invalidates the prompt cache. The per-message effort beta (mid-conversation-output-config-2026-07-01) lets you drop an effort-only system message into the conversation, which takes effect from the next user turn and keeps the cache:

{ "role": "system", "content": [], "output_config": { "effort": "low" } }

The four breaking API changes

The migration guide lists four. If you use Claude Code, /claude-api migrate this project to claude-opus-5-5 will apply them to your codebase.

1. Thinking can’t be disabled

Both thinking: { type: "disabled" } and { type: "enabled", budget_tokens: N } now return a 400:

"thinking.type.disabled" is not supported for this model. Use "thinking.type.adaptive" and "output_config.effort" to control thinking behavior.

Remove the thinking field or send { type: "adaptive" }, which means the same thing. If your Opus 5 integration ran with thinking disabled for latency, the guide suggests starting at low and measuring. If time to first token still matters after that, a system prompt line such as “Answer directly without deliberating.” cuts thinking further, at some risk to quality.

A response may or may not open with a thinking block now, so select blocks by type rather than taking content[0]. Pass thinking blocks back unmodified.

2. Forced tool use is gone

tool_choice with type any or tool returns a 400, including on the token-counting endpoint. auto and none still work. The documented replacement is strict tools with auto, plus a line in the prompt saying when the tool applies:

python
tools = [{**tool, "strict": True} for tool in tools]
tool_choice = {"type": "auto"}

Structured outputs are the other option if you were forcing a tool just to get JSON.

3. Thinking blocks are tied to the model and the conversation

Opus 5.5 reads thinking blocks from Opus 5 and earlier Opus, Sonnet and Haiku models, but not from Fable or Mythos. A block the target model can’t read is dropped silently and not billed.

The sharper edge is for accounts created on or after 31 August 2026. Replaying a thinking block after editing system, tools or an earlier message returns a 400 by default. Integrations that only ever append are fine. If you edit history, the thinking-binding-controls-2026-08-01 beta lets you set thinking.block_binding.prefix_mismatch_behavior to "drop_block" instead of "error".

This matters for later sections too. Several of the guide’s suggestions (a standing instruction, a message tool) come with the warning to add them from the first request, because adding them mid-session changes the prefix.

4. The computer-use tool changed

On the Claude API and Google Cloud, computer_20251124 is rejected. Drop the computer-use-2025-11-24 beta and send { "type": "computer_toolset_20260801" } with no name or display size. Your loop then has to read the action from each tool_use block’s name rather than input.action, handle several per turn, and echo toolset_name on every result. Bedrock keeps the old tool.

Why your agent UI went quiet

This one produces no error, which makes it the easiest to miss.

On Opus 5, the short notes the model wrote between tool calls (“found the bug, editing auth.py”) came back as text blocks. On 5.5 they come back as progress-update thinking blocks, at most one before each tool call. At the default display: "omitted", their text is empty. A client that renders only text blocks shows nothing for the whole of a long agentic turn.

The fix is display: "updates", a beta behind the thinking-display-updates-2026-08-18 header. Reasoning blocks stay empty, and only progress updates carry text:

typescript
const stream = client.beta.messages.stream({
  model: "claude-opus-5-5",
  max_tokens: 128000,
  thinking: { type: "adaptive", display: "updates" },
  output_config: { effort: "medium" },
  betas: ["thinking-display-updates-2026-08-18"],
  messages: [{ role: "user", content: "Review the PRs open against our billing service." }],
});
const message = await stream.finalMessage();

No field marks a block as a progress update. Under "updates", any thinking block with non-empty text is one, so the rendering rule is short:

typescript
for (const block of message.content) {
  if (block.type === "thinking" && block.thinking) {
    showStatus(block.thinking); // progress update
  } else if (block.type === "text") {
    showReply(block.text);
  }
}

"summarized" also works, but then you can’t tell progress updates from reasoning summaries. When streaming, a pause of several seconds before a progress-update block opens is normal.

If turns still go quiet for too long, the guide suggests having the harness count consecutive tool-calling steps that give the user nothing to read. After five or so, append this as a turn-scoped system message (clear_at: "next_user_message", beta header mid-conversation-system-clear-at-2026-08-21):

The user hasn't heard from you in a while — say in a few words what you're doing, then continue.

Stop after two or three reminders. Because the message is appended and left in place, the cache still matches. Anthropic says this roughly halved the share of agentic coding tasks with a long silent stretch, with no measurable change in cost.

Unattended runs that stop early

The other side of those progress updates: on long tasks, some of them end the turn with text and no tool call (stop_reason: "end_turn"). An agent loop that reads end_turn as “task finished” stops there.

The guide’s harness advice:

  • Treat a text-only end of turn as a report, not proof the work is done.
  • Keep the task’s parts in a checklist the model updates, as a to-do tool or a file.
  • If a turn ends with open items and no blocker stated, send a short user message naming them.
  • Stop after two or three automatic continuations, so a genuinely stuck run ends and someone can look at it.
  • If a background command or subagent is still running, wait for it and return its output before treating the task as done.

The continuation message can be this plain:

Your task list still has open items: migrate the remaining two endpoints and update their tests. Continue with them. If one is blocked, say what is blocking it.

The guide also offers a long standing-instruction paragraph for fully unattended agents. It names four ways the model ends a turn while work is still owed: a summary that announces the next step instead of taking it, an offer to continue “unless you’d prefer otherwise”, a list of decisions that don’t actually block anything, and deciding a milestone is a good place to report. It tells the model to put status notes in the same message as its next tool call. It’s worth reading in full on the guide itself. Two caveats come with it. Add it from the first request, and leave it out of anything with a human in the loop, where stopping to check in is the point.

Claude Code specifics

Opus 5.5 needs Claude Code v2.1.280 or later, which also makes it the default Opus model. The opus alias resolves to it everywhere except Microsoft Foundry. It runs at medium unless you say otherwise.

You can set effort in several places. The first match wins:

  1. CLAUDE_CODE_EFFORT_LEVEL, --effort <level> at launch, or /effort in the session
  2. Settings: a per-model level under modelSettings beats a top-level effortLevel in the same file, and across files the usual settings precedence applies, so managed settings win
  3. The model’s default (medium on Opus 5.5)

/effort high sets a level directly, /effort alone opens a slider, and /effort auto clears the saved level for the current model. Skills and subagents can set effort in their frontmatter.

The trap is in step 2. A top-level effortLevel in ~/.claude/settings.json is ignored by Opus 5.5. It’s the older form /effort wrote before levels were saved per model, and it keeps applying to Opus 5 and earlier. If you set xhigh there months ago and forgot, you’re now on medium without being told. To pin a level for 5.5 in settings:

json
{
  "modelSettings": {
    "claude-opus-5-5": {
      "effortLevel": "high"
    }
  }
}

A top-level effortLevel in project, local or managed settings still applies to every model.

Thinking can’t be turned off in Claude Code either. alwaysThinkingEnabled, the Option+T (Alt+T) toggle and MAX_THINKING_TOKENS=0 do nothing on 5.5.

What to change in CLAUDE.md and system prompts

Anthropic hasn’t published CLAUDE.md guidance specific to 5.5. Most of the prompting guide carries over, though, since CLAUDE.md is just prompt text that gets loaded every session.

Delete “think carefully” lines. The guide recommends removing instructions that tell Claude to think before answering. Effort controls that now, and in Anthropic’s chat testing, removing such a line made replies start sooner with no clear loss of quality.

Reword anything that asks for visible reasoning. Opus 5.5 has a reasoning_extraction classifier, and prompts that push the model to reproduce its internal reasoning in the response can be declined outright. Server-side fallback won’t retry those. Prompt wording can trip it by accident. The day before 5.5 launched, the locus project was already hitting reasoning_extraction flags on Opus 5 from lines such as “do NOT hide reasoning in internal thinking blocks” and “retrace your reasoning”. The fix was rewording: “traceable reasoning”, for example, became “traceable working”. If you want the reasoning, set display: "summarized" and read it from the thinking blocks.

Say when to keep going and when to stop. The unattended-run advice shrinks to a couple of lines for an interactive agent, for example:

markdown
When a step doesn't need my input, keep going. Put status notes in the same message as your next action.
Stop and ask only when you can't continue without me, or before anything destructive.

Mark pasted text. Opus 5.5 resists prompt injection from tool results and web pages better than any earlier Opus model, and it can do the same for text a user pastes into a message, if it can tell which text was pasted. Wrap each pasted block in tags carrying a random ID your app generates:

<pasted_content id="ab12">
...text the user pasted...
</pasted_content id="ab12">

Then add the guide’s note to the system prompt, telling the model to follow instructions inside those tags only where the user’s own message asks it to. Claude Code already does something similar for large pastes. The tags are plain text and can be imitated, so treat them as one guardrail among several.

Name the frontend patterns you don’t want. Asked for a website with no design direction, 5.5 falls back on a few default styles. “Avoid a generic AI look” mostly swaps one default for another. What works is a concrete list, and the guide’s example list is specific:

Do not use a cream or off-white background, italic accent words in headlines, numbered "01/02/03" section labels, monospace labels, or pill-shaped buttons.

Reading that, I recognised my own site. This blog runs on a #fafafa background, small monospace labels for every date and section, and pill-shaped tag chips. I chose all three deliberately, but it’s a useful reminder that one person’s design system is a model’s default. If you do want something the model reaches for by habit, write that down too, so it’s a decision rather than an accident.

Consider telling it not to relitigate. In multi-turn chat, 5.5 sometimes re-examines an earlier answer while thinking about a short follow-up. The guide’s fix is two sentences telling it to treat earlier answers as settled unless asked. Leave that out of agentic coding, where a later step often reveals an earlier mistake.

Smaller things worth knowing

Time budgets for multi-agent runs. Opus 5.5 pays attention to elapsed time. If a lead agent delegates to subagents, have the harness append something like elapsed 340s / 1200s to each message. The model paces itself and usually finishes early, mostly by keeping more agents working in parallel. The budget is advisory, so keep your own hard timeout.

Visual inputs. 5.5 reads charts, diagrams and screenshots much more accurately without tools. Anthropic says that even at its lowest effort it read dense charts better than Opus 5 at its highest. Re-test any scaffolding you built for earlier models. For technical drawings and the densest inputs, higher-resolution images and a cropping tool still help. The cookbook recipe defines one, called zoom.

Refusals. Classifier declines arrive as HTTP 200 with stop_reason: "refusal" and a stop_details object naming the category: cyber, bio, frontier_llm, reasoning_extraction, general_harms, or null. Branch on stop_reason. The biology safeguards are new if you’re coming from Opus 5, and they’re a common complaint in the launch thread so far, from people in bioinformatics and medicine. Embedded, driver and systems-level developers are reporting cyber flags too. If that’s your work, set up fallback before you switch, or keep those workloads where they are for now.

Cost. Early numbers are mixed. One HN commenter reported per-task cost falling from $0.35 to $0.16 at low; others saw roughly the same cost as Opus 5. CodeRabbit’s review saw token use 41–60% above their production baseline and advised checking whether the lower prices translate into lower bills. Measure on your own traffic before you promise anyone a saving.

Migration checklist

  1. Change the model ID to claude-opus-5-5.
  2. Remove thinking: { type: "disabled" } and budget_tokens; control depth with output_config.effort.
  3. Set effort explicitly and run a sweep on your own evals, starting at medium (or low if you ran with thinking off).
  4. Raise max_tokens; 128,000 for long agentic turns, with streaming.
  5. Replace tool_choice any / tool with strict tools and auto.
  6. Read response blocks by type, and pass thinking blocks back untouched.
  7. If you edit conversation history, decide how to handle thinking-block binding.
  8. Set display: "updates" if your UI shows progress between tool calls.
  9. Make your agent loop treat a text-only end_turn as a report and check the task list.
  10. Update the computer-use tool if you use it on the Claude API or Google Cloud.
  11. Handle stop_reason: "refusal", and configure fallback if bio or cyber work is in scope.
  12. In Claude Code, upgrade to v2.1.280+, and move any user-level effortLevel into modelSettings.
  13. Delete “think carefully” instructions and reword requests for visible reasoning.
  14. Add keep-going and stop-only-when-blocked lines to CLAUDE.md or your system prompt.

Most of this is an afternoon’s work. The part that needs more care is the effort sweep, because the numbers from Opus 5 won’t tell you anything about 5.5.