Aller au contenu principal

Contexte de requête

Les agents, les outils et les workflows peuvent tous accepter RequestContext comme paramètre, ce qui rend les valeurs propres à la requête accessibles aux primitives sous-jacentes.

Quand utiliser RequestContext
Lien direct vers when-to-use-requestcontext

Utilisez RequestContext lorsque le comportement d'une primitive doit varier selon les conditions d'exécution. Vous pouvez, par exemple, changer de modèle ou de système de stockage en fonction des attributs de l'utilisateur, ou adapter les instructions et la sélection des outils selon la langue.

remarque

RequestContext sert principalement à transmettre des données à des requêtes précises. Il se distingue de la mémoire de l'agent, qui gère l'historique de la conversation et la persistance de l'état entre plusieurs appels.

Définir des valeurs
Lien direct vers Définir des valeurs

Transmettez requestContext à un appel d'agent, de réseau, de workflow ou d'outil afin de rendre les valeurs accessibles à toutes les primitives sous-jacentes pendant l'exécution. Utilisez .set() pour définir les valeurs avant l'appel.

La méthode .set() accepte deux arguments :

  1. clé : nom servant à identifier la valeur.
  2. valeur : données à associer à cette clé.
import { RequestContext } from '@mastra/core/request-context'

export type UserTier = {
'user-tier': 'enterprise' | 'pro'
}

const requestContext = new RequestContext<UserTier>()
requestContext.set('user-tier', 'enterprise')

const agent = mastra.getAgent('weatherAgent')
await agent.generate("What's the weather in London?", {
requestContext,
})

const routingAgent = mastra.getAgent('routingAgent')
routingAgent.network("What's the weather in London?", {
requestContext,
})

const run = await mastra.getWorkflow('weatherWorkflow').createRun()
await run.start({
inputData: {
location: 'London',
},
requestContext,
})
await run.resume({
resumeData: {
city: 'New York',
},
requestContext,
})

await weatherTool.execute({ location: 'London' }, { requestContext })

Définir des valeurs à partir des en-têtes de requête
Lien direct vers Définir des valeurs à partir des en-têtes de requête

Vous pouvez renseigner requestContext dans un middleware du serveur à l'exécution en extrayant des informations de la requête. Dans cet exemple, temperature-unit est défini selon l'en-tête Cloudflare CF-IPCountry afin que les réponses correspondent aux paramètres régionaux de l'utilisateur.

src/mastra/index.ts
import { Mastra } from '@mastra/core'
import { RequestContext } from '@mastra/core/request-context'
import { testWeatherAgent } from './agents/test-weather-agent'

export const mastra = new Mastra({
agents: { testWeatherAgent },
server: {
middleware: [
async (context, next) => {
const country = context.req.header('CF-IPCountry')
const requestContext = context.get('requestContext')

requestContext.set('temperature-unit', country === 'US' ? 'fahrenheit' : 'celsius')

await next()
},
],
},
})

Consultez Middleware pour découvrir comment utiliser les middlewares du serveur.

Studio
Lien direct vers Studio

Lors du développement local, vous pouvez définir des préréglages dans un fichier JSON et les charger dans Studio avec l'option CLI --request-context-presets. Une liste déroulante est alors ajoutée à l'éditeur de contexte de requête dans Studio, ce qui permet de passer rapidement d'une configuration à l'autre sans modifier manuellement le JSON à chaque fois.

mastra dev --request-context-presets ./presets.json
presets.json
{
"development": { "userId": "dev-user", "env": "development" },
"production": { "userId": "prod-user", "env": "production" }
}

Lorsque vous sélectionnez un préréglage dans la liste déroulante, l'éditeur JSON est renseigné avec ses valeurs. Si vous modifiez le JSON manuellement, la liste revient à l'option « Personnalisé ».

Accéder aux valeurs avec des agents
Lien direct vers Accéder aux valeurs avec des agents

Vous pouvez accéder à l'argument requestContext depuis toutes les options de configuration prises en charge par les agents. Ces fonctions peuvent être synchrones ou async. Utilisez la méthode .get() pour lire les valeurs de requestContext.

src/mastra/agents/weather-agent.ts
export type UserTier = {
'user-tier': 'enterprise' | 'pro'
}

