Aller au contenu principal

Outils

Les agents utilisent des outils pour appeler des API, interroger des bases de données ou exécuter des fonctions personnalisées de votre base de code. Les outils leur offrent des capacités qui dépassent la génération de langage en fournissant un accès structuré aux données et en réalisant des opérations clairement définies. Vous pouvez également charger des outils depuis des serveurs MCP distants afin d’étendre les capacités d’un agent.

Quand utiliser des outils
Lien direct vers Quand utiliser des outils

Utilisez des outils lorsqu’un agent a besoin de contexte ou d’informations supplémentaires provenant de ressources distantes, ou lorsqu’il doit exécuter du code réalisant une opération précise. Cela inclut les tâches qu’un modèle ne peut pas effectuer seul de manière fiable, comme récupérer des données en temps réel ou renvoyer des résultats cohérents et clairement définis.

Démarrage rapide
Lien direct vers Démarrage rapide

Importez createTool depuis @mastra/core/tools, puis définissez un outil avec un id, une description, un inputSchema, un outputSchema et une fonction execute.

Cet exemple crée un outil qui récupère des données météorologiques depuis une API. La fonction execute reçoit en premier argument une entrée validée par rapport à inputSchema, puis un contexte d’exécution facultatif en second argument. Vous pouvez déstructurer les champs d’entrée directement dans la signature de la fonction.

src/mastra/tools/weather-tool.ts
import { createTool } from '@mastra/core/tools'
import { z } from 'zod'

export const weatherTool = createTool({
id: 'weather-tool',
description: 'Fetches weather for a location',
inputSchema: z.object({
location: z.string(),
}),
outputSchema: z.object({
location: z.string(),
temperatureCelsius: z.number(),
conditions: z.string(),
}),
execute: async ({ location }, { abortSignal }) => {
const response = await fetch(`https://wttr.in/${location}?format=j1`, {
signal: abortSignal,
})
const data = await response.json()

return {
location,
temperatureCelsius: Number(data.current_condition[0].temp_C),
conditions: data.current_condition[0].weatherDesc[0].value,
}
},
})

Lors de la création d’outils, utilisez des descriptions concises et centrées sur l’action de l’outil, en mettant en avant son cas d’utilisation principal. Des noms de schémas explicites peuvent également aider l’agent à comprendre comment utiliser l’outil. Consultez la référence de createTool pour en savoir plus sur les propriétés, configurations et exemples disponibles.

Pour mettre un outil à la disposition d’un agent, ajoutez-le à la propriété tools de la classe Agent. Mentionner les outils disponibles et leur objectif général dans le prompt système de l’agent aide celui-ci à déterminer quand appeler ou non un outil.

src/mastra/agents/weather-agent.ts
import { Agent } from '@mastra/core/agent'
import { weatherTool } from '../tools/weather-tool'

export const weatherAgent = new Agent({
id: 'weather-agent',
name: 'Weather Agent',
instructions: `
You are a helpful weather assistant.
Use the weatherTool to fetch current weather data.`,
model: 'openai/gpt-5.6-sol',
tools: { weatherTool },
})

Définir les schémas
Lien direct vers Définir les schémas

Vous pouvez définir les propriétés inputSchema et outputSchema de l’outil avec toute bibliothèque prenant en charge Standard JSON Schema. Cela inclut notamment Zod, Valibot et ArkType.

src/mastra/tools/weather-tool.ts
import { createTool } from '@mastra/core/tools'
import { z } from 'zod'

export const weatherTool = createTool({
id: 'weather-tool',
description: 'Fetches weather for a location',
inputSchema: z.object({
location: z.string(),
}),
outputSchema: z.object({
location: z.string(),
temperatureCelsius: z.number(),
conditions: z.string(),
}),
execute: async ({ location }) => {
return { location, temperatureCelsius: 21, conditions: 'sunny' }
},
})

Utiliser plusieurs outils
Lien direct vers Utiliser plusieurs outils

Un agent peut utiliser plusieurs outils pour traiter des tâches plus complexes en déléguant des parties précises à chacun d’eux. Il choisit les outils en fonction du message de l’utilisateur et de ses propres instructions, ainsi que des descriptions et schémas des outils.

