How to create smart Multi-Agent work processes using Mistral Agent’s API’s Handoffs feature

In this tutorial, we explore how to create smart, multi-agent workflows using Mistral Agent’s API’s Handoffs feature. This lets different agents work together by transferring tasks to each other, which makes it possible to solve complex problems in a modular and effective way. We build a system where agents work together to answer inflation-related question-what performs calculations, retrieve data online and create visualizations to provide clear, accurate and dynamic answers.

Step 1: Setting up dependencies

Installation of the libraries

pip install mistralai pydantic

Loading the Mistral API key

You can get an API key from https://console.mistral.ai/api-Kays

from getpass import getpass
MISTRAL_API_KEY = getpass('Enter Mistral API Key: ')

Step 2: Prerequisites for Agent and Setup

Initialization of the agent

from mistralai import CompletionArgs, ResponseFormat, JSONSchema
from pydantic import BaseModel
from mistralai import Mistral

client = Mistral(MISTRAL_API_KEY)

Creating the custom feature

The Adjustment_for_inflation feature calculates how much a given amount would be worth after explaining inflation over time. It uses the connection formula based on the number of years and the annual inflation. If the end of the year is before the start year, it returns an error. Otherwise, it returns the adjusted value along with the input details. E.g. Displays adjustment_for_inflation (1000, 1899, 2025, 10), what £ 1000 from 1899 would be worth in 2025 at 10% inflation.

def adjust_for_inflation(amount: float, start_year: int, end_year: int, annual_inflation_rate: float):
    """
    Calculates inflation-adjusted value using compound formula.
    """
    if end_year < start_year:
        return {"error": "End year must be greater than or equal to start year."}

    years = end_year - start_year
    adjusted_value = amount * ((1 + annual_inflation_rate / 100) ** years)

    return {
        "original_amount": amount,
        "start_year": start_year,
        "end_year": end_year,
        "inflation_rate": annual_inflation_rate,
        "adjusted_value": round(adjusted_value, 2)
    }

adjust_for_inflation(1000, 1899, 2025, 10)

Creating structured output for mathematical reasoning

class CalcResult(BaseModel):
    reasoning: str
    result: str

inflation_tool = {
    "type": "function",
    "function": {
        "name": "adjust_for_inflation",
        "description": "Calculate the value of money adjusted for inflation over a time period.",
        "parameters": {
            "type": "object",
            "properties": {
                "amount": {
                    "type": "number",
                    "description": "Original amount of money"
                },
                "start_year": {
                    "type": "integer",
                    "description": "The starting year for inflation adjustment"
                },
                "end_year": {
                    "type": "integer",
                    "description": "The ending year for inflation adjustment"
                },
                "annual_inflation_rate": {
                    "type": "number",
                    "description": "Annual inflation rate in percent"
                }
            },
            "required": ["amount", "start_year", "end_year", "annual_inflation_rate"]
        }
    }
}

Step 3: Creating the agents

Definition of the different agents

In this setup, we define a multi-agent system using Mistral Agent’s API to deal with inflation-related financial queries. The main agent (finance agent) acts as a coordinator who routes tasks to specialized agents. The inflation agent performs inflation adjustment calculations using a custom function. If inflation is missing in the query, webseearch agent will pick it up from the Internet. The calculator agent handles complex numerical calculations with step-by-step reasoning, while the graphic is using cod interpreter to visualize inflation trends over time. Together, these agents collaborate via deliveries to deliver accurate, dynamic reactions to financial queries.

# Main Agent
economics_agent = client.beta.agents.create(
    model="mistral-large-latest",
    name="economics-agent",
    description="Handles economic queries and delegates inflation calculations.",
)

# Inflation Function Agent
inflation_agent = client.beta.agents.create(
    model="mistral-large-latest",
    name="inflation-agent",
    description="Agent that calculates inflation-adjusted value using a custom function.",
    tools=[inflation_tool],
)

# Web Search Agent
websearch_agent = client.beta.agents.create(
    model="mistral-large-latest",
    name="websearch-agent",
    description="Agent that can search the internet for missing economic data such as inflation rates.",
    tools=[{"type": "web_search"}]
)


# Calculator Agent
from pydantic import BaseModel

class CalcResult(BaseModel):
    reasoning: str
    result: str

calculator_agent = client.beta.agents.create(
    model="mistral-large-latest",
    name="calculator-agent",
    description="Agent used to make detailed calculations.",
    instructions="When doing calculations, explain step by step.",
    completion_args=CompletionArgs(
        response_format=ResponseFormat(
            type="json_schema",
            json_schema=JSONSchema(
                name="calc_result",
                schema=CalcResult.model_json_schema(),
            )
        )
    )
)

# Graph Agent
graph_agent = client.beta.agents.create(
    model="mistral-large-latest",
    name="graph-agent",
    description="Agent that generates graphs using code interpreter.",
    instructions="Use code interpreter to draw inflation trends.",
    tools=[{"type": "code_interpreter"}]
)

Definition of handover responsibility