export const weatherAgent = new Agent({
id: 'weather-agent',
name: 'Weather Agent',
instructions: async ({ requestContext }) => {
const userTier = requestContext.get('user-tier') as UserTier['user-tier']

if (userTier === 'enterprise') {
}
},
model: ({ requestContext }) => {},
tools: ({ requestContext }) => {},
memory: ({ requestContext }) => {},
})

Vous pouvez également utiliser requestContext avec d'autres options telles que agents, workflows, scorers, inputProcessors et outputProcessors.

Instructions dynamiques
Lien direct vers Instructions dynamiques

Les instructions d'un agent peuvent être fournies sous forme de fonction asynchrone, ce qui permet de déterminer les prompts lors de l'exécution. Associée à requestContext, cette approche permet notamment les scénarios suivants :

  • Personnalisation : adapter les instructions aux attributs, préférences ou niveau de l'utilisateur
  • Localisation : ajuster le ton, la langue ou le comportement selon les paramètres régionaux
  • Tests A/B : proposer différentes variantes de prompts à des fins d'expérimentation
  • Gestion externe des prompts : récupérer des prompts depuis des services de registre sans redéployer l'application
src/mastra/agents/dynamic-agent.ts
import { Agent } from '@mastra/core/agent'

export const dynamicAgent = new Agent({
id: 'dynamic-agent',
name: 'Dynamic Agent',
instructions: async ({ requestContext }) => {
const userTier = requestContext?.get('user-tier')
const locale = requestContext?.get('locale')

// Personalize based on user tier
const basePrompt =
userTier === 'enterprise'
? 'You are a premium support agent. Provide detailed, thorough responses with technical depth.'
: 'You are a helpful assistant. Be concise and friendly.'

// Localize behavior
const localeInstructions = locale === 'ja' ? 'Respond in Japanese using formal keigo.' : ''

return `${basePrompt} ${localeInstructions}`.trim()
},
model: 'openai/gpt-5.6-sol',
})

Récupérer les prompts depuis un registre
Lien direct vers Récupérer les prompts depuis un registre

Si votre organisation utilise un service de registre pour centraliser la gestion des prompts, vous pouvez récupérer les instructions lors de l'exécution. Vous pouvez ainsi mettre à jour les prompts sans redéployer l'application, mener des expériences avec différentes variantes et suivre leur utilisation dans vos agents.

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

// Your prompt registry client
import { promptRegistry } from '../lib/prompt-registry'

export const registryAgent = new Agent({
id: 'registry-agent',
name: 'Registry Agent',
instructions: async ({ requestContext }) => {
const prompt = await promptRegistry.getPrompt({
promptId: 'customer-support-agent',
// Pass context for variant selection or tracking
variant: requestContext?.get('experiment-variant'),
userId: requestContext?.get('user-id'),
})

return prompt.content
},
model: 'openai/gpt-5.6-sol',
})

Consultez Agent pour obtenir la liste complète des options de configuration.

Accéder aux valeurs depuis les étapes d'un workflow
Lien direct vers Accéder aux valeurs depuis les étapes d'un workflow

Vous pouvez accéder à l'argument requestContext depuis la fonction execute d'une étape de workflow. Cette fonction peut être synchrone ou asynchrone. Utilisez la méthode .get() pour lire les valeurs de requestContext.

src/mastra/workflows/weather-workflow.ts
export type UserTier = {
'user-tier': 'enterprise' | 'pro'
}

const stepOne = createStep({
id: 'step-one',
execute: async ({ requestContext }) => {
const userTier = requestContext.get('user-tier') as UserTier['user-tier']

if (userTier === 'enterprise') {
}
},
})

Consultez createStep() pour obtenir la liste complète des options de configuration.

Accéder aux valeurs avec des outils
Lien direct vers Accéder aux valeurs avec des outils

Vous pouvez accéder à l'argument requestContext depuis la fonction execute d'un outil. Cette fonction est async. Utilisez la méthode .get() pour lire les valeurs de requestContext.

src/mastra/tools/weather-tool.ts
export type UserTier = {
'user-tier': 'enterprise' | 'pro'
}

export const weatherTool = createTool({
id: 'weather-tool',
execute: async (inputData, context) => {
const userTier = context?.requestContext?.get('user-tier') as UserTier['user-tier'] | undefined

if (userTier === 'enterprise') {
}
},
})

Consultez createTool() pour obtenir la liste complète des options de configuration.

Clés réservées
Lien direct vers Clés réservées