src/mastra/agents/weather-agent.ts
import { Agent } from '@mastra/core/agent'
import { weatherTool } from '../tools/weather-tool'
import { hazardsTool } from '../tools/hazards-tool'

export const weatherAgent = new Agent({
id: 'weather-agent',
name: 'Weather Agent',
instructions: `
You are a helpful weather assistant.
Use the weatherTool to fetch current weather data.
Use the hazardsTool to provide information about potential weather hazards.`,
model: 'openai/gpt-5.6-sol',
tools: { weatherTool, hazardsTool },
})

Utiliser des agents comme outils
Lien direct vers Utiliser des agents comme outils

Ajoutez des sous-agents au moyen de la configuration agents afin de créer un superviseur. Mastra convertit chaque sous-agent en outil agent-<key>. Ajoutez une description à chaque sous-agent pour que le superviseur sache quand lui déléguer une tâche.

src/mastra/agents/supervisor.ts
import { Agent } from '@mastra/core/agent'

const writer = new Agent({
id: 'writer',
name: 'Writer',
description: 'Drafts and edits written content',
instructions: 'You are a skilled writer.',
model: 'openai/gpt-5.6-sol',
})

export const supervisor = new Agent({
id: 'supervisor',
name: 'Supervisor',
instructions: 'Coordinate the writer to produce content.',
model: 'openai/gpt-5.6-sol',
agents: { writer },
})

Utiliser des workflows comme outils
Lien direct vers Utiliser des workflows comme outils

Ajoutez des workflows au moyen de la configuration workflows. Mastra convertit chaque workflow en outil workflow-<key> qui utilise les propriétés inputSchema et outputSchema du workflow. Ajoutez une description au workflow pour que l’agent sache quand le déclencher.

src/mastra/agents/research-agent.ts
import { Agent } from '@mastra/core/agent'
import { researchWorkflow } from '../workflows/research-workflow'

export const researchAgent = new Agent({
id: 'research-agent',
name: 'Research Agent',
instructions: 'You are a research assistant.',
model: 'openai/gpt-5.6-sol',
workflows: { researchWorkflow },
})

Partager des outils entre les agents
Lien direct vers Partager des outils entre les agents

Les imports directs constituent le meilleur choix lorsqu’un même outil est utilisé par plusieurs agents. Chaque agent importe l’outil et l’ajoute à son objet tools. Les dépendances restent explicites et chaque agent peut être utilisé indépendamment.

src/mastra/tools/weather-tool.ts
import { createTool } from '@mastra/core/tools'

export const weatherTool = createTool({
id: 'weather-tool',
// Rest of the tool definition...
})
src/mastra/agents/weather-agents.ts
import { Agent } from '@mastra/core/agent'
import { weatherTool } from '../tools/weather-tool'

export const weatherAgent = new Agent({
id: 'weather-agent',
name: 'Weather Agent',
instructions: 'Answer questions about current weather.',
model: 'openai/gpt-5.6-sol',
tools: { weatherTool },
})
src/mastra/agents/travel-agents.ts
import { Agent } from '@mastra/core/agent'
import { weatherTool } from '../tools/weather-tool'

export const travelAgent = new Agent({
id: 'travel-agent',
name: 'Travel Agent',
instructions: 'Help users plan trips.',
model: 'openai/gpt-5.6-sol',
tools: { weatherTool },
})

Si vous devez accéder aux outils depuis l’instance Mastra, consultez Mastra.getTool(), Mastra.getToolById(), Mastra.listTools() ainsi que la référence de Agent.

Adapter la sortie destinée au modèle
Lien direct vers Adapter la sortie destinée au modèle

Utilisez toModelOutput lorsque votre outil renvoie à votre application des données structurées riches, mais que vous souhaitez fournir au modèle une représentation plus compacte ou multimodale. Le contexte du modèle reste ainsi ciblé tandis que le résultat complet de l’outil est conservé dans votre application.

