Reasoning in agents and conversations
On this page
Lesson rewritten on November 2, 2026 for Mistral Small 4 and Large 4. Mistral’s documentation states that
reasoning_effortis available on the Agents and Conversations endpoints within thecompletion_argsfield. 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
| Criterion | Chat Completions | Agents | Conversations |
|---|---|---|---|
| Where to set reasoning | reasoning_effort in the request | completion_args in the agent | completion_args in start or append |
| History | Resend on every call, reflection included | Carried by the conversation | Kept on the server |
Built-in tools (web_search…) | No | Yes | Yes |
| Typical use | One-off calls, full control | Shared, reusable configuration | Multi-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_effortinsidecompletion_args - Responses arrive in
outputs; text lives inmessage.outputentries, 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