Skip to content
Subscribe

Think Mode (Extended Thinking)

Module 6.1: Think Mode (Extended Thinking)

Section titled “Module 6.1: Think Mode (Extended Thinking)”

Estimated time: ~30 minutes

Prerequisite: Module 5.3 (Image & Visual Context)

Outcome: After this module you will know extended thinking is already on, how to raise or lower it with effort levels, when to reach for ultrathink, and how to read the reasoning Claude Code hides.


Half the Claude Code advice online tells you to type “think step by step” or “think harder” to unlock a deeper mode. Those phrases do nothing: Claude Code “passes other phrases such as ‘think’, ‘think hard’, and ‘think more’ through as ordinary prompt text and doesn’t recognize them as keywords.”

So you paid for magic words while the real controls — the effort level and the ultrathink keyword — sat unused, and thinking was on all along. This module replaces the folklore with four switches that exist.


Extended thinking is on by default. There is no mode to enter. You control how much reasoning Claude spends (effort level, session-wide), whether one turn gets extra (ultrathink), whether it happens at all (Option+T), and whether you see it (Ctrl+O).

The effort level is the main dial. This is the old think-vs-act matrix, re-axed onto levels that exist:

The task is…Effort
”short, scoped, latency-sensitive… not intelligence-sensitive”low
cost-sensitive, “can trade off some intelligence”medium
everyday coding: “balances token usage and intelligence”high, the default
worth “deeper reasoning at higher token spend”xhigh
demanding, but “prone to overthinking” — “test before adopting broadly”max
big enough to orchestrate: “xhigh … plus dynamic workflows”ultracode

high is “the default on every model except Opus 4.7”, which defaults to xhigh.

ultrathink is the one keyword Claude Code recognizes, and it lasts a single turn: “Include ultrathink anywhere in your prompt to request deeper reasoning on that turn without changing your session effort setting… The effort level sent to the API is unchanged.”


All steps run in a lab repo holding src/math.js and one test file.

Step 1: Read the effort level you are on

Start claude and look above the prompt box.

# Output may vary
▐▛███▛█ Claude Code v2.1.278
▝▜██████▀ Opus 5 (1M context) · Claude Max
▝▝ ▝▝ ~/cc-lab
● high · /effort
────────────────────────────────────────────────────────────────────────────────────
❯

● high · /effort is your current level. You never turned thinking on — it already was on.

Step 2: Open the effort slider with /effort

Type /effort and press Enter.

# Output may vary
Effort
Faster Smarter
────────────────────▲──────────────────────┆──────────────────
low medium high xhigh max ultracode
xhigh + workflows
←/→ to adjust · Enter to confirm · s for this session only · Esc to cancel

The slider shows the levels this model has — Opus 4.6 and Sonnet 4.6 have no xhigh. /effort <level> sets one; /effort auto clears the saved level for that model.

Step 3: The on/off switch, Option+T

Press Option+T (macOS) or Alt+T (Windows/Linux).

# Output may vary
Toggle thinking mode
Enable or disable thinking for this session.
❯ 1. Enabled ✔ Claude will think before responding
2. Disabled Claude will respond without extended thinking
Enter to confirm · Esc to cancel

Enabled is already checked. /config saves it as alwaysThinkingEnabled in ~/.claude/settings.json.

Step 4: The one keyword that works

ultrathink: does the guard in divide() in src/math.js also reject -0? Answer in one sentence.
# Output may vary
❯ ultrathink: does the guard in divide() in src/math.js also reject -0? …
⏺ I'll read the file.
Thought for 2s, read 1 file
⏺ Yes — b === 0 is true for -0 as well (strict equality doesn't distinguish the two zeros,
unlike Object.is), so divide(1, -0) also throws instead of returning -Infinity.

Thought for 2s is all you get: “Claude Code collapses thinking output by default.”

Step 5: Expand the reasoning, Ctrl+O

Press Ctrl+O to toggle the transcript viewer.

# Output may vary
10:00 PM claude-opus-5
⏺ I'll read the file.
⏺ Read(/Users/luatnq/cc-lab/src/math.js)
⎿ Read 6 lines
∴ Since -0 equals 0 in the comparison, it correctly rejects -0 too.
────────────────────────────────────────────────────────────────────────────────────
Showing detailed transcript · ctrl+o to toggle · ? for shortcuts verbose

The ∴ line is the thinking summary. This capture used { "showThinkingSummaries": true } in .claude/settings.json, because “interactive sessions on the Anthropic API receive redacted thinking blocks by default.”

Step 6: Measure the difference, headlessly

Terminal window
# docs: cli-reference
claude --effort low -p "List the edge cases divide() in src/math.js does not handle." \
--output-format json --permission-mode default --allowedTools "Read"
claude --effort high -p "List the edge cases divide() in src/math.js does not handle." \
--output-format json --permission-mode default --allowedTools "Read"