src/mastra/tools/weather-tool.ts
export const weatherTool = createTool({
execute: async ({ location }) => {
const response = await fetch(`https://wttr.in/${location}?format=j1`)
const data = await response.json()

return {
location,
temperatureCelsius: Number(data.current_condition[0].temp_C),
conditions: data.current_condition[0].weatherDesc[0].value,
weatherIconUrl: data.current_condition[0].weatherIconUrl[0].value,
source: data,
}
},
toModelOutput: output => {
return {
type: 'content',
value: [
{
type: 'text',
text: `${output.location}: ${output.temperatureCelsius}°C and ${output.conditions}`,
},
{ type: 'image-url', url: output.weatherIconUrl },
],
}
},
})

toModelOutput fonctionne également avec les outils côté client transmis par clientTools. Le mappage s’exécute sur le client après l’outil, puis la sortie transformée est renvoyée au serveur avec le résultat brut.

Transformer les charges utiles des outils pour les interfaces et les transcriptions
Lien direct vers Transformer les charges utiles des outils pour les interfaces et les transcriptions

Utilisez transform lorsqu’un outil renvoie des données brutes dont votre application a besoin, mais que les flux destinés au navigateur ou les messages de transcription visibles par l’utilisateur doivent recevoir une forme plus compacte ou plus sûre. transform est distinct de toModelOutput : toModelOutput adapte la charge utile renvoyée au modèle, tandis que transform adapte les entrées, sorties, erreurs, charges utiles d’approbation et charges utiles de suspension des outils pour les cibles display et transcript.

Si une transformation est configurée et échoue, Mastra ne se rabat pas sur la charge utile brute pour les cibles d’affichage ou de transcription. Les deltas d’entrée sont supprimés lorsqu’aucune transformation inputDelta sûre n’est disponible.

Consultez la référence de createTool() pour obtenir un exemple de transform. Pour appliquer des règles communes à plusieurs outils, configurez la stratégie transform au niveau de l’agent dans le constructeur de Agent.

Exécuter une logique autour des appels d’outils
Lien direct vers Exécuter une logique autour des appels d’outils

Utilisez hooks pour exécuter une logique personnalisée avant et après chaque appel d’outil effectué par un agent. Les hooks s’appliquent à toutes les sources d’outils : outils attribués, outils de mémoire, ensembles d’outils, outils client, outils d’agents et de workflows, ainsi qu’aux outils de Workspace. Ils servent couramment à la journalisation, à l’audit, à la validation des entrées et au blocage de certains appels.

src/mastra/agents/support-agent.ts
import { Agent } from '@mastra/core/agent'

export const supportAgent = new Agent({
id: 'support-agent',
name: 'support-agent',
instructions: 'Help users with their questions.',
model: 'openai/gpt-5.6-sol',
hooks: {
beforeToolCall: ({ toolName, input }) => {
console.log(`Running ${toolName}`, input)
},
afterToolCall: ({ toolName, output, error }) => {
console.log(`Finished ${toolName}`, { output, error })
},
},
})

beforeToolCall s’exécute avant l’outil et reçoit le nom de l’outil, l’entrée et le contexte d’exécution. Renvoyez { proceed: false, output } pour ignorer entièrement l’appel d’outil ; l’agent reçoit alors output comme résultat de l’outil :

const guardedAgent = new Agent({
id: 'guarded-agent',
name: 'guarded-agent',
instructions: 'Run shell commands for the user.',
model: 'openai/gpt-5.6-sol',
hooks: {
beforeToolCall: ({ toolName, input }) => {
const command = (input as { command?: string }).command ?? ''
if (toolName === 'execute_command' && command.includes('rm -rf')) {
return { proceed: false, output: 'Command blocked by policy.' }
}
},
},
})

afterToolCall s’exécute une fois l’outil terminé, qu’il ait réussi ou échoué. En cas de réussite, il reçoit output ; si l’outil a levé une exception, il reçoit error à la place, puis l’erreur est relancée après l’exécution du hook.

Hooks propres à une exécution
Lien direct vers Hooks propres à une exécution

Transmettez hooks à .generate() ou .stream() pour définir des hooks pour une seule exécution. Les hooks propres à l’exécution remplacent les hooks correspondants définis au niveau de l’agent :

