Subagents
API reference: Subagent, SubagentPolicy
An agent can hand parts of a job to subagents. Each one works on its own task with its own history while the others run, and the parent combines what they report. A subagent is a session of its own, with its own turns.
Coming from Agents API handoffs: a subagent reports back to its parent; it does not take over the conversation.
When to use subagents
- Independent tasks in parallel: look up five products at once, one subagent each.
- A specialist: a subagent with its own instructions and tools, such as a deployer that alone
can call
deploy. - A long task that would fill the parent's context: the subagent reads the logs, and the parent gets only its summary.
When a step needs the result of the step before it, let the parent do both. Use a skill when only the procedure changes.
Declare and run subagents
Pass the subagents the model may start in Agent(subagents=[...]). The parent's model picks one by
name when it starts a subagent:
import asyncio
from pydantic import BaseModel
from mistralai import agents
PRICES = {"atlas": "1,200 EUR", "nova": "850 EUR"}
class PriceArgs(BaseModel):
product: str
@agents.tool(name="lookup_price", description="Price of one product.", input_schema=PriceArgs)
async def lookup_price(args: PriceArgs) -> dict[str, str]:
return {"price": PRICES.get(args.product.casefold(), "unknown")}
agent = agents.Agent(
model="mistral-large-4",
instructions=(
"You answer questions about our products. Start one researcher per product, "
"wait for every result, then answer in one sentence."
),
subagents=[
agents.Subagent(
name="researcher",
description="Looks up one product and reports its price.",
instructions="Call lookup_price once, then answer with the product name and its price.",
tools=[lookup_price],
builtins=agents.Builtins(subagents=False),
)
],
)
async def main() -> None:
session = await agent.start_session()
state = await session.run("What do the Atlas and the Nova cost?")
if isinstance(state, agents.Completed):
print(state.text)
print(len(await session.subagents()))
await session.cancel()
asyncio.run(main())The parent has no tools of its own; it starts a researcher for each product and waits for both
results. Each researcher has lookup_price, and agents.Builtins(subagents=False) keeps it from
starting subagents of its own, generic ones included. session.subagents() returns the two
researchers' sessions, so the program prints 2; see See and stop subagents.
name, description and instructions are required. The model reads the name and the description
when it picks a subagent, so write the description for the model. Most other fields come from the
parent unless you set them; see Configure subagents.
The model can also start a generic subagent. It has the parent's model, tools and settings, and
runs on instructions the model writes. The model can start one whenever the agent has subagents or
a subagent_policy.
How subagents run
The agent you run is the root; it and its subagents form a tree. The parent's model drives its subagents with tools the harness adds for it: one starts a subagent, others send it a message, wait for its result or interrupt its turn. You write none of them.
- A subagent runs in the background, so the parent can start several at once.
- The parent can send a subagent follow-up messages, and the subagent keeps its history.
- Each result reaches the parent's current turn, or its next turn if it has ended.
session.run()returns when the parent's turn ends, not when its subagents' turns end. Tell the parent to "wait for every result" when it must not answer before them. - A subagent stopped early still reports its last message, and the parent can message it to continue.
Where subagents run
- Subagents run in the root's sandbox and share its files. You set the sandbox once, on the root agent. Give subagents that run at once separate files to write.
- In your process, every sandbox works with subagents.
- When you deploy with Studio, self-hosted or Mistral-managed, use
MistralSandbox, which needs thecloud_userrole, orNoSandbox. With another sandbox, an agent with subagents stops at startup.
Limits
At most 10 subagent turns run at once in the whole tree. The tree is two levels deep: subagents and
their own subagents. Change the limits on the root agent with subagent_policy=. Add to the Agent
above:
subagent_policy=agents.SubagentPolicy(concurrent_child_turn_limit=4),Every field and its default: SubagentPolicy reference.
When the tree is full, starting a subagent fails, and the parent's model reads the error like any
other tool error.
See and stop subagents
await session.subagents() returns a session handle for each direct
subagent, newest first. You can read a subagent and interrupt its turn, but only its parent gives it
work: send_message, run, start_turn and cancel on its handle, and steer on its turn, raise
agents.UnsupportedSessionProcedureError. When a subagent waits on a callback, such as an approval,
the root's Blocked result lists it in state.callbacks with the subagent's IDs
(Approvals across subagents). Interrupt its turn with
await agent.session(callback.session_id).turn(callback.turn_id).interrupt().
To stop a subagent, cancel the root: await session.cancel() on the root session ends the root and
every subagent. turn.interrupt() on the root's turn stops that turn only: the subagents keep
running, and their results reach the root's next turn. In your process, the tree also stops when the event loop ends, so let the parent
wait for its subagents before your program exits.
Common issues
| You see | Cause | Fix |
|---|---|---|
| The answer leaves out a subagent's result | The parent's turn ended before the subagent's, so the result reached the next turn. | Tell the parent to wait for every result before it answers. |
A deployed agent stops at startup with subagents_with_unborrowable_sandbox | Its subagents cannot share its sandbox. | Use MistralSandbox or NoSandbox. |
Next
- Configure subagents: what a subagent inherits, its own tools, and subagents of a subagent.
- Approvals across subagents: one handler answers the whole tree.
- One approval policy for every subagent: a lead agent starts a tester and a docs writer, in a full program.