Skip to content
Journal

AI Integration · Engineering

Reasoning Models: When to Use Them and How to Set Effort

Use reasoning models for multi-step code, math and planning, not lookups or chat. How effort and thinking levels work in Claude, OpenAI, Gemini and DeepSeek.

Anurag Verma

Anurag Verma

10 min read · Updated Oct 19, 2026

Thinking Models in 2026: The Adaptive Reasoning Revolution

Sponsored

Share

Every major model API now lets you choose how hard the model thinks before it answers. That turns “should we use a reasoning model?” into a different question: how much reasoning does this request deserve, and how do you set it on the API you’re using? This guide covers both, with current parameters for Anthropic, OpenAI, Google and DeepSeek.

Thinking models use chain-of-thought reasoning before producing a final answer Reasoning models spend extra output tokens working through a problem before they respond

When to use a reasoning model

Use high reasoning effort for tasks with several dependent steps: debugging, refactoring, multi-step plans, math, and ambiguous specs where the model has to weigh interpretations. Use low effort, or a small fast model, for lookups, formatting, tagging, extraction and anything a user waits on in real time. Then measure on your own traffic.

That rule holds across vendors because the cost structure is the same everywhere. Reasoning tokens are billed as output, they count against your output cap, and they add latency before the first visible token. The payoff only shows up when the task has real steps to reason through.

Where higher effort tends to pay off

  • Code tasks with hidden state: race conditions, deadlocks, off-by-one bugs, migrations with edge cases. Reasoning also cuts the back-and-forth of follow-up corrections, a theme in AI code review tools and workflows.
  • Multi-step planning for agents, where the model has to order tool calls and track dependencies. Anthropic’s effort docs recommend high effort for agentic tasks and complex coding, with xhigh for long-running work. Framework choice matters here too; see our comparison of LangGraph, CrewAI and AutoGen.
  • Math, proofs and constraint problems, where skipping a step produces a confident wrong answer.
  • Underspecified requests, where the model needs to notice the ambiguity before choosing an interpretation.
  • High-stakes analysis (security review, financial calculations). Reasoning doesn’t remove the need for checks, which is why systematic LLM evaluation matters more once you rely on it.

Where it usually doesn’t

  • Retrieval and formatting: “convert this JSON to YAML,” “what’s our refund window.”
  • High-volume classification, tagging and extraction. Run these at low effort or on the small tier of whichever family you use.
  • Latency-sensitive UI such as autocomplete and inline suggestions, the constraint that shapes agentic IDE design as much as raw model quality does.
  • Open-ended creative drafts, where extra deliberation often produces more structured, less natural prose. Test it rather than assuming.

A rule of thumb I keep coming back to: if a senior engineer would reach for scratch paper, raise the effort. If they’d answer off the top of their head, lower it.

How the controls work in each API

The parameter names differ, but the shape has converged: a named effort level per request, a hard output cap, and an optional summary of the reasoning.

Adaptive reasoning lets you balance quality against speed and cost Effort settings let you dial reasoning depth up or down per request

ProviderCurrent models (October 2026)Reasoning controlDefaultReasoning visibility
AnthropicClaude Opus 5.5, Sonnet 5.5, Haiku 5.5output_config.effort: low, medium, high, xhigh, maxmedium on Opus 5.5 and Haiku 5.5, high on most othersthinking.display: summarized or omitted
OpenAIGPT-6 Astra, GPT-6.1 Sol, GPT-6 Lunareasoning.effort: none, minimal, low, medium, high, xhigh, max (each model supports a subset)medium on GPT-6.1 Sol and the GPT-5.6 modelsreasoning.summary: auto
GoogleGemini 4 Argon, Gemini 3.8 Flash and other Gemini 3.x modelsthinking_level: low, medium, high (some models add minimal)medium on Gemini 4 Argon and 3.8 Flashthinking_summaries: auto or none
DeepSeekdeepseek-flash, deepseek-v4-proreasoning_effort: low, high, max; thinking on or off via thinking.typethinking on, effort highreasoning_content field

Two things in that table deserve a warning. First, defaults move between versions. Anthropic’s docs note that Claude Opus 5.5 defaults to medium where Opus 5 defaulted to high, so the same request without an effort setting runs one level lower after an upgrade. Second, not every level exists on every model. OpenAI’s docs say gpt-6-astra rejects none with a 400, and GPT-6.1 Sol supports neither none nor minimal. Check the model page before you hardcode a level.