await supportAgent.generate('Look up the order status', {
hooks: {
beforeToolCall: ({ toolName }) => {
console.log(`This run only: ${toolName}`)
},
},
})

Les hooks définis au niveau de l’agent et ceux propres à l’exécution sont fusionnés clé par clé : si vous transmettez uniquement beforeToolCall lors de l’exécution, le hook afterToolCall de l’agent est conservé.

Diffusion en continu
Lien direct vers Diffusion en continu

Les outils prennent en charge des hooks de cycle de vie qui vous permettent de surveiller les différentes phases de leur exécution pendant la diffusion en continu. Ces hooks sont particulièrement utiles pour la journalisation ou l’analyse.

Pour une utilisation générique de l’API writer, consultez la page Diffusion en continu.

Hooks disponibles
Lien direct vers Hooks disponibles

  • onInputStart : appelé lorsque commence la diffusion en continu de l’entrée de l’appel d’outil
  • onInputDelta : appelé pour chaque fragment d’entrée reçu au fil de la diffusion
  • onInputAvailable : appelé lorsque l’entrée complète a été analysée et validée
  • onOutput : appelé après l’exécution réussie de l’outil, avec sa sortie

Pour obtenir une documentation détaillée sur tous les hooks de cycle de vie, consultez la référence de createTool().

Exemple : utiliser onInputAvailable et onOutput
Lien direct vers example-using-oninputavailable-and-onoutput

import { createTool } from '@mastra/core/tools'
import { z } from 'zod'

export const weatherTool = createTool({
id: 'weather-tool',
description: 'Get weather information',
inputSchema: z.object({
location: z.string(),
}),
outputSchema: z.object({
location: z.string(),
temperatureCelsius: z.number(),
conditions: z.string(),
}),
// Called when the complete input is available
onInputAvailable: ({ input, toolCallId }) => {
console.log(`Weather requested for: ${input.location}`)
},
execute: async ({ location }) => {
const weather = await fetchWeather(location)
return weather
},
// Called after successful execution
onOutput: ({ output, toolName }) => {
console.log(`${toolName} result: ${output.temperatureCelsius}°C, ${output.conditions}`)
},
})

Diffuser l’entrée d’un outil dans une interface utilisateur
Lien direct vers Diffuser l’entrée d’un outil dans une interface utilisateur

Lorsqu’un modèle génère un appel d’outil, les arguments arrivent progressivement sous forme de fragments de flux tool-call-delta, avant le fragment tool-call final. Les interfaces utilisateur peuvent écouter les événements correspondants tool_input_start, tool_input_delta et tool_input_end afin d’afficher les arguments de l’outil à mesure qu’ils arrivent. Elles peuvent par exemple montrer immédiatement un chemin de fichier ou une commande, sans attendre l’appel d’outil complet.

L’utilisation d’un analyseur JSON partiel sur les fragments argsTextDelta accumulés permet d’extraire des valeurs d’arguments exploitables avant que le JSON soit complet. Elle rend possibles des fonctionnalités telles que la prévisualisation en direct des différences pour les outils de modification, la diffusion continue du contenu des fichiers pour les outils d’écriture et l’affichage instantané des motifs de recherche ou des chemins de fichiers.

Contrôler la sélection des outils
Lien direct vers Contrôler la sélection des outils

Transmettez toolChoice ou activeTools à .generate() ou .stream() pour contrôler les outils utilisés par l’agent au moment de l’exécution.

await agent.generate('Check the forecast', {
toolChoice: 'required',
activeTools: ['weatherTool'],
})

Consultez la référence de Agent.generate() pour découvrir toutes les options d’exécution, notamment toolsets, clientTools et prepareStep.

Contrôler toolName dans les réponses du flux
Lien direct vers control-toolname-in-stream-responses

La valeur de toolName dans les réponses du flux est déterminée par la clé de l’objet que vous utilisez, et non par la propriété id de l’outil, de l’agent ou du workflow.

export const weatherTool = createTool({
id: 'weather-tool',
})

// Using the variable name as the key
tools: { weatherTool }
// Stream returns: toolName: "weatherTool"

