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

Reasoning in agents and conversations

Lesson 4 of 12 Updated November 2, 2026 Developer
On this page
  1. Three ways to call a reasoning model
  2. An agent that reasons
  3. Reading conversation outputs
  4. A conversation without an agent
  5. Reasoning and tools
  6. Comparing the three approaches
  7. Integration best practices
  8. Key takeaways

Lesson rewritten on November 2, 2026 for Mistral Small 4 and Large 4. Mistral’s documentation states that reasoning_effort is available on the Agents and Conversations endpoints within the completion_args field. Sources: Reasoning · Python SDK — Conversations.

Three ways to call a reasoning model

Previous lessons used the Chat Completions API: you sent the full history with every call, and reasoning_effort went directly into the request. Mistral offers two other interfaces: the Agents API, which saves a reusable configuration (model, instructions, tools, parameters), and the Conversations API, which keeps history on the server. In these two APIs, you don’t set reasoning at the top level; you nest it inside completion_args alongside other generation parameters.

An agent that reasons

Setting the reasoning level in the agent definition avoids repeating it on every call and ensures your whole team uses the same setting:

import os
from mistralai.client import Mistral

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

agent = client.beta.agents.create(
    model="mistral-small-2603",
    name="Financial Analyst",
    instructions=(
        "You analyze financial situations for SMEs. "
        "End every response with a quantified recommendation and its assumptions."
    ),
    completion_args={"reasoning_effort": "high"},
)

reponse = client.beta.conversations.start(
    agent_id=agent.id,
    inputs="Our working capital requirement has doubled in a year while revenue grew by 15%. What should we look at first?",
)

Reading conversation outputs

A conversation doesn’t return choices; it returns a list of entries (outputs). The model’s response lives in entries of type message.output. As with Chat Completions, the content is either a string or a list of chunks that may include a ThinkChunk. The separer function from Lesson 3 works exactly as before:

for entry in reponse.outputs:
    if entry.type == "message.output":
        reflexion, texte = separer(entry.content)
        print(texte)

Other entries describe what happened during the turn, such as tool execution (tool.execution) or a function call. Ignore them if you only care about the final answer.

A conversation without an agent

For one-off tasks, the Conversations API accepts a model directly, with no prior agent setup. The server keeps the history, and you continue the exchange with conversations.append, adjusting the reasoning level for a specific turn if needed:

conv = client.beta.conversations.start(
    model="mistral-large-4-0",
    inputs="Propose a migration plan for a 2 TB PostgreSQL database with zero downtime.",
    completion_args={"reasoning_effort": "high"},
)

suite = client.beta.conversations.append(
    conversation_id=conv.conversation_id,
    inputs="Summarize this plan in five steps for executive leadership.",
    completion_args={"reasoning_effort": "low"},   # a summary doesn't need deep reflection
)

This is a concrete advantage over Chat Completions, where the documentation requires you to replay the assistant’s full message, reflection included, on every new turn (Lesson 7). With the Conversations API, the server keeps the history; you don’t resend it on every call.

Reasoning and tools

An agent can combine reasoning and tools: tools and completion_args are independent fields when creating an agent. An analysis agent can thus have web search and deep reasoning:

agent_veille = client.beta.agents.create(
    model="mistral-small-2603",
    name="Competitive Intelligence",
    instructions="You compare competitor offers using cited public sources.",
    tools=[{"type": "web_search"}],
    completion_args={"reasoning_effort": "high"},
)

Keep an eye on cost, though: reflection and tool calls add up in the bill for a single turn.

Comparing the three approaches

CriterionChat CompletionsAgentsConversations
Where to set reasoningreasoning_effort in the requestcompletion_args in the agentcompletion_args in start or append
HistoryResend on every call, reflection includedCarried by the conversationKept on the server
Built-in tools (web_search…)NoYesYes
Typical useOne-off calls, full controlShared, reusable configurationMulti-turn exchanges

Integration best practices

Set the reasoning level in the agent when the task is uniform, and per turn when it varies: an initial analysis turn at high, followed by reformulation turns at low or none, depending on the model. Verify that the value suits the agent’s model: Small 4 accepts high and none; Large 4 accepts low, medium, and high. Finally, log token usage per turn; it’s the only way to know whether reasoning pays off for your use case.

Key takeaways

  • In the Agents and Conversations APIs, pass reasoning_effort inside completion_args
  • Responses arrive in outputs; text lives in message.output entries, reflection included
  • The Conversations API keeps history on the server: no need to resend it every turn
  • You can change the level on every turn with conversations.append
  • An agent can combine built-in tools and reasoning, at the cost of cumulative usage