Both runs are read-only, so --allowedTools "Read" is their whole permission budget. The two JSON objects, same prompt and repo: result 1,399 characters at low vs 2,494 at high; num_turns 2 vs 4; duration_ms 10,615 vs 40,056. Output may vary — one pair of runs on one machine. Compare length, turns and content, never a thinking-token count: Claude Code does not print one.


Goal: Confirm “think step by step” is ordinary prompt text and ultrathink is not.

Instructions:

  1. In a repo of yours, run claude and ask a question prefixed with think step by step:.
  2. Press Ctrl+O and note the reasoning.
  3. Ask the same question prefixed with ultrathink:. Press Ctrl+O again.
  4. Compare the two transcripts.

Expected result: Both turns think, because thinking is on by default. Only the ultrathink turn got an extra instruction.

💡 Hint Do not look for a “mode” indicator. Compare reasoning length in the transcript viewer — step 1’s phrase reached the model as plain text.

✅ Solution

The first prompt is like any other — Claude Code “passes other phrases such as ‘think’, ‘think hard’, and ‘think more’ through as ordinary prompt text.” The second is recognized: it “adds an in-context instruction. The effort level sent to the API is unchanged.” ultrathink buys a deeper turn; the folk phrases buy only tokens.

Goal: Pick the cheapest effort level that still solves a task you run.

Instructions:

  1. Choose a real, repeatable task (for example “summarize what changed in the last commit”).
  2. Run it with --effort low, --effort medium and --effort high, each with --output-format json, saving every result.
  3. Compare the result fields for correctness, not length.
  4. Pin the winner with /effort <level> or the effortLevel setting.

Expected result: A note saying which level you will use for this task class.

💡 Hint low is for work “not intelligence-sensitive”. If low gets the right answer, high is wasted spend.

✅ Solution

For mechanical tasks low often ties high, so pin it per model with modelSettings. The docs are specific: “set effortLevel to low, medium, high, or xhigh as the default for models without one. max isn’t accepted as a level in either key, and ultracode has its own ultracode key.” So max must come from /effort or --effort.


ControlWhereWhat it does
/effort · /effort autoSessionSlider (s = session only) · clear the saved level
/effort <level>, --effort <level>Session, CLIlow, medium, high, xhigh, max, ultracode
effortLevel, modelSettingssettings.jsonDefault, and per model: low–xhigh only
ultracodesettings.jsonIts own key — xhigh plus dynamic workflows
ultrathinkPromptDeeper reasoning, that turn only
Option+T / Alt+TSessionToggle extended thinking
alwaysThinkingEnabledsettings.jsonThinking off for every session
MAX_THINKING_TOKENS=0Env varThinking off on the Anthropic API
Ctrl+OSessionToggle the transcript viewer
showThinkingSummariessettings.jsonFull summaries instead of redacted blocks

Defaults: thinking on; effort high except Opus 4.7 (xhigh). Thinking cannot be turned off on Fable.


❌ Mistake✅ Correct Approach
”think step by step” to unlock a deeper modeThinking is already on. Raise /effort, or use ultrathink
Quoting a “thinking tokens: 2,768” figureClaude Code prints no such count. Compare length and turns
Assuming ultrathink raises your effort level”The effort level sent to the API is unchanged”
Running everything at maxmax “may show diminishing returns and is prone to overthinking”
"effortLevel": "max" in settings.json”max isn’t accepted as a level in either key”. Use /effort max or --effort max
Expecting Option+T to work on Fable”You can’t turn thinking off on Fable models”
Assuming collapsed reasoning is free”You are charged for all thinking tokens generated, even when collapsed”

Scenario: A Vietnam-based fintech team building payment reconciliation: VND amounts (no decimals), three banks with different API response formats (VietcomBank, Techcombank, MBBank), and State Bank of Vietnam (SBV) audit requirements.

Problem: They asked Claude Code to “implement payment reconciliation logic” at the default effort, in a session already holding two unrelated tasks. The result assumed USD-style minor units (amount * 100), one uniform bank response shape, and skipped the SBV state machine and audit trail. Five rounds of corrections followed, piling up in the same polluted context.

Solution: The team lead ran /clear, raised the session with /effort xhigh, and rewrote the prompt to carry the constraints the first attempt had to guess: VND is an integer currency, each bank has its own field names, SBV requires a state machine plus an audit trail, settlement windows differ per bank. The hardest sub-problem — mismatched settlement windows — got its own turn prefixed with ultrathink.

Result: Integer VND handling, a per-bank adapter layer, and an explicit state machine with audit events. The rule they wrote into CLAUDE.md was not “add think to your prompts” — it was: clear the context, put the constraints in the prompt, reach for effort and ultrathink deliberately.


Next: Module 6.2: Plan Mode →