// Using the tool's id as the key
tools: { [weatherTool.id]: weatherTool }
// Stream returns: toolName: "weather-tool"

// Using a custom key
tools: { "my-custom-name": weatherTool }
// Stream returns: toolName: "my-custom-name"

Vous pouvez ainsi définir la façon dont les outils sont identifiés dans le flux. Si vous souhaitez que toolName corresponde à l’id de l’outil, utilisez l’id de l’outil comme clé de l’objet.

Sous-agents et workflows utilisés comme outils
Lien direct vers Sous-agents et workflows utilisés comme outils

Les sous-agents et les workflows suivent le même modèle. Ils sont convertis en outils dont le nom associe un préfixe à la clé de votre objet :

PropriétéPréfixeExemple de clétoolName
agentsagent-weatheragent-weather
workflowsworkflow-researchworkflow-research
const orchestrator = new Agent({
id: 'orchestrator',
agents: {
weather: weatherAgent, // toolName: "agent-weather"
},
workflows: {
research: researchWorkflow, // toolName: "workflow-research"
},
})

Pour les sous-agents, deux identifiants différents apparaissent dans les réponses du flux :

  • toolName: "agent-weather" dans les événements d’appel d’outil : le nom généré de l’outil d’encapsulation
  • id: "weather-agent" dans les fragments data-tool-agent : la propriété id réelle du sous-agent

Outils intégrés
Lien direct vers Outils intégrés

Mastra inclut dans @mastra/core/tools des outils intégrés indépendants des agents, qui ajoutent des capacités interactives et organisationnelles à n’importe quel agent.

OutilObjectif
ask_userPoser une question à l’utilisateur et attendre sa réponse
submit_planSoumettre un fichier de plan à l’approbation de l’utilisateur
task_writeCréer ou remplacer une liste de tâches structurée
task_updateMettre à jour une tâche suivie à partir de son identifiant
task_completeMarquer une tâche suivie comme terminée
task_checkVérifier l’état d’achèvement de la liste de tâches
webSearchToolExécuter la recherche web native du fournisseur avec le modèle actif
webFetchToolRécupérer une page web par URL et renvoyer son contenu textuel

Importez webSearchTool depuis @mastra/core/tools lorsque vous souhaitez que le fournisseur du modèle exécute son outil natif de recherche web. Mastra le résout au moment de l’exécution à partir du modèle actif, puis transmet au modèle l’outil géré par le fournisseur.

src/mastra/agents/research-agent.ts
import { Agent } from '@mastra/core/agent'
import { webSearchTool } from '@mastra/core/tools'

export const researchAgent = new Agent({
id: 'research-agent',
name: 'Research Agent',
instructions: 'Use web search when you need current information.',
model: 'openai/gpt-5.6-sol',
tools: {
search: webSearchTool,
},
})

webSearchTool prend en charge les modèles OpenAI, Anthropic, Google Gemini et xAI. Si Mastra ne peut pas déduire l’un de ces fournisseurs à partir du modèle actif, l’exécution de l’agent échoue avec une MastraError.

La clé search n’est que le nom local de l’outil dans l’agent. Vous pouvez utiliser n’importe quelle clé. La valeur webSearchTool indique à Mastra d’utiliser la recherche web du fournisseur.

Récupérer une page web
Lien direct vers Récupérer une page web

Importez webFetchTool depuis @mastra/core/tools lorsque l’agent doit lire une URL précise. L’outil demande la page via HTTP ou HTTPS et renvoie son contenu textuel ainsi que les métadonnées de la réponse.

src/mastra/agents/reader-agent.ts
import { Agent } from '@mastra/core/agent'
import { webFetchTool } from '@mastra/core/tools'

export const readerAgent = new Agent({
id: 'reader-agent',
name: 'Reader Agent',
instructions: 'Fetch the page the user links to before answering.',
model: 'openai/gpt-5.6-sol',
tools: {
fetch: webFetchTool,
},
})