Anthropic Claude: effort plus adaptive thinking

On current Claude models, thinking is adaptive: the model decides per request whether to think and how much, and effort steers that decision. Anthropic’s steering docs say plainly that you don’t set a thinking token budget. Effort is soft guidance and max_tokens is the hard cap on thinking plus answer. On Claude Opus 5.5, thinking can’t be turned off at all, so effort is the only lever.

import anthropic

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=16000,
    thinking={"type": "adaptive", "display": "summarized"},
    output_config={"effort": "high"},  # low | medium | high | xhigh | max
    messages=[{
        "role": "user",
        "content": "Find the race condition in this worker pool and explain the fix: ...",
    }],
)

for block in response.content:
    if block.type == "thinking":
        print("Reasoning summary:", block.thinking)
    elif block.type == "text":
        print("Answer:", block.text)

# Billed reasoning tokens, separate from the visible answer
print(response.usage.output_tokens_details.thinking_tokens)

display: "summarized" matters if you stream reasoning to users. With "omitted", thinking blocks arrive with empty text, which looks like a long pause before output. Billing is the same either way. The effort docs also list per-model starting points: xhigh for coding and agentic work on Opus 4.7 and 4.8, medium for well-specified agentic coding on Sonnet 5.5, and medium or low for chat and latency-sensitive work.

OpenAI: reasoning.effort in the Responses API

OpenAI’s reasoning guide says reasoning models work better with the Responses API than with Chat Completions, and recommends starting with gpt-6-astra for most reasoning workloads, gpt-5.6-terra for lower cost, and gpt-5.6-luna for the lowest cost and latency.

from openai import OpenAI

client = OpenAI()

response = client.responses.create(
    model="gpt-6-astra",
    reasoning={"effort": "low", "summary": "auto"},
    input=[{
        "role": "user",
        "content": "Write a bash script that prints the transpose of a matrix given as '[1,2],[3,4],[5,6]'.",
    }],
)

print(response.output_text)
print(response.usage)  # includes the reasoning token count

Summaries come back in the summary array of the reasoning output item, and only when you opt in. If generation hits max_output_tokens or the context limit, the response returns with status: "incomplete", possibly before any visible output. OpenAI recommends reserving at least 25,000 tokens for reasoning and output while you experiment.

Google Gemini: thinking_level

The Gemini thinking docs now use thinking_level across the Gemini 3.x and 4 models, through the Interactions API:

from google import genai

client = genai.Client()

interaction = client.interactions.create(
    model="gemini-3.8-flash",
    input="Provide a list of 3 famous physicists and their key contributions",
    generation_config={
        "thinking_level": "low",
        "thinking_summaries": "auto",
    },
)

print(interaction.output_text)
print("Thoughts tokens:", interaction.usage.total_thought_tokens)

Defaults vary by model. Gemini 4 Argon and Gemini 3.8 Flash default to medium, gemini-3.1-pro-preview defaults to high, and Gemini 2.5 Flash-Lite has thinking off by default. Only some models accept minimal. If you have older code using a numeric thinking_budget, check it against the current docs, which no longer document that parameter.

DeepSeek: thinking on by default

DeepSeek’s thinking mode docs describe thinking as on by default with effort at high, through an OpenAI-compatible API:

from openai import OpenAI

client = OpenAI(base_url="https://api.deepseek.com", api_key="your-deepseek-key")

response = client.chat.completions.create(
    model="deepseek-flash",
    messages=[{"role": "user", "content": "Solve this scheduling problem: ..."}],
    reasoning_effort="high",  # low | high | max
    extra_body={"thinking": {"type": "enabled"}},  # "disabled" turns it off
)

print(response.choices[0].message.reasoning_content)  # the reasoning
print(response.choices[0].message.content)            # the answer

DeepSeek maps requested levels onto three real ones: minimal and low become low; medium, high and xhigh become high; max stays max. Asking for medium gets you high, which matters for cost. The pricing page lists two models, deepseek-flash and deepseek-v4-pro.

Route requests by complexity