This configuration defines how agents delegate tasks between each other:

  • The main agent (Economics_Agent) acts as an entry point and delegates queries either to the inflation_Agenten (for inflation calculations) or webSearch_Agent (to retrieve missing data such as inflation rates).
  • Inflation_Agent, after receiving either user request or webhented data, may further transfer tasks to the calculator_Agenten (for detailed math) or graph_ agent (to visualize trends).
  • WebSearch_Agent can pass on control to the inflation_Agent after retrieving the necessary information, such as inflation speed.
  • Calculator_Agent and Graph_Agent are considered terminal funds. Optional mutual delivery, however, is activated if you are to perform follow -up work (eg graphing of a calculated result or vice versa).
# Main Agent hands off to inflation_agent and websearch_agent
economics_agent = client.beta.agents.update(
    agent_id=economics_agent.id,
    handoffs=[inflation_agent.id, websearch_agent.id]
)

# Inflation Agent can delegate to calculator_agent or graph_agent if deeper analysis or visualization is needed
inflation_agent = client.beta.agents.update(
    agent_id=inflation_agent.id,
    handoffs=[calculator_agent.id, graph_agent.id]
)

# Web Search Agent can hand off to inflation_agent (after finding the missing rate)
websearch_agent = client.beta.agents.update(
    agent_id=websearch_agent.id,
    handoffs=[inflation_agent.id]
)

# Calculator and Graph agents are terminal--they don't hand off further
# But if needed, we could let them hand off to each other:
calculator_agent = client.beta.agents.update(
    agent_id=calculator_agent.id,
    handoffs=[graph_agent.id]  # Optional
)

graph_agent = client.beta.agents.update(
    agent_id=graph_agent.id,
    handoffs=[calculator_agent.id]  # Optional
)

Step 4: Driving the Agent

Example A: What is the current inflation in India?

In this example “What is the current inflation in India?” transferred to Economics_Agent, which is the most important entry point for dealing with financial queries. As the question requires real -time data not included in the agent’s static knowledge, Economics_Agent automatically hand over the query to webSearch_Agent, which is equipped with web search features.

prompt = "What is the current inflation rate in India?"
response = client.beta.conversations.start(
    agent_id=economics_agent.id,
    inputs=prompt
)
print(response.outputs[-1].content[0].text)

Example B: What is the inflation -adjusted value of 5,000 from the year 2010 to 2023 with an annual inflation of 6.5%. Explain the calculation step and plot a graph of data tags

This code block sends the prompt to an economic agent, checks if the agent triggers a specific function call (adjustment_for_inflation), performs this feature locally with the accompanying arguments and then returns the calculated result back to the agent. Finally, it prints the agent’s answer, which includes explanation of the inflation calculation along with the Python code to plot the trend.

import json

from mistralai.models import FunctionResultEntry

prompt = """What is the inflation-adjusted value of 5,000 from the year 2010 to 2023 with annual inflation rate of 6.5%. 
Explain calculation steps and plot a graph with data labels"""

response = client.beta.conversations.start(
    agent_id=economics_agent.id,
    inputs=prompt
)

# Check for function call
if response.outputs[-1].type == "function.call" and response.outputs[-1].name == "adjust_for_inflation":
    args = json.loads(response.outputs[-1].arguments)

    # Run local function
    function_result = json.dumps(adjust_for_inflation(**args))

    # Return result to Mistral
    result_entry = FunctionResultEntry(
        tool_call_id=response.outputs[-1].tool_call_id,
        result=function_result
    )

    response = client.beta.conversations.append(
        conversation_id=response.conversation_id,
        inputs=[result_entry]
    )

    print(response.outputs[-1].content)
else:
    print(response.outputs[-1].content)

The following code block was returned by the agent to plot the trend of inflation -adjusted value over time.

import matplotlib.pyplot as plt
import numpy as np

# Parameters
original_amount = 5000
start_year = 2010
end_year = 2023
inflation_rate = 6.5 / 100  # Convert percentage to decimal

# Calculate the number of years
num_years = end_year - start_year + 1

# Calculate the adjusted value for each year
years = np.arange(start_year, end_year + 1)
adjusted_values = original_amount * (1 + inflation_rate) ** (years - start_year)

# Plot the graph
plt.figure(figsize=(10, 6))
plt.plot(years, adjusted_values, marker="o", linestyle="-", color="b")

# Add data labels
for year, value in zip(years, adjusted_values):
    plt.text(year, value, f'${value:.2f}', ha="right")

# Add titles and labels
plt.title('Inflation-Adjusted Value Over Time')
plt.xlabel('Year')
plt.ylabel('Adjusted Value')

# Save the plot as an image
plt.savefig('inflation_adjusted_value.png')

# Show the plot
plt.show()

Check Notebook. All credit for this research goes to the researchers in this project. You are also welcome to follow us on Twitter And don’t forget to join our 98k+ ml subbreddit and subscribe to Our newsletter.


I am a candidate for a civil engineer (2022) from Jamia Millia Islamia, New Delhi, and I have a great interest in data sciences, especially neural networks and their use in different areas.

Leave a Comment