L’outil accepte une seule entrée url et renvoie content, truncated, status, statusText, contentType, url et ok. Il applique les limites suivantes :

  • Seules les URL http: et https: sont autorisées.
  • Les requêtes vers localhost et vers des adresses IP privées ou réservées sont bloquées, y compris les adresses renvoyées par la résolution DNS.
  • Les réponses sont tronquées à 100 000 caractères, avec truncated: true dans le résultat.
  • Les requêtes suivent au maximum 5 redirections et expirent après 15 secondes.

Les échecs ne lèvent pas d’exception. L’outil renvoie isError: true avec le motif dans content, afin que l’agent puisse réessayer ou expliquer le problème.

Poser une question à l’utilisateur
Lien direct vers Poser une question à l’utilisateur

Importez askUserTool et ajoutez-le à l’ensemble d’outils de l’agent.

L’outil suspend l’exécution et émet un événement tool-call-suspended contenant la question. L’exécution reprend lorsque vous appelez resumeStream() avec la réponse de l’utilisateur.

src/mastra/agents/index.ts
import { Agent } from '@mastra/core/agent'
import { askUserTool } from '@mastra/core/tools'

const agent = new Agent({
id: 'assistant',
name: 'Assistant',
instructions: 'Ask the user for clarification when the request is ambiguous.',
model,
tools: { askUserTool },
})

Diffusez la réponse de l’agent et surveillez les fragments tool-call-suspended. Le suspendPayload contient la question et les choix structurés facultatifs :

src/run.ts
const stream = await agent.stream('Summarize my project')

for await (const chunk of stream.fullStream) {
if (chunk.type === 'tool-call-suspended') {
const { question, options } = chunk.payload.suspendPayload
console.log(question)
const answer = await getUserAnswer() // your UI logic
const resumed = await agent.resumeStream(answer, { runId: stream.runId })
for await (const c of resumed.textStream) process.stdout.write(c)
}
}

askUserTool prend en charge les prompts en texte libre, à sélection unique (tableau options) et à sélection multiple (selectionMode: 'multi_select'). Associez-le à autoResumeSuspendedTools afin que l’agent reprenne automatiquement à partir du message de chat suivant de l’utilisateur. Consultez la page Reprise automatique des outils pour plus de détails.

Soumettre un plan à réviser
Lien direct vers Soumettre un plan à réviser

Importez submitPlanTool pour permettre à l’agent d’écrire un plan dans un fichier et de le soumettre à l’utilisateur pour révision. L’outil suspend l’exécution jusqu’à ce que l’utilisateur l’approuve ou le refuse :

src/run.ts
for await (const chunk of stream.fullStream) {
if (chunk.type === 'tool-call-suspended' && chunk.payload.toolName === 'submit_plan') {
const { path } = chunk.payload.suspendPayload
// Read and display the plan file, then resume:
const resumed = await agent.resumeStream({ action: 'approved' }, { runId: stream.runId })
for await (const c of resumed.textStream) process.stdout.write(c)
}
}

Suivi des tâches
Lien direct vers Suivi des tâches

Les outils de tâches gèrent une liste de tâches structurée et durable pour une exécution d’agent. Ils nécessitent la mémoire afin que la liste soit conservée dans un stockage propre au thread.

Ajoutez le suivi des tâches au moyen de TaskSignalProvider, qui regroupe les quatre outils et le TaskStateProcessor dans une seule inscription :

src/mastra/agents/index.ts
import { Agent } from '@mastra/core/agent'
import { Memory } from '@mastra/memory'
import { TaskSignalProvider } from '@mastra/core/signals'

const agent = new Agent({
id: 'coder',
name: 'Coder',
instructions: 'Track your progress with the task tools.',
model,
memory: new Memory(),
signals: [new TaskSignalProvider()],
})

Une seule tâche peut avoir l’état in_progress à la fois. La liste est stockée dans le domaine de stockage threadState propre au thread et projetée sur le canal state-signal de l’agent, de sorte qu’elle survive à la troncature de la mémoire observationnelle. Consultez la référence des outils de tâches pour obtenir les schémas complets.

AgentController inclut automatiquement tous les outils intégrés dans chaque mode ; vous n’avez donc pas besoin de les ajouter manuellement. Consultez la page Approbation des outils pour connaître le comportement propre à AgentController.