Most production systems don’t need one global effort level. They need a cheap path for easy requests and a deliberate path for hard ones. Two ways to get there:

  1. Let the model decide within a level. Adaptive thinking on Claude already skips thinking on simple requests at lower effort, and Anthropic’s docs note that follow-up requests that only process tool results can skip thinking at any level.
  2. Classify first, then route. A small model or a rule scores the request, and you pick model and effort from the score. This is the same pattern as multi-provider LLM routing.
// Simplified router: pick an effort level per request
type Effort = "low" | "medium" | "high";

async function routeQuery(query: string): Promise<string> {
  const complexity = await classifyComplexity(query); // 1-5, from a small model or rules

  let effort: Effort = "low";
  if (complexity >= 3) effort = "medium";
  if (complexity >= 5) effort = "high";

  return callModel(query, { effort });
}

Before you build a multi-model cascade, test the simpler option: one capable model at lower effort. Anthropic’s effort docs say that on Claude Fable 5, lower effort settings often exceed xhigh performance on prior models. One model is also simpler to operate than three.

Production notes that save money

Size the output cap for reasoning

Reasoning shares the output budget with the answer. On Claude, max_tokens caps both, and a response that stops with stop_reason: "max_tokens" needs either a higher cap or lower effort. Which one depends on whether the truncated requests needed the reasoning. On OpenAI, plan for the incomplete status above.

Keep effort stable inside a cached conversation

Anthropic’s docs say the effort value is rendered into the prompt, so changing top-level effort between requests invalidates prompt-cache breakpoints. Pick a level per conversation. If some turns need less reasoning, newer Claude models support a per-message effort change (beta) that keeps the cache.

Don’t over-prompt

Instructions like “think step by step” and “consider every angle” were written for models that didn’t reason on their own. With a reasoning model, state the problem, give the context, and let the effort setting do the work. That’s the same shift described in how context engineering replaced prompt engineering. Anthropic’s docs suggest raising effort before you prompt around shallow reasoning, and lowering effort before you prompt the model to think less.

Show progress in the UI

A blank screen for 15 seconds feels broken. Stream reasoning summaries where the API offers them, or at least a “working” state, and measure time to first visible token separately from total latency.

Measure on your own traffic

Track three numbers per route: reasoning tokens as a share of output, quality on a fixed eval set at two or three effort levels, and time to first token. Raise a default only when the eval shows a gain at the higher level. Judge cost per completed task, not per request, since a cheaper request that needs a retry isn’t cheaper.

If you’re working out where reasoning models fit in your product, or trying to bring down the cost of ones you’ve already shipped, get in touch with us.

Frequently asked questions

What is a reasoning model?
A model trained to work through a problem internally before it writes the final answer. The intermediate reasoning is billed as output tokens. Most providers hide the raw reasoning and return a summary only if you ask for one, through settings like Claude's thinking display, OpenAI's reasoning summary, or Gemini's thinking_summaries.
When should I not use a reasoning model at high effort?
Skip high effort for simple retrieval and formatting, high-volume classification or tagging, and user-facing interactions that need sub-second responses. Anthropic's effort docs describe low effort as the setting for simpler tasks that need the best speed and lowest cost, such as subagents.
How do I control how much a model reasons?
Set a named effort level. On Claude it is output_config.effort (low, medium, high, xhigh, max). On OpenAI it is reasoning.effort, with levels that vary by model. On Gemini it is thinking_level in the generation config. On DeepSeek it is reasoning_effort, and the extra_body thinking setting turns thinking on or off.
Can I still set a thinking token budget?
On the newest Claude models, no. Anthropic's docs say you don't set a thinking token budget; effort is soft guidance and max_tokens is the hard cap on thinking plus answer. Fixed budgets survive only on older models. On OpenAI, max_output_tokens caps reasoning plus output, and a response that hits it comes back with status incomplete.
Does changing effort affect prompt caching?
On Claude, yes. Anthropic's docs say the effort value is rendered into the prompt, so changing the top-level effort between requests invalidates cache breakpoints. Pick one level per conversation, or use the per-message effort beta on models that support it.

Sources

Sponsored

Sponsored

Discussion

Join the conversation.

Comments are powered by GitHub Discussions. Sign in with your GitHub account to leave a comment.

Sponsored