> Discover all available pages from the documentation index: https://mastra.zisheng.pro/fr/llms.txt # Tâches en arrière-plan **Ajouté dans :** `@mastra/core@1.29.0` Les tâches en arrière-plan permettent à un agent de lancer un appel d’outil de longue durée sans bloquer la boucle agentique. L’outil renvoie immédiatement un accusé de réception, le LLM poursuit sa réponse et la tâche s’exécute jusqu’à son terme en arrière-plan. Lorsqu’elle se termine, son résultat est écrit dans la mémoire. Si vous utilisez `stream()` avec l’option [`untilIdle`](https://mastra.zisheng.pro/fr/reference/streaming/agents/stream), l’agent est automatiquement invoqué de nouveau afin que le résultat soit traité au cours du même appel. ## Quand utiliser les tâches en arrière-plan Utilisez les tâches en arrière-plan lorsqu’un appel d’outil risque de durer assez longtemps pour que l’utilisateur ne doive pas attendre sa fin avant de voir une réponse. Cas courants : - Délégations à des sous-agents qui effectuent eux-mêmes des recherches ou des travaux de rédaction en plusieurs étapes. - Appels d’outils qui sollicitent des services externes lents, des files d’attente ou des traitements portant sur de grands volumes de données. - Workflows déclenchés par un appel d’outil dont l’exécution peut prendre plusieurs minutes. Pour les appels d’outils qui renvoient rapidement un résultat, une exécution au premier plan avec `agent.stream()` et `agent.generate()` est plus simple. > **Remarque:** Les tâches en arrière-plan nécessitent un système de [stockage](https://mastra.zisheng.pro/fr/docs/storage/overview) configuré sur l’instance Mastra. Les tâches sont conservées afin de survivre aux redémarrages du processus. ## Démarrage rapide Les tâches en arrière-plan sont désactivées par défaut. Activez-les en définissant `backgroundTasks.enabled` sur l’instance Mastra : ```typescript import { Mastra } from '@mastra/core' import { LibSQLStore } from '@mastra/libsql' export const mastra = new Mastra({ storage: new LibSQLStore({ id: 'storage', url: 'file:mastra.db' }), backgroundTasks: { enabled: true, globalConcurrency: 10, perAgentConcurrency: 5, backpressure: 'queue', defaultTimeoutMs: 300_000, }, }) ``` La liste complète des options figure dans la [référence de configuration de backgroundTasks](https://mastra.zisheng.pro/fr/reference/configuration). ## Exécuter un outil en arrière-plan L’activation du gestionnaire ne lance à elle seule aucune exécution en arrière-plan, car tous les outils s’exécutent par défaut au premier plan. L’activation des outils s’effectue à l’un des deux niveaux suivants : 1. **Configuration au niveau de l’outil** : l’outil se déclare lui-même compatible avec l’exécution en arrière-plan. 2. **Configuration au niveau de l’agent** : l’agent déclare lesquels de ses outils sont compatibles avec l’exécution en arrière-plan. Une fois l’outil activé, le LLM peut ajouter un champ `_background` aux arguments de l’outil afin de remplacer facultativement la configuration résolue pour un appel donné : délai d’expiration, nouvelles tentatives ou retour de l’appel au premier plan. ### Au niveau de l’outil Définissez `background.enabled: true` dans la définition de l’outil. Les outils activés à ce niveau s’exécutent en arrière-plan chaque fois qu’ils sont appelés par un agent dont le gestionnaire est activé. ```typescript import { createTool } from '@mastra/core/tools' import { z } from 'zod' export const researchTool = createTool({ id: 'research', description: 'Run a long research job', inputSchema: z.object({ topic: z.string() }), background: { enabled: true, timeoutMs: 600_000, maxRetries: 1, }, execute: async ({ topic }) => { // Run the research job for topic }, }) ``` ### Au niveau de l’agent Utilisez `backgroundTasks.tools` sur l’agent pour activer certains outils, remplacer le délai d’expiration de chaque outil ou, à l’inverse, exécuter en arrière-plan tous les outils compatibles. Utilisez `disabled: true` pour désactiver entièrement le lancement en arrière-plan pour cet agent. ```typescript import { Agent } from '@mastra/core/agent' export const researcher = new Agent({ id: 'researcher', instructions: 'You research topics and answer questions.', model: 'openai/gpt-5.6-sol', tools: { researchTool, summarizeTool }, backgroundTasks: { tools: { researchTool: { enabled: true, timeoutMs: 600_000 }, summarizeTool: false, }, }, }) ``` Définissez `tools: 'all'` pour activer tous les outils de l’agent. ### Remplacement par le LLM pour chaque appel Lorsqu’un outil est enregistré auprès d’un agent dont les tâches en arrière-plan sont activées, le modèle peut inclure un champ `_background` dans les arguments de l’outil afin de remplacer la configuration résolue pour cet appel précis. Le modèle n’inclut que les éléments qu’il souhaite remplacer ; tous les champs de `_background` sont facultatifs. Ce remplacement est retiré des arguments avant l’exécution de l’outil. ```json { "topic": "solana", "_background": { "enabled": true, "timeoutMs": 900_000 } } ``` Le remplacement `_background` est un _modificateur_ applicable aux outils que le développeur a déjà activés au niveau de l’outil ou de l’agent ; il ne constitue pas une activation autonome. Si un outil n’a pas été activé, la valeur `_background.enabled: true` fournie par le modèle est ignorée et l’outil s’exécute au premier plan. Cela évite que des outils déterministes, réservés au premier plan — calculatrices, recherches ou validateurs de schéma — soient discrètement lancés comme tâches. ### Ordre de résolution Lorsqu’un appel d’outil est lancé, la configuration d’arrière-plan résolue est calculée selon l’ordre de priorité suivant : 1. Entrée `backgroundTasks.tools` de l’outil au niveau de l’agent. 2. Configuration `background` au niveau de l’outil. 3. Remplacement `_background.enabled` du LLM, utilisé uniquement pour activer le lancement en arrière-plan lorsque l’outil a été activé à l’un des niveaux précédents. 4. Valeurs par défaut du gestionnaire (`defaultTimeoutMs`, `defaultRetries`). Si l’agent possède `backgroundTasks.disabled: true`, chaque appel d’outil s’exécute de manière synchrone, quels que soient les niveaux précédents. ## Fragments de diffusion liés aux tâches en arrière-plan Lorsqu’un appel d’outil est lancé comme tâche en arrière-plan, deux flux peuvent exposer ses événements de cycle de vie : le propre flux de l’agent et le flux SSE de [`backgroundTaskManager.stream()`](https://mastra.zisheng.pro/fr/docs/long-running-agents/background-tasks). Chaque flux couvre un ensemble distinct de types de fragments : | Type de fragment | Moment de l’émission | Émis par | | --------------------------- | --------------------------------------------------------------------------------------------------------- | -------------------- | | `background-task-started` | La tâche a été placée dans la file d’attente et un `taskId` lui a été attribué. | Flux de l’agent | | `background-task-running` | Un processus de travail a pris en charge la tâche et commencé son exécution. | Flux du gestionnaire | | `background-task-progress` | Indique le nombre de tâches en arrière-plan en cours d’exécution. | Flux de l’agent | | `background-task-output` | Fragment de sortie diffusé par la fonction `execute` de la tâche. | Flux du gestionnaire | | `background-task-completed` | La tâche s’est terminée correctement. La valeur `payload.result` correspond au résultat final de l’outil. | Flux du gestionnaire | | `background-task-failed` | La tâche a levé une erreur ou dépassé son délai d’expiration. | Flux du gestionnaire | | `background-task-cancelled` | La tâche a été annulée avant son achèvement. | Flux du gestionnaire | | `background-task-suspended` | L’outil a appelé `suspend()` depuis sa fonction execute. | Flux du gestionnaire | | `background-task-resumed` | Une tâche suspendue a été reprise au moyen de `manager.resume(taskId, resumeData)`. | Flux du gestionnaire | À lui seul, `agent.stream().fullStream` n’émet que les fragments de la boucle de l’agent (`background-task-started`, `background-task-progress`). `agent.stream()` avec `untilIdle: true` émet ces deux mêmes fragments, s’abonne en outre au système pub-sub du gestionnaire pour la portée mémoire de l’exécution et achemine les sept fragments du gestionnaire (`background-task-running`, `background-task-output`, `background-task-completed`, `background-task-failed`, `background-task-cancelled`, `background-task-suspended`, `background-task-resumed`) vers le même `fullStream`. `backgroundTaskManager.stream()` n’émet que les sept fragments du gestionnaire. La structure complète des charges utiles est décrite dans la [référence des fragments de tâches en arrière-plan](https://mastra.zisheng.pro/fr/reference/streaming/ChunkType). ## Maintenir le flux de l’agent ouvert avec `untilIdle` `agent.stream()` renvoie dès que le LLM émet une réponse finale, même si une tâche en arrière-plan est toujours en cours. Transmettez `untilIdle: true` pour maintenir le flux ouvert jusqu’à ce que toutes les tâches en arrière-plan lancées soient terminées et que le LLM ait pu réagir au résultat : ```typescript const stream = await agent.stream('Research solana for me', { memory: { thread: 't1', resource: 'u1' }, untilIdle: true, }) for await (const chunk of stream.fullStream) { // chunks from the initial turn AND any continuation turns triggered by // background task completions flow through here } ``` Lorsqu’une tâche en arrière-plan se termine, son résultat est injecté dans la mémoire de l’agent et `stream()` réintègre la boucle agentique afin que le LLM puisse y réagir. Le flux se ferme lorsqu’aucune tâche n’est en cours et qu’aucun achèvement n’est en attente. Pour personnaliser le délai d’inactivité, transmettez un objet plutôt que `true`. Le minuteur ne s’exécute que lorsque l’enveloppe se trouve entre deux tours ; un premier jeton lent ne fermera donc pas le flux. La valeur par défaut est de 5 minutes : ```typescript const stream = await agent.stream('Research solana for me', { memory: { thread: 't1', resource: 'u1' }, untilIdle: { maxIdleMs: 30_000 }, }) ``` Consultez la [référence complète de `Agent.stream()`](https://mastra.zisheng.pro/fr/reference/streaming/agents/stream). ### Propriétés agrégées `stream()` avec `untilIdle` renvoie un `MastraModelOutput` semblable à celui d’un appel `stream()` ordinaire, mais seul `fullStream` couvre le tour initial et toutes les continuations automatiques. Les propriétés agrégées (`text`, `toolCalls`, `toolResults`, `finishReason`, `messageList`, `getFullOutput()`) sont toujours résolues à partir du tampon interne du **premier tour**. Si vous avez besoin d’une vue agrégée couvrant les continuations, consommez vous-même `fullStream` et cumulez les données. ## Sous-agents en arrière-plan En interne, les invocations de sous-agents sont lancées sous forme d’appels d’outils ; la même configuration d’arrière-plan s’applique donc. La méthode recommandée consiste à activer chaque sous-agent sur le superviseur : elle est plus claire et permet d’ajuster `timeoutMs` pour chaque sous-agent depuis un emplacement unique. ```typescript import { Agent } from '@mastra/core/agent' const supervisor = new Agent({ id: 'supervisor', 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 supervisor.stream('Research AI in education and write an article', { memory: { thread: 't1', resource: 'u1' }, untilIdle: true, }) ``` ### Héritage depuis le sous-agent Si un sous-agent ne figure pas dans `backgroundTasks.tools` du superviseur, mais possède ses propres outils compatibles avec l’exécution en arrière-plan — au moyen de `background.enabled: true` au niveau de l’outil ou de sa propre entrée `backgroundTasks.tools` — l’infrastructure logicielle lance malgré tout l’invocation complète du sous-agent comme tâche en arrière-plan. Le superviseur hérite de l’intention du sous-agent : le sous-agent devient lui-même la tâche en arrière-plan, tandis que ses outils internes s’exécutent au premier plan dans sa boucle. La configuration d’arrière-plan utilisée pour ce lancement hérité, par exemple `waitTimeoutMs`, provient de la propre configuration `backgroundTasks` du sous-agent. ```typescript const researchAgent = new Agent({ id: 'research-agent', description: 'Gathers factual information.', model: 'openai/gpt-5-mini', tools: { deepResearchTool }, backgroundTasks: { tools: { deepResearchTool: { enabled: true, timeoutMs: 600_000 }, }, waitTimeoutMs: 900_000, }, }) ``` Lorsque ce `researchAgent` reçoit une délégation d’un superviseur qui ne possède aucune configuration de tâche en arrière-plan pour `researchAgent`, le superviseur lance tout de même l’invocation complète de `researchAgent` comme tâche en arrière-plan. `deepResearchTool` s’exécute alors au premier plan au sein de cette invocation, au lieu de lancer sa propre tâche en arrière-plan imbriquée. Utilisez cette méthode lorsque vous souhaitez qu’un sous-agent adopte un comportement cohérent en arrière-plan, quel que soit le superviseur qui l’invoque. Utilisez l’activation côté superviseur décrite précédemment lorsque vous souhaitez ajuster de façon centralisée le comportement en arrière-plan pour chaque superviseur. ## Suspendre et reprendre Une tâche en arrière-plan peut se mettre en pause en cours d’exécution et attendre un signal externe avant de poursuivre. Cette possibilité est utile pour les validations humaines, les webhooks ou tout processus dont l’étape suivante dépend de données reçues ultérieurement. Un outil appelle `suspend(data)` depuis sa fonction `execute`, ce qui : - conserve `status: 'suspended'` et la charge utile `data` dans l’enregistrement de la tâche ; - enregistre l’instantané du workflow afin que l’exécution survive aux redémarrages du processus ; - émet un fragment `background-task-suspended` dans le flux du gestionnaire ; - libère l’emplacement d’exécution simultanée afin que d’autres tâches puissent s’exécuter. Reprenez la tâche avec `mastra.backgroundTaskManager.resume(taskId, resumeData)`. Les données `resumeData` sont transmises aux options `execute` de l’outil lors de l’exécution reprise, et la tâche repasse à l’état `running`. ```typescript import { createTool } from '@mastra/core/tools' import { z } from 'zod' export const reviewTool = createTool({ id: 'review', description: 'Submit a draft for human review.', inputSchema: z.object({ draft: z.string() }), outputSchema: z.object({ approvedBy: z.string(), edits: z.string().optional() }), background: { enabled: true }, execute: async ({ draft }, context) => { const { suspend, resumeData } = context.agent if (!resumeData) { await suspend?.({ awaiting: 'approval', draft }) return { approvedBy: '', edits: undefined } } const { reviewer, edits } = resumeData as { reviewer: string; edits?: string } return { approvedBy: reviewer, edits } }, }) ``` Lors de la première invocation de `execute`, `resumeData === undefined` est constaté et `suspend` est appelé. Après la reprise de la tâche, l’environnement d’exécution redémarre l’outil avec `resumeData` renseigné. La condition `if` est alors fausse et l’outil renvoie son résultat réel. Pour reprendre la tâche à la réception d’une validation : ```typescript await mastra.backgroundTaskManager?.resume(taskId, { reviewer: 'alice@example.com', edits: 'Reworded paragraph 3.', }) ``` ### Comportement de la boucle de l’agent Lorsqu’une tâche est suspendue au milieu d’un `stream()` avec `untilIdle`, l’enveloppe la considère comme terminée pour l’itération en cours et se ferme. Pour relancer immédiatement l’agent dès que la charge utile de reprise est disponible, appelez `agent.resumeStream(resumeData, { runId, toolCallId, memory, untilIdle: true })` : la tâche en arrière-plan reprise s’exécute jusqu’à son terme, son résultat est ajouté à la liste des messages et l’agent effectue un tour de suivi, le tout sur la même connexion SSE. Si vous préférez piloter la reprise hors bande, appelez directement `mastra.backgroundTaskManager.resume(taskId, resumeData)` ; le résultat sera tout de même écrit dans le fil afin d’être récupéré au prochain tour de l’utilisateur. ### Réenregistrer l’exécuteur lors de la reprise Le gestionnaire conserve les exécuteurs d’outils dans la mémoire du processus. Si le processus redémarre alors qu’une tâche est suspendue, la fermeture de l’exécuteur disparaît ; l’appelant de `resume()` doit donc d’abord le réenregistrer au moyen de `manager.registerTaskContext(taskId, ...)`. Cette opération n’est pas nécessaire pour les tâches lancées et reprises dans le même processus. ### Annuler une tâche suspendue `manager.cancel(taskId)` fonctionne sur les tâches suspendues de la même manière que sur celles en cours d’exécution. La ligne passe à l’état `cancelled` et l’instantané du workflow est supprimé. Un événement `task.cancelled` est ensuite émis. ## Fonctions de rappel du cycle de vie Chaque niveau peut enregistrer des fonctions de rappel pour les états finaux. Elles ne se remplacent pas mutuellement et les points d’extension de réussite ou d’échec sont déclenchés selon le résultat : - `background.onComplete` / `onFailed` au niveau de l’outil : portée limitée à un seul outil. - `backgroundTasks.onTaskComplete` / `onTaskFailed` au niveau de l’agent : portée limitée à toutes les tâches lancées par cet agent. - `onTaskComplete` / `onTaskFailed` au niveau du gestionnaire : portée globale. ```typescript export const mastra = new Mastra({ storage, backgroundTasks: { enabled: true, onTaskComplete: task => { logger.info('Background task complete', { taskId: task.id, toolName: task.toolName }) }, onTaskFailed: task => { logger.error('Background task failed', { taskId: task.id, error: task.error }) }, }, }) ``` ## Diffusion en continu ### S’abonner à tous les événements de tâche L’appel de `stream()` sans filtre renvoie un flux contenant tous les événements de tâche du système. Lors de la connexion, le flux émet un instantané de toutes les tâches en cours d’exécution, puis transmet les événements en direct à mesure qu’ils surviennent. ```typescript const bgManager = mastra.backgroundTaskManager if (!bgManager) throw new Error('Background tasks are not enabled') const controller = new AbortController() const stream = bgManager.stream({ abortSignal: controller.signal }) for await (const chunk of stream) { switch (chunk.type) { case 'background-task-running': console.log('started', chunk.payload.taskId, chunk.payload.toolName) break case 'background-task-completed': console.log('done', chunk.payload.taskId, chunk.payload.result) break case 'background-task-failed': console.error('failed', chunk.payload.taskId, chunk.payload.error) break } } ``` Le flux reste ouvert jusqu’au déclenchement de l’`AbortSignal` de l’appelant. Transmettez toujours un `abortSignal` afin de pouvoir vous déconnecter proprement. ### Filtrer le flux Transmettez toute combinaison d’options de filtrage pour restreindre les événements reçus. Les filtres s’appliquent à la fois à l’instantané initial et à l’abonnement aux événements en direct. ```typescript const stream = bgManager.stream({ agentId: 'researcher', threadId: 't1', resourceId: 'u1', abortSignal: controller.signal, }) ``` | Filtre | Description | | ------------- | ------------------------------------------------------------------ | | `agentId` | Uniquement les événements des tâches lancées par cet agent | | `runId` | Uniquement les événements de cette exécution précise de l’agent | | `threadId` | Uniquement les événements des tâches associées à ce fil de mémoire | | `resourceId` | Uniquement les événements des tâches associées à cette ressource | | `taskId` | Uniquement les événements d’une seule tâche | | `abortSignal` | Ferme le flux lorsque le signal est interrompu | ### Consulter directement l’état d’une tâche Pour des consultations ponctuelles plutôt qu’un flux en direct, utilisez `getTask` et `listTasks` : ```typescript const task = await mastra.backgroundTaskManager?.getTask(taskId) const { tasks, total } = await mastra.backgroundTaskManager?.listTasks({ status: 'running', agentId: 'researcher', }) ``` Ces méthodes lisent les données depuis le stockage plutôt que depuis le flux pub-sub ; elles conviennent donc aux listes paginées et aux vues détaillées. ## Voir aussi - [Référence de `Agent.stream()`](https://mastra.zisheng.pro/fr/reference/streaming/agents/stream) - [Référence de configuration de backgroundTasks](https://mastra.zisheng.pro/fr/reference/configuration) - [Agents durables](https://mastra.zisheng.pro/fr/docs/long-running-agents/durable-agents) - [Agents superviseurs](https://mastra.zisheng.pro/fr/docs/capabilities/subagents) - [Types de fragments de diffusion](https://mastra.zisheng.pro/fr/reference/streaming/ChunkType) - [Stockage](https://mastra.zisheng.pro/fr/docs/storage/overview)