Models and effort
Models and effort are the two dials on a Claude Code session: which model answers, and how hard it thinks before it does.
Most people never touch either, and the default is a reasonable place to leave them. This lesson exists so that when a session is going badly you know there is something to change, and so you know what the change costs.
The models
Pick one with /model in a session, or --model at launch. You can use an alias rather
than a version number:
opus- the latest Opus. Complex reasoning.sonnet- the latest Sonnet. Daily coding work.haiku- fast and cheap. Simple, mechanical tasks.fable- Fable 5, for work larger than a single sitting.best- Fable 5 where your organisation has it, otherwise the latest Opus.opusplan- Opus while planning, then Sonnet to do the work.default- clears any override and goes back to your account’s default.
The aliases move as new versions ship, which is what you want most of the time and not what
you want when you are trying to reproduce something. Name the version explicitly for that:
--model claude-opus-5.
opusplan deserves a second look, because it matches how lesson 14 said to work. The
expensive model decides what to do, which is where thinking pays, and the cheaper one
carries it out, which is where thinking mostly does not.
What does the effort level change?
Effort controls how much the model reasons before answering. Set it with /effort, or
--effort at launch:
low, medium, high, xhigh, max. The default is high on every model that supports
it.
The scale is calibrated per model, so high on Haiku and high on Opus are not the same
amount of thinking. And max is not the best one by definition: the documentation’s own
wording is that it “may show diminishing returns and is prone to overthinking”. That matches
experience. A model at max on a two-line fix will find three architectural concerns you
did not ask about.
One more, for a single turn rather than a session: put the word ultrathink anywhere in
your prompt and Claude Code adds an instruction asking for deeper reasoning on that turn
only. Other phrasings people try, like “think hard” or “think step by step”, are passed
through as ordinary text and do nothing.
What the difference looks like
Numbers from one run, in a stockroom clone, both asked the same open question:
Read src/domain/stock.ts and src/domain/movements.ts carefully. Is there a bug in how
stock is valued? Be specific and name the function.
| Model | Cost | Time | Turns | Answer |
|---|---|---|---|---|
| Haiku | $0.0475 | 45s | 3 | Confident, specific, wrong |
| Opus 5 | $1.0209 | 181s | 22 | Correct, and worse than I knew |
Twenty-one times the money and four times the wait. That is the honest headline, and if the answers had been equally good it would be an easy argument for Haiku.
They were not. Haiku said unitCost could be undefined and produce NaN in the
valuation. It named a function, quoted a line, and explained the mechanism. It is also not
true: record() defaults unitCost to the item’s cost, so it is never undefined. A
plausible, specific, checkable-and-false answer, delivered in the same tone as a correct
one.
Opus read further and found something worse than the bug I knew about. MovementKind
includes adjustment, but record() only negates a pick and rejects any quantity of
zero or less. So a downward adjustment, which is how you write off damaged stock, cannot be
expressed at all: write off ten units and you get a positive ten. It then lands in
averageCost’s receipt branch, because that branch tests the sign rather than the kind,
and gets valued at the item’s list cost. Damaged stock increases the valuation.
That bug is real and it was not planted. It took 22 turns of reading to find.
Do not take this table as a benchmark. It is one question on one repository on one day, and a rerun will give different numbers and possibly different answers. What is stable is the shape: the cheap model answers quickly and sometimes wrongly in a way you cannot detect without checking, and the expensive model reads more before it commits.
Choosing, in practice
Haiku for work where you would recognise a wrong answer instantly. Renaming things, mechanical edits, formatting, “what does this file do”, running a command and reporting output.
Sonnet for the ordinary day. Most changes with a clear shape.
Opus or Fable when you do not know the answer yourself. Debugging something strange, a change across many files, anything where a confident wrong answer would cost you an afternoon. That is the real rule: spend the money in proportion to how hard the mistake would be to catch.
Effort moves in the same direction for less. Before reaching for a bigger model, try
/effort xhigh on the one you have.
The failure worth naming: running everything at the maximum of both dials because it feels safer. It is slower, it costs more, and on simple work it produces more to review, which is your time rather than the machine’s.
Switching mid-session
Both dials change without restarting. /model sonnet and /effort medium take effect from
your next message and the conversation carries on.
The move that works: plan on the expensive setting, execute on the cheap one. Once the plan is agreed and the file list is known, the remaining work is mostly typing.
The move that does not work: switching models to escape a session that has gone wrong. If
the context contains four failed attempts, a better model inherits four failed attempts.
/clear first, then switch. Lesson 16.
Your turn
Ask the same question at two settings and measure both, in a stockroom clone.
Q="Read src/domain/stock.ts and src/domain/movements.ts carefully. Is there a bug
in how stock is valued? Be specific and name the function."
claude -p --output-format json --model haiku "$Q" < /dev/null > /tmp/cheap.json
claude -p --output-format json --model opus "$Q" < /dev/null > /tmp/dear.json
Then read the cost, the time, and the answers:
python3 -c "
import json
for n in ('cheap','dear'):
d = json.load(open(f'/tmp/{n}.json'))
print(n, '\$%.4f' % d['total_cost_usd'], '%.0fs' % (d['duration_ms']/1000), d['num_turns'], 'turns')
print(d['result'][:400], '\n')
"
Check: both files contain a
total_cost_usdand aresult, the two costs differ by more than a factor of ten, and you can say in one sentence what each answer claimed. Then the real check, which no script can do for you: opensrc/domain/movements.tsand decide which of them is right. If you accept an answer here without opening the file, you have just demonstrated the failure this whole lesson is about.
Recap
Two dials. /model picks who answers, /effort picks how hard they think, and both change
mid-session. Aliases move with releases; name a version when you need to reproduce
something.
Spend in proportion to how hard the mistake would be to catch, not in proportion to how important the task feels. Cheap models fail by being confidently specific and wrong, which is the failure mode that gets past review.
opusplan for plan-then-execute, ultrathink for one deep turn, and /clear before you
switch away from a session that has gone wrong.
Next: deciding once what Claude may do without asking, and the short list of things that should always stop.