Sous-agents
Ajouté dans : @mastra/core@1.8.0
Les sous-agents sont des agents spécialisés auxquels un autre agent peut déléguer des tâches. Ajoutez-les à la propriété agents de l’agent parent, puis appelez Agent.stream() ou Agent.generate(). L’agent parent s’appuie sur ses instructions et sur la description de chaque sous-agent pour décider quand et comment déléguer les tâches.
Quand utiliser des sous-agentsLien direct vers Quand utiliser des sous-agents
Utilisez des sous-agents lorsqu’une tâche nécessite la collaboration d’agents aux spécialités différentes. L’agent parent décide du moment de la délégation, transmet le contexte à chaque sous-agent, puis synthétise leurs résultats.
Cas d’usage courants :
- Workflows de recherche et de rédaction dans lesquels un agent collecte des données et un autre produit le contenu
- Tâches en plusieurs étapes nécessitant une expertise différente à chaque phase
- Tâches pour lesquelles vous devez contrôler finement le comportement de la délégation
Un agent parent qui coordonne des sous-agents est souvent appelé superviseur. Le modèle du superviseur constitue l’une des approches permettant de créer des systèmes multi-agents avec Mastra. Pour découvrir d’autres modèles, consultez la présentation conceptuelle.
Démarrage rapideLien direct vers Démarrage rapide
Définissez des sous-agents avec des descriptions claires, puis ajoutez-les à un agent parent :
import { Agent } from '@mastra/core/agent'
import { Memory } from '@mastra/memory'
import { LibSQLStore } from '@mastra/libsql'
const researchAgent = new Agent({
id: 'research-agent',
description: 'Gathers factual information and returns bullet-point summaries.',
model: 'openai/gpt-5-mini',
})
const writingAgent = new Agent({
id: 'writing-agent',
description: 'Transforms research into well-structured articles.',
model: 'openai/gpt-5-mini',
})
const parentAgent = new Agent({
id: 'parent-agent',
instructions: `You coordinate research and writing using specialized agents.
Delegate to research-agent for facts, then writing-agent for content.`,
model: 'openai/gpt-5.6-sol',
agents: { researchAgent, writingAgent },
memory: new Memory({
storage: new LibSQLStore({ id: 'storage', url: 'file:mastra.db' }),
}),
})
const stream = await parentAgent.stream('Research AI in education and write an article', {
maxSteps: 10,
})
for await (const chunk of stream.textStream) {
process.stdout.write(chunk)
}
Hooks de délégationLien direct vers Hooks de délégation
Les hooks de délégation permettent d’intercepter, de modifier ou de refuser les délégations au moment où elles se produisent. Configurez-les sous l’option delegation, soit dans les defaultOptions de l’agent, soit pour chaque appel.
onDelegationStartLien direct vers ondelegationstart
Appelé avant que l’agent parent ne délègue une tâche à un sous-agent. Renvoyez un objet pour contrôler la délégation :
proceed: true: autorise la délégation (comportement par défaut)proceed: false: refuse la délégation avec unrejectionReasonmodifiedPrompt: réécrit le prompt envoyé au sous-agentmodifiedMaxSteps: limite le nombre d’itérations du sous-agent
const stream = await parentAgent.stream('Research AI trends', {
maxSteps: 10,
delegation: {
onDelegationStart: async context => {
console.log(`Delegating to: ${context.primitiveId}`)
// Modify the prompt for a specific agent
if (context.primitiveId === 'research-agent') {
return {
proceed: true,
modifiedPrompt: `${context.prompt}\n\nFocus on 2024-2025 data.`,
modifiedMaxSteps: 5,
}
}
// Reject delegation after too many iterations
if (context.iteration > 8) {
return {
proceed: false,
rejectionReason: 'Max iterations reached. Synthesize current findings.',
}
}
return { proceed: true }
},
},
})
L’objet context contient :
| Propriété | Description |
|---|---|
primitiveId | ID du sous-agent auquel la tâche est déléguée |
prompt | Prompt envoyé par l’agent parent |
iteration | Numéro de l’itération actuelle |
requestContext | Contexte de requête que recevra l’exécution du sous-agent |
Contexte de requête à la frontière de délégationLien direct vers Contexte de requête à la frontière de délégation
Chaque délégation reçoit un contexte de requête dont les entrées sont copiées superficiellement depuis l’exécution parente, à l’exception des clés d’identité propres à l’exécution. La définition ou la suppression d’entrées pendant l’exécution du sous-agent n’affecte pas le contexte de l’agent parent. Définissez des entrées sur context.requestContext dans onDelegationStart pour transmettre des valeurs à l’exécution déléguée :
const stream = await parentAgent.stream('Research AI trends', {
maxSteps: 10,
delegation: {
onDelegationStart: async context => {
context.requestContext.set('audience', 'technical')
},
},
})
Le sous-agent lit ces entrées dans ses outils et sa configuration dynamique, par exemple instructions: ({ requestContext }) => .... Consultez la page Contexte de requête pour plus de détails. Les valeurs doivent être sérialisables en JSON pour fonctionner avec les agents durables.
onDelegationCompleteLien direct vers ondelegationcomplete
Appelé à la fin d’une délégation. Utilisez-le pour examiner les résultats, fournir un retour ou interrompre l’exécution :
context.bail(): arrête immédiatement la boucle de l’agent parent- Renvoyer
{ feedback: '...' }: ajoute un retour qui est enregistré dans la mémoire de l’agent parent et reste visible lors des itérations suivantes
const stream = await parentAgent.stream('Research AI trends', {
maxSteps: 10,
delegation: {
onDelegationComplete: async context => {
console.log(`Completed: ${context.primitiveId}`)
// Bail on errors
if (context.error) {
context.bail()
return {
feedback: `Delegation to ${context.primitiveId} failed: ${context.error}. Try a different approach.`,
}
}
},
},
})
L’objet context contient :
| Propriété | Description |
|---|---|
primitiveId | ID du sous-agent qui a été exécuté |
result | Réponse du sous-agent |
error | Erreur en cas d’échec de la délégation |
bail() | Fonction qui arrête la boucle de l’agent parent |
Filtrage des messagesLien direct vers Filtrage des messages
Par défaut, les sous-agents reçoivent l’intégralité du contexte de conversation de l’agent parent. Utilisez messageFilter pour contrôler les messages partagés, par exemple afin de supprimer des données sensibles ou de limiter la taille du contexte.
const stream = await parentAgent.stream('Research AI trends', {
maxSteps: 10,
delegation: {
messageFilter: ({ messages, primitiveId, prompt }) => {
// Remove messages containing sensitive data
return messages
.filter(msg => {
const content =
typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content)
return !content.includes('confidential')
})
.slice(-10) // Only pass the last 10 messages
},
},
})
La fonction de rappel reçoit messages (l’historique complet de la conversation), primitiveId (l’ID du sous-agent) et prompt (le prompt de délégation). Renvoyez le tableau de messages filtré.
Contexte du résultat du sous-agentLien direct vers Contexte du résultat du sous-agent
Lorsqu’un sous-agent termine son travail, le modèle de l’agent parent reçoit sa réponse textuelle lors des itérations suivantes. Les appels d’outils imbriqués et les métadonnées du sous-agent, comme les ID de thread et de ressource, ne sont pas ajoutés au contexte du modèle de l’agent parent.
Le code de l’application et les intégrations d’interface utilisateur peuvent néanmoins examiner subAgentToolResults ainsi que le reste du résultat brut de la délégation dans la charge utile du résultat de l’outil.
Les données de débogage et d’affichage restent ainsi disponibles, sans renvoyer les arguments ou les sorties des outils imbriqués au prochain appel du modèle de l’agent parent.
Définissez includeSubAgentToolResultsInModelContext pour inclure le résultat complet du sous-agent, notamment les résultats des outils imbriqués et les métadonnées du sous-agent, dans le contexte du modèle de l’agent parent.
await parentAgent.generate('Research AI trends', {
delegation: {
includeSubAgentToolResultsInModelContext: true,
},
})
Suivi des itérationsLien direct vers Suivi des itérations
onIterationComplete est appelé après chaque itération de la boucle de l’agent parent. Utilisez-le pour surveiller l’exécution ou guider l’itération suivante. Vous pouvez également interrompre l’exécution de manière anticipée.
const stream = await parentAgent.stream('Research AI trends', {
maxSteps: 10,
onIterationComplete: async context => {
console.log(`Iteration ${context.iteration}/${context.maxIterations}`)
console.log(`Finish reason: ${context.finishReason}`)
// Inject feedback to guide the agent
if (!context.text.includes('recommendations')) {
return {
continue: true,
feedback: 'Please include specific recommendations in your analysis.',
}
}
// Stop early when the response is sufficient
if (context.text.length > 1000 && context.finishReason === 'stop') {
return { continue: false }
}
return { continue: true }
},
})
Renvoyez { continue: true } pour poursuivre les itérations ou { continue: false } pour les arrêter. Ajoutez éventuellement feedback afin d’injecter des indications dans la conversation. Lorsque feedback est combiné à continue: false, le modèle peut bénéficier d’un dernier tour pour produire une réponse textuelle qui tient compte du retour, mais uniquement si l’itération actuelle est toujours active, par exemple après des appels d’outils. Dans le cas contraire, aucun tour supplémentaire n’est accordé.
Isolation de la mémoireLien direct vers Isolation de la mémoire
Mastra isole la mémoire des sous-agents pendant la délégation. Les sous-agents reçoivent l’intégralité du contexte de la conversation pour prendre de meilleures décisions, mais seuls leur prompt de délégation et leur réponse sont enregistrés dans leur mémoire.
Fonctionnement :
- Transmission du contexte complet : lorsque l’agent parent délègue une tâche, le sous-agent reçoit tous les messages de la conversation de l’agent parent.
- Enregistrements de mémoire limités : seuls le prompt de délégation et la réponse du sous-agent sont enregistrés dans la mémoire de ce dernier.
- Nouveau thread à chaque invocation : chaque délégation utilise un ID de thread unique, ce qui garantit une séparation nette.
Les sous-agents disposent ainsi du contexte nécessaire sans encombrer leur mémoire avec l’intégralité de la conversation de l’agent parent. Consultez la section Mémoire dans les systèmes multi-agents pour plus de détails.
Propagation de l’approbation des outilsLien direct vers Propagation de l’approbation des outils
Les approbations d’outils se propagent dans la chaîne de délégation. Lorsqu’un sous-agent utilise un outil avec requireApproval: true ou appelle suspend(), la demande d’approbation apparaît dans le flux de l’agent parent.
const sensitiveDataTool = createTool({
id: 'get-user-data',
requireApproval: true,
execute: async input => {
return await database.getUserData(input.userId)
},
})
const dataAgent = new Agent({
id: 'data-agent',
tools: { sensitiveDataTool },
})
const parentAgent = new Agent({
id: 'parent-agent',
agents: { dataAgent },
memory: new Memory(),
})
const stream = await parentAgent.stream('Get data for user 123')
for await (const chunk of stream.fullStream) {
if (chunk.type === 'tool-call-approval') {
console.log('Tool requires approval:', chunk.payload.toolName)
}
}
AnnulationLien direct vers Annulation
Lorsque vous transmettez un abortSignal à l’appel stream() ou generate() de l’agent parent, Mastra transmet ce même signal aux sous-agents délégués. L’appel de AbortController.abort() annule les exécutions de sous-agents en cours à leur prochaine étape, au lieu de les laisser aller jusqu’à leur terme.
const controller = new AbortController()
const stream = await parentAgent.stream('Research AI trends', {
abortSignal: controller.signal,
})
// Cancel the parent agent and any in-flight subagents
controller.abort()
Évaluation de l’achèvement des tâchesLien direct vers Évaluation de l’achèvement des tâches
Les agents ne produisent pas toujours une sortie complète et correcte dès la première tentative. Les évaluateurs d’achèvement peuvent vérifier si la tâche est terminée après chaque itération. Si la validation échoue, l’agent parent poursuit ses itérations. Le retour des évaluateurs ayant échoué est inclus dans le contexte de la conversation afin que les sous-agents puissent identifier les éléments manquants.
import { createScorer } from '@mastra/core/evals'
const taskCompleteScorer = createScorer({
id: 'task-complete',
name: 'Task Completeness',
}).generateScore(async context => {
const text = (context.run.output || '').toString()
const hasAnalysis = text.includes('analysis')
const hasRecommendations = text.includes('recommendation')
return hasAnalysis && hasRecommendations ? 1 : 0
})
const stream = await parentAgent.stream('Research AI in education', {
maxSteps: 10,
isTaskComplete: {
scorers: [taskCompleteScorer],
strategy: 'all',
onComplete: async result => {
console.log('Task complete:', result.complete)
},
},
})
Évaluateur par grilleLien direct vers Évaluateur par grille
L’évaluateur par grille intégré permet de définir ce qui est considéré comme « correct » sous la forme d’une liste de contrôle. L’agent peut alors s’autoévaluer et recommencer jusqu’à ce que tous les critères soient remplis ou que maxSteps soit atteint.
Il fonctionne comme un évaluateur LLM-as-judge. Après chaque itération, un modèle évaluateur distinct compare la sortie de l’agent à la grille. La boucle prend fin lorsque tous les critères obligatoires sont satisfaits. Lorsqu’un critère échoue, son retour est ajouté à la conversation afin que l’agent puisse réessayer.
Cette approche est particulièrement efficace pour les tâches dont les critères de réussite sont clairs et vérifiables. Vous pouvez l’utiliser comme suit :
import { Agent } from '@mastra/core/agent'
import { createRubricScorer } from '@mastra/evals/scorers/prebuilt'
const parentAgent = new Agent({
id: 'parent-agent',
instructions: 'You coordinate research and writing using specialized agents.',
model: 'openai/gpt-5.6-sol',
agents: { researchAgent, writingAgent },
})
const rubricScorer = createRubricScorer({
model: 'openai/gpt-5-mini',
criteria: [
{ description: 'The response includes an analysis section' },
{ description: 'The response includes concrete recommendations' },
],
})
const stream = await parentAgent.stream('Research AI in education', {
maxSteps: 10,
isTaskComplete: {
scorers: [rubricScorer],
strategy: 'all',
},
})
Pour tous les détails de l’API, consultez la référence de l’évaluateur par grille.
Rédiger des instructions efficacesLien direct vers Rédiger des instructions efficaces
Des instructions claires sont essentielles à une délégation efficace.
Les instructions de l’agent parent doivent préciser les ressources disponibles et indiquer quand utiliser chacune d’elles. Elles doivent également définir le comportement de coordination et les critères de réussite.
Chaque sous-agent doit disposer d’une description claire qui explique son rôle et son format de retour, ainsi que les situations dans lesquelles l’agent parent doit l’utiliser.
L’agent parent s’appuie sur ces descriptions pour prendre ses décisions de délégation.
const parentAgent = new Agent({
id: 'parent-agent',
instructions: `You coordinate research and writing tasks.
Available resources:
- researchAgent: Gathers factual data and sources (returns bullet points)
- writingAgent: Transforms research into narrative content (returns full paragraphs)
Delegation strategy:
1. For research requests: Delegate to researchAgent first
2. For writing requests: Delegate to writingAgent
3. For complex requests: Delegate to researchAgent first, then writingAgent
Success criteria:
- All user questions are fully answered
- Response is well-formatted and complete`,
agents: { researchAgent, writingAgent },
})
Exécuter des sous-agents en arrière-planLien direct vers Exécuter des sous-agents en arrière-plan
Les invocations de sous-agents sont envoyées sous forme d’appels d’outils et peuvent donc s’exécuter comme des tâches en arrière-plan. Cette approche est utile lorsqu’une ou plusieurs délégations sont longues et que vous ne souhaitez pas qu’elles bloquent la réponse de l’agent parent.
Activez le gestionnaire backgroundTasks sur l’instance Mastra, puis activez les sous-agents concernés sur l’agent parent :
const parentAgent = new Agent({
id: 'parent-agent',
instructions: 'Coordinate research and writing using the available agents.',
model: 'openai/gpt-5.6-sol',
agents: { researchAgent, writingAgent },
backgroundTasks: {
tools: {
researchAgent: { enabled: true, timeoutMs: 900_000 },
writingAgent: { enabled: true, timeoutMs: 900_000 },
},
},
})
const stream = await parentAgent.streamUntilIdle('Research AI in education and write an article', {
memory: { thread: 't1', resource: 'u1' },
})
Utilisez streamUntilIdle() au lieu de stream() afin que le flux reste ouvert jusqu’à la fin des sous-agents et que l’agent parent ait la possibilité de répondre à leurs résultats.
Si un sous-agent n’est pas répertorié dans les backgroundTasks.tools de l’agent parent, mais possède ses propres outils pouvant s’exécuter en arrière-plan, l’agent parent l’envoie tout de même comme tâche en arrière-plan et hérite de sa configuration. Consultez la section Hériter de la configuration du sous-agent pour plus de détails.
Versionnage des sous-agentsLien direct vers Versionnage des sous-agents
Lorsque vous utilisez l’éditeur, vous pouvez contrôler la version stockée de chaque sous-agent que l’agent parent utilise lors de l’exécution. Définissez les surcharges de version sur l’instance Mastra ou pour chaque invocation :
const result = await parentAgent.generate('Research and write about AI safety', {
versions: {
agents: {
'research-agent': { status: 'published' },
'writing-agent': { versionId: 'draft-456' },
},
},
})
Les surcharges de version se propagent automatiquement lors de la délégation. Consultez la section Versionnage des sous-agents pour en savoir plus sur l’ordre de résolution et l’utilisation de l’API du serveur.
Ressources associéesLien direct vers Ressources associées
- Tâches en arrière-plan
- Versionnage des sous-agents
- Guide : coordinateur de recherche
- Référence d’Agent.stream()
- Référence d’Agent.streamUntilIdle()
- Référence d’Agent.generate()
- Approbation des agents
- Mémoire dans les systèmes multi-agents
- Concept : systèmes multi-agents
- 📹 Atelier sur les agents superviseurs Mastra