Sous-agents
Référence API : Subagent, SubagentPolicy
Un agent peut confier des parties d'un travail à des sous-agents. Chacun exécute sa propre tâche avec son propre historique pendant que les autres travaillent, et le parent rassemble leurs rapports. Un sous-agent est une session distincte, avec ses propres tours.
Si vous connaissez les transferts de l'API d'agent : un sous-agent transmet son rapport à son parent ; il ne prend pas le relais dans la conversation.
Quand utiliser des sous-agents
- Des tâches indépendantes en parallèle : recherchez cinq produits à la fois, avec un sous-agent par produit.
- Un spécialiste : un sous-agent avec ses propres instructions et outils, par exemple un agent de déploiement qui seul
peut appeler
deploy. - Une tâche longue qui remplirait le contexte du parent : le sous-agent lit les logs, et le parent ne reçoit que son résumé.
Lorsqu'une étape dépend du résultat de la précédente, laissez le parent exécuter les deux. Utilisez un skill lorsque seule la procédure change.
Déclarer et exécuter des sous-agents
Passez les sous-agents que le modèle peut démarrer dans Agent(subagents=[...]). Le modèle du parent en choisit un par son
nom lorsqu'il démarre un sous-agent :
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 Atlas costs **1,200 EUR** and the Nova costs **850 EUR**.
2Le parent n'a aucun outil propre ; il démarre un agent de recherche pour chaque produit et attend les deux
résultats. Chaque agent de recherche dispose de lookup_price, et agents.Builtins(subagents=False) l'empêche de
démarrer ses propres sous-agents, y compris des sous-agents génériques. session.subagents() renvoie les sessions des deux
agents de recherche, donc le programme affiche 2 ; voir Consulter et arrêter les sous-agents.
name, description et instructions sont obligatoires. Le modèle lit le nom et la description
pour choisir un sous-agent ; rédigez donc la description à son intention. La plupart des autres champs sont hérités du
parent, sauf si vous les définissez ; voir Configurer les sous-agents.
Le modèle peut aussi démarrer un sous-agent générique. Celui-ci reprend le modèle, les outils et les paramètres du parent, et
s'exécute selon des instructions rédigées par le modèle. Le modèle peut en démarrer un dès que l'agent possède des sous-agents ou
une subagent_policy.
Fonctionnement des sous-agents
L'agent que vous exécutez est la racine ; il forme avec ses sous-agents un arbre. Le modèle du parent pilote ses sous-agents avec des outils que le système d'exécution lui fournit : l'un démarre un sous-agent, les autres lui envoient un message, attendent son résultat ou interrompent son tour. Vous n'avez aucun de ces outils à écrire.
- Un sous-agent s'exécute en arrière-plan ; le parent peut donc en démarrer plusieurs à la fois.
- Le parent peut envoyer des messages de suivi à un sous-agent, qui conserve son historique.
- Chaque résultat arrive dans le tour en cours du parent, ou dans son prochain tour si le tour en cours est terminé.
session.run()renvoie un résultat lorsque le tour du parent se termine, et non lorsque les tours de ses sous-agents se terminent. Demandez au parent d'« attendre tous les résultats » lorsqu'il ne doit pas répondre avant de les avoir reçus. - Un sous-agent arrêté avant la fin transmet tout de même son dernier message, et le parent peut lui envoyer un message pour qu'il continue.
Où s'exécutent les sous-agents
- Les sous-agents s'exécutent dans la sandbox de la racine et partagent ses fichiers. Vous configurez la sandbox une seule fois, sur l'agent racine. Attribuez des fichiers distincts aux sous-agents qui écrivent en parallèle.
- Dans votre processus, toutes les sandbox fonctionnent avec les sous-agents.
- Lorsque vous déployez avec Studio, en auto-hébergement ou avec une gestion par Mistral, utilisez
MistralSandbox, qui nécessite le rôlecloud_user, ouNoSandbox. Avec une autre sandbox, un agent doté de sous-agents s'arrête au démarrage.
Limites
Au maximum, 10 tours de sous-agents s'exécutent à la fois dans l'ensemble de l'arbre. L'arbre comporte deux niveaux de sous-agents : les sous-agents et
leurs propres sous-agents. Modifiez les limites sur l'agent racine avec subagent_policy=. Ajoutez ce qui suit à l'agent
ci-dessus :
subagent_policy=agents.SubagentPolicy(concurrent_child_turn_limit=4),Tous les champs et leurs valeurs par défaut : Références SubagentPolicy.
Lorsque l'arbre est plein, le démarrage d'un sous-agent échoue, et le modèle du parent lit l'erreur comme toute
autre erreur d'outil.
Consulter et arrêter les sous-agents
await session.subagents() renvoie un handle de session pour chaque
sous-agent direct, du plus récent au plus ancien. Vous pouvez consulter un sous-agent et interrompre son tour, mais seul son parent lui confie du
travail : send_message, run, start_turn et cancel sur son handle, ainsi que steer sur son tour, lèvent
agents.UnsupportedSessionProcedureError. Lorsqu'un sous-agent attend un callback, par exemple une approbation,
le résultat Blocked de la racine le répertorie dans state.callbacks avec les identifiants du sous-agent
(Approbations entre sous-agents). Interrompez son tour avec
await agent.session(callback.session_id).turn(callback.turn_id).interrupt().
Pour arrêter un sous-agent, annulez la racine : await session.cancel() sur la session racine arrête la racine et
tous les sous-agents. turn.interrupt() sur le tour de la racine n'arrête que ce tour : les sous-agents continuent de
s'exécuter, et leurs résultats arrivent dans le prochain tour de la racine. Dans votre processus, l'arbre s'arrête aussi lorsque la boucle d'événements se termine ; laissez donc le parent
attendre ses sous-agents avant que votre programme ne se termine.
Problèmes courants
| Symptôme | Cause | Solution |
|---|---|---|
| La réponse omet le résultat d'un sous-agent | Le tour du parent s'est terminé avant celui du sous-agent ; le résultat est donc arrivé dans le tour suivant. | Demandez au parent d'attendre tous les résultats avant de répondre. |
Un agent déployé s'arrête au démarrage avec subagents_with_unborrowable_sandbox | Ses sous-agents ne peuvent pas partager sa sandbox. | Utilisez MistralSandbox ou NoSandbox. |
Aller plus loin
- Configurer les sous-agents : ce qu'un sous-agent hérite, ses propres outils, et les sous-agents d'un sous-agent.
- Approbations entre sous-agents : un seul gestionnaire répond pour l'ensemble de l'arbre.
- Une politique d'approbation pour tous les sous-agents : un agent principal démarre un agent de test et un agent de rédaction de documentation, dans un programme complet.