Mastra réserve certaines clés de contexte à des fins de sécurité. Lorsqu'elles sont définies, elles sont prioritaires sur les valeurs fournies par le client. Le serveur valide automatiquement la propriété des ressources et renvoie une erreur 403 lorsque des utilisateurs tentent d'accéder à des ressources qui ne leur appartiennent pas.

La manière la plus simple de définir MASTRA_RESOURCE_ID_KEY consiste à utiliser la fonction de rappel mapUserToResourceId dans la configuration d'authentification :

auth: {
authenticateToken: async token => verifyToken(token),
mapUserToResourceId: user => user.id,
}

Lorsque l'ID de ressource est déterminé de cette manière, les clients peuvent omettre memory.resource du corps des requêtes de génération et de streaming de l'agent. La valeur déterminée par le serveur est utilisée à la place et reste toujours prioritaire sur toute valeur fournie par le client. Si une requête utilise la mémoire et que ni son corps ni son contexte ne fournissent d'ID de ressource, le serveur renvoie une erreur 400.

Vous pouvez également définir ces clés manuellement dans un middleware :

import { MASTRA_RESOURCE_ID_KEY, MASTRA_THREAD_ID_KEY } from '@mastra/core/request-context'

// In middleware: force memory operations to use authenticated user's ID
requestContext.set(MASTRA_RESOURCE_ID_KEY, user.id)

// In middleware: set validated thread ID
requestContext.set(MASTRA_THREAD_ID_KEY, threadId)
CléFonction
MASTRA_RESOURCE_ID_KEYForce toutes les opérations de mémoire à utiliser cet ID de ressource. Le serveur vérifie que les threads consultés appartiennent à cette ressource et renvoie une erreur 403 dans le cas contraire.
MASTRA_THREAD_ID_KEYForce les opérations sur les threads à utiliser cet ID de thread, en remplaçant les valeurs fournies par le client.

Ces clés servent à mettre en œuvre l'isolation des utilisateurs dans les applications mutualisées. Consultez Middleware d'autorisation pour voir des exemples d'utilisation.

Prise en charge de TypeScript
Lien direct vers Prise en charge de TypeScript

Lorsque vous fournissez un paramètre de type à RequestContext, toutes les méthodes sont entièrement typées :

import { RequestContext } from '@mastra/core/request-context'

type MyContext = {
userId: string
maxTokens: number
isPremium: boolean
}

const ctx = new RequestContext<MyContext>()

// set() enforces correct value types
ctx.set('userId', 'user-123') // ✓ valid
ctx.set('maxTokens', 4096) // ✓ valid
ctx.set('maxTokens', 'wrong') // ✗ TypeScript error: expected number

// get() returns the correct type automatically
const tokens = ctx.get('maxTokens') // inferred as number
const id = ctx.get('userId') // inferred as string

// keys() returns typed keys
for (const key of ctx.keys()) {
// key is "userId" | "maxTokens" | "isPremium"
}

// entries() supports type narrowing
for (const [key, value] of ctx.entries()) {
if (key === 'maxTokens') {
// TypeScript knows value is number here
console.log(value.toFixed(2))
}
if (key === 'userId') {
// TypeScript knows value is string here
console.log(value.toUpperCase())
}
}

Validation du schéma
Lien direct vers Validation du schéma

Utilisez requestContextSchema pour définir un schéma JSON standard (Zod, Valibot, ArkType, etc.) qui valide les valeurs du contexte de requête lors de l'exécution. Cela permet de détecter rapidement les valeurs de contexte absentes ou non valides, de fournir des messages d'erreur clairs et de bénéficier de l'inférence de types dans votre composant.

Validation du schéma d'un agent
Lien direct vers Validation du schéma d'un agent

Lorsque vous définissez requestContextSchema sur un agent, le contexte est validé au début de generate() ou de stream(). Si la validation échoue, l'agent lève une MastraError avant tout appel au LLM.

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

export const validatedAgent = new Agent({
id: 'validated-agent',
name: 'Validated Agent',
requestContextSchema: z.object({
userId: z.string(),
apiKey: z.string(),
}),
instructions: ({ requestContext }) => {
// Access all values as a typed object
const { userId, apiKey } = requestContext.all
// { userId: string; apiKey: string }

// Or retrieve individual values with .get()
const id = requestContext.get('userId')
// string

return `You are helping user ${userId}`
},
model: 'openai/gpt-5.6-sol',
})

