Skip to main content
Lesson 3 of 18 · Mistral Agents: Building Autonomous AI

Mistral Agents API Architecture

Lesson 3 of 18 Updated November 3, 2026 Developer
On this page
  1. The Three Fundamental Objects
  2. The Agent Object
  3. The Conversation Object
  4. The Entry Object
  5. Relationships Between Objects
  6. Conversation Options
  7. Key Takeaways

Updated November 3, 2026. The previous full agent example passed guardrails={"enabled": True}, a format that does not exist: the official parameter is a list of moderation_llm_v2 configurations. The tool.execution input exposes the tool name in entry.name, not entry.tool_name, which previously raised an AttributeError. Sources: Agents & Conversations · Moderation & Guardrailing · mistralai SDK 3.7.0.

The Three Fundamental Objects

The Mistral Agents API relies on three interacting objects: Agent, Conversation, and Entry. Most design errors encountered early in a project—recreating an agent for every request, reusing an expired conversation_id, or response parsing that crashes on an unexpected entry—stem from confusion between these three levels. Understanding their roles and relationships is a prerequisite to writing even a single line of code.

The Agent Object

An Agent is a configuration set that defines the model’s behavior. It contains no conversation data: it is a reusable template that you create once and that thousands of conversations can reference.

Creation requires at minimum a model, a name, and a description.

agent = client.beta.agents.create(
    model="mistral-large-latest",        # LLM model to use
    name="My Agent",                     # Human-readable identifier
    description="Agent for financial analysis"  # Task-oriented description
)

The model parameter designates the model that will power the agent, chosen from available chat completion models like mistral-medium-latest or mistral-large-latest. The name is a human-readable identifier you use to find and reference the agent: in a project with twenty of them, this is what saves you from digging through logs to figure out which one is answering customers. The description, meanwhile, is task-oriented and serves more than just internal documentation—it helps the model understand the role expected of it, which explains the phrasing “agent for financial analysis” rather than a vague “agent number 3”.

The rest is configured optionally, and this is where the agent’s actual personality takes shape.

agent = client.beta.agents.create(
    model="mistral-large-latest",
    name="Complete Agent",
    description="Agent with all parameters",
    instructions="You are a finance expert. Always respond with sources.",
    tools=[
        {"type": "web_search"},
        {"type": "code_interpreter"}
    ],
    completion_args={"temperature": 0.3, "top_p": 0.95},
    guardrails=[
        {
            "block_on_error": True,
            "moderation_llm_v2": {
                "custom_category_thresholds": {"jailbreaking": 0.2, "financial": 1},
                "action": "block",
            },
        }
    ],
)
  • instructions — The agent’s system prompt (defines its personality, rules, and style)
  • tools — List of available tools: web_search, web_search_premium, code_interpreter, image_generation, document_library, or custom functions
  • completion_args — Sampler parameters (temperature, top_p, max_tokens, etc.)
  • guardrails — A list of moderation configurations (moderation_llm_v2) applied to the incoming message of each of the agent’s conversations; here, jailbreaking is blocked above 0.2 and the financial category is disabled (threshold 1), since the agent is built to discuss finance. Details are in the AI Moderation and Security with Mistral course.

In the example above, the financial agent inherits a sourcing requirement from its instructions, the ability to verify a figure from its tools, and a low temperature that limits creativity where rigor is expected.

The Conversation Object

A Conversation is the history of interactions between a user and an agent—or between a user and a model alone. It contains messages, tool execution results, and handoff events.

response = client.beta.conversations.start(
    agent_id=agent.id,
    inputs="Analyze trends in the European AI market."
)

# Retrieve the conversation ID to continue later
conversation_id = response.conversation_id

This object’s behavior holds a few surprises. The conversation is persistent: the history is stored on Mistral’s side, unless you pass store=False. It is independent of the agent, meaning a conversation can perfectly well exist without an agent, in direct model mode. Finally, it is immutable: every addition returns a new conversation_id, with the old one remaining accessible. This last point is the most surprising: if you store the initial ID in your database and reuse it on the third turn, you will revert to the context of the first exchange.

The Entry Object

An Entry is an individual action within a conversation: the atomic unit of the history. When you receive a response, the outputs field contains a list of entries whose type depends on what the agent did. A message.output entry carries a text response from the agent, i.e., the text your interface will display. A tool.execution entry carries the execution result of a tool, such as code or a web search: the script launched and its output, or the pages returned by the engine. An agent.handoff entry signals a transfer event to another agent, and thus only appears in multi-agent scenarios.

A single response commonly mixes these types. Ask a tooled agent for a calculation and you will receive the execution, then the commentary accompanying it: your code must therefore iterate through this list rather than reading a single field.

response = client.beta.conversations.start(
    agent_id=agent.id,
    inputs="Calculate the square root of 144"
)

for entry in response.outputs:
    print(f"Type: {entry.type}")
    if entry.type == "message.output":
        print(f"Message: {entry.content}")
    elif entry.type == "tool.execution":
        print(f"Tool: {entry.name}")

Relationships Between Objects

The following diagram summarizes the articulation of the three levels: a reusable configuration, a history thread, and unit actions.

Agent (configuration)
  ├── model, instructions, tools, guardrails
  └── Can be referenced by N conversations

Conversation (history)
  ├── Linked to 0 or 1 Agent (optional)
  ├── Contains N ordered entries
  └── Each append creates a new conversation_id

Entry (unit action)
  ├── message.output (text response)
  ├── tool.execution (tool result)
  └── agent.handoff (agent transfer)

Conversation Options

Starting a conversation accepts settings that impact your compliance as much as your architecture, and it is better to decide them than to suffer them. Storage first: store=False prevents any saving on Mistral’s side, which you will use to process data that your internal policy forbids leaving on a third-party server.

# Disable cloud storage
response = client.beta.conversations.start(
    agent_id=agent.id,
    inputs="Sensitive question",
    store=False
)

The second setting defines who executes handoffs. In server mode, the default value, Mistral chains agent transfers without your intervention; in client mode, you receive handoff events and keep control to log, filter, or refuse them.

# Server mode (default) — Mistral handles handoffs automatically
response = client.beta.conversations.start(
    agent_id=agent.id,
    inputs="Complex request",
    handoff_execution="server"
)

# Client mode — You receive handoff events and decide what to do
response = client.beta.conversations.start(
    agent_id=agent.id,
    inputs="Complex request",
    handoff_execution="client"
)

Key Takeaways

  • Agent = reusable configuration (model, instructions, tools, guardrails)
  • Conversation = persistent history stored on the server, independent of the agent
  • Entry = unit action (message, tool execution, handoff)
  • Conversations can exist without an agent (direct model mode)
  • Each addition to a conversation creates a new conversation_id
  • The store=False mode prevents storage on Mistral’s side