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 RequestContextLien 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.
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 valeursLien 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 :
- clé : nom servant à identifier la valeur.
- 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êteLien 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.
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.
StudioLien 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
{
"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 agentsLien 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.
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 dynamiquesLien 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
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 registreLien 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.
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 workflowLien 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.
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 outilsLien 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.
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éesLien 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_KEY | Force 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_KEY | Force 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 TypeScriptLien 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émaLien 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 agentLien 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.
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 outilLien 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 :
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 workflowLien 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.
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 validationLien direct vers Comportement de la validation
| Composant | Propriété | Moment de la validation | En cas d'échec |
|---|---|---|---|
| Agent | requestContextSchema | Début de generate() / stream() | Lève une MastraError |
| Outil | requestContextSchema | Avant execute() | Renvoie un objet d'erreur |
| Workflow | requestContextSchema | Début de run.start() | Lève une Error |
| Étape | requestContextSchema | Avant execute() pour l'étape | L'étape échoue avec une erreur |
Bonnes pratiquesLien 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.