Skip to main content
Lesson 2 of 12 · AI Reasoning with Mistral: reasoning_effort, Small 4 and Large 4

The reasoning_effort parameter

Lesson 2 of 12 Updated November 2, 2026 Developer
On this page
  1. Setting the depth of thought
  2. Accepted values, model by model
  3. Implementation in Python
  4. Choosing the level by task
  5. Measuring the cost
  6. Routing by complexity
  7. Limits to know
  8. Key takeaways

Lesson rewritten on November 2, 2026. The previous version stated that reasoning_effort accepted only two values and existed only on Mistral Small. In reality, accepted values depend on the model, and Mistral Large 4 offers three. Source: Reasoning (Mistral documentation).

Setting the depth of thought

Adjustable reasoning rests on a simple principle: you decide, request by request, how much the model should think before answering. The lever is called reasoning_effort. You pass it in the API call at the same level as the model and messages, with no other configuration required.

Accepted values, model by model

This is the most common pitfall: accepted values depend on the model.

ModelDocumented valuesOfficial recommendation
Mistral Small 4 (mistral-small-2603)high, none—
Mistral Medium 3.5 (mistral-medium-3-5)high, nonehigh for agentic workflows and code
Mistral Large 4 (mistral-large-4-0)low, medium, highStart with high, then switch to medium or low if tokens or latency matter more

On Small 4 and Medium 3.5, high produces a full reasoning fragment before the answer, at the cost of higher token consumption; none reduces reasoning to the minimum and omits it from the response. On Large 4, the scale has three levels: low for simple tasks, medium to balance quality, tokens, and latency, and high for complex tasks. Large 4 does not accept none: the documentation specifies that the level formerly called none in its preview is now called low.

One last nuance: the ReasoningEffort type in the SDKs also enumerates minimal, xhigh, and max because the enumeration covers every model on the platform (max is used, for example, by the third-party model zai-glm-5-3). Just because a value appears in the enumeration doesn’t mean your model accepts it.

Implementation in Python

import os
from mistralai.client import Mistral

client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

# Mistral Small 4, deep reasoning
response_high = client.chat.complete(
    model="mistral-small-2603",
    messages=[{"role": "user", "content": "Solve x^3 - 6x^2 + 11x - 6 = 0 and verify each root."}],
    reasoning_effort="high",
)

# Mistral Small 4, direct answer
response_none = client.chat.complete(
    model="mistral-small-2603",
    messages=[{"role": "user", "content": "What is the capital of Portugal?"}],
    reasoning_effort="none",
)

# Mistral Large 4, intermediate level
response_medium = client.chat.complete(
    model="mistral-large-4-0",
    messages=[{"role": "user", "content": "Compare two caching strategies for a high-traffic API."}],
    reasoning_effort="medium",
)

The response shape changes with the setting. With high, message.content is a list that starts with a reasoning fragment; with none, it’s a simple string. Your code must therefore handle both forms, as the next lesson shows.

In TypeScript, the parameter follows JavaScript casing and is written reasoningEffort:

import { Mistral } from '@mistralai/mistralai';

const client = new Mistral({ apiKey: process.env.MISTRAL_API_KEY });

const response = await client.chat.complete({
  model: 'mistral-small-2603',
  messages: [{ role: 'user', content: 'Solve x^3 - 6x^2 + 11x - 6 = 0.' }],
  reasoningEffort: 'high',
});

Choosing the level by task

Reserve deep reasoning for multi-step math problems, complex code debugging, comparative analysis, planning, logic puzzles, and risk assessment. These share a common trait: multiple paths are possible, and picking the wrong one is costly.

Turn it off (or drop to the lowest level) for simple factual questions, translation, paraphrasing, direct information extraction, and everyday conversation. The model has nothing to arbitrate here: it retrieves or transforms, and a reasoning phase would only add latency.

Measuring the cost

Reasoning costs output tokens. The official documentation example gives a sense of scale: an age riddle sent to Mistral Small 4 with high consumes 77 input tokens and 1,114 output tokens. At Small 4’s listed rate of $0.15 per million input tokens and $0.60 per million output tokens, the request costs about $0.0007. That’s negligible per unit, but across a million similar requests, reasoning alone represents several hundred dollars, with no gain if half the questions didn’t need it.

The usage field in every response gives you the exact measure: track completion_tokens by request type before generalizing a setting.

Routing by complexity

A simple workaround is to choose the level based on the question, using a table per model to ensure you never send a rejected value:

LEVELS = {
    "mistral-small-2603": {"simple": "none", "complex": "high"},
    "mistral-large-4-0": {"simple": "low", "complex": "high"},
}

COMPLEX_WORDS = ("calculate", "prove", "compare", "analyze", "optimize", "debug", "why")

def query(client, question, model="mistral-small-2603", level=None):
    """Chooses reasoning_effort based on the question, or applies a forced level."""
    if level is None:
        is_complex = any(word in question.lower() for word in COMPLEX_WORDS)
        level = LEVELS[model]["complex" if is_complex else "simple"]
    return client.chat.complete(
        model=model,
        messages=[{"role": "user", "content": question}],
        reasoning_effort=level,
    )

Keyword heuristics remain crude; they suffice to reserve reasoning for requests that benefit from it, and the level argument lets you force a setting. Lesson 12 proposes a more complete routing architecture.

Limits to know

Reasoning increases the probability of a correct answer; it doesn’t guarantee one: verify critical results (Lesson 9). It also increases latency, which matters in a conversational interface. Finally, the passed value must match the called model: plan for a table like the one above rather than scattering strings throughout your code.

Key takeaways

  • reasoning_effort controls reasoning request by request, with no other configuration
  • Small 4 and Medium 3.5 accept high and none; Large 4 accepts low, medium, and high, not none
  • SDK enumerations contain values that not all models accept
  • With high, content is a list of fragments; with none, a string
  • Measure cost with usage.completion_tokens and route by complexity