Lorsque la validation échoue, l'erreur comprend l'ID de l'agent et le détail des champs concernés :

Request context validation failed for agent 'validated-agent':
- apiKey: Required

Validation du schéma d'un outil
Lien direct vers Validation du schéma d'un outil

Lorsque vous définissez requestContextSchema sur un outil, le contexte est validé avant l'exécution de execute(). Contrairement aux agents, les outils renvoient un objet d'erreur de validation au lieu de lever une exception :

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

export const validatedTool = createTool({
id: 'validated-tool',
description: 'A tool that requires authenticated context',
inputSchema: z.object({
query: z.string(),
}),
requestContextSchema: z.object({
userId: z.string(),
}),
execute: async (inputData, context) => {
// Access all values as a typed object
const { userId } = context.requestContext?.all ?? {}
// { userId: string }

// Or retrieve individual values with .get()
const id = context.requestContext?.get('userId')
// string | undefined

return { result: `Processed for ${userId}` }
},
})

Lorsque la validation échoue, l'outil renvoie un objet d'erreur au lieu de lever une exception :

{
"error": true,
"message": "Request context validation failed for validated-tool. Please fix the following errors and try again:\n- userId: Required\n\nProvided context: {}"
}

Validation du schéma d'un workflow
Lien direct vers Validation du schéma d'un workflow

Lorsque vous définissez requestContextSchema sur un workflow, le contexte est validé au début de run.start(). Si la validation échoue, le workflow lève une erreur avant l'exécution de toute étape.

src/mastra/workflows/validated-workflow.ts
import { createWorkflow, createStep } from '@mastra/core/workflows'
import { z } from 'zod'

// Define schema once and share between workflow and steps
const workflowContextSchema = z.object({
tenantId: z.string(),
})

const step1 = createStep({
id: 'step-1',
inputSchema: z.object({ message: z.string() }),
outputSchema: z.object({ result: z.string() }),
// Add schema to step for type inference
requestContextSchema: workflowContextSchema,
execute: async ({ inputData, requestContext }) => {
// Access all values as a typed object
const { tenantId } = requestContext.all
// { tenantId: string }

// Or retrieve individual values with .get()
const id = requestContext.get('tenantId')
// string

return { result: `Processed for tenant ${tenantId}` }
},
})

export const validatedWorkflow = createWorkflow({
id: 'validated-workflow',
inputSchema: z.object({ message: z.string() }),
outputSchema: z.object({ result: z.string() }),
requestContextSchema: workflowContextSchema,
})
.then(step1)
.commit()

Lorsque la validation échoue, le workflow lève une erreur :

Request context validation failed for workflow 'validated-workflow':
- tenantId: Required

Les étapes peuvent également définir leur propre requestContextSchema pour une validation à leur niveau. Cette validation s'exécute avant la fonction execute() de l'étape.

Comportement de la validation
Lien direct vers Comportement de la validation

ComposantPropriétéMoment de la validationEn cas d'échec
AgentrequestContextSchemaDébut de generate() / stream()Lève une MastraError
OutilrequestContextSchemaAvant execute()Renvoie un objet d'erreur
WorkflowrequestContextSchemaDébut de run.start()Lève une Error
ÉtaperequestContextSchemaAvant execute() pour l'étapeL'étape échoue avec une erreur

Bonnes pratiques
Lien direct vers Bonnes pratiques

Faites correspondre votre middleware : définissez dans votre schéma les mêmes champs obligatoires que ceux renseignés par le middleware. Le contrat entre le middleware et les composants est ainsi explicite et validé.

// Middleware sets these fields
requestContext.set('userId', user.id)
requestContext.set('tenantId', tenant.id)

// Schema validates they exist
requestContextSchema: z.object({
userId: z.string(),
tenantId: z.string(),
})

Utilisez des champs facultatifs pour le contexte conditionnel : utilisez .optional() pour les valeurs qui ne sont pas toujours présentes.

requestContextSchema: z.object({
userId: z.string(), // Always required
experimentVariant: z.string().optional(), // May not be set
})

Gérez les erreurs de validation des outils : puisque les outils renvoient des objets d'erreur au lieu de lever une exception, vérifiez les erreurs dans la logique de votre agent ou de votre workflow lorsque l'exécution de l'outil est critique.