Request context
Agent、工具和工作流都可以接受 RequestContext 作为参数,使请求特定的值对底层原语可用。
何时使用 RequestContext何时使用-requestcontext的直接链接
当某个原语的行为应随运行时条件变化时,请使用 RequestContext。例如,你可能根据用户属性切换模型或存储后端,或根据语言调整指令和工具选择。
RequestContext 主要用于将数据传入特定请求。它与 agent 记忆不同,后者处理多次调用之间的对话历史和状态持久化。
设置值设置值的直接链接
将 requestContext 传入 agent、network、workflow 或 tool 调用,使值在执行期间对所有底层原语可用。在调用之前使用 .set() 定义值。
.set() 方法接受两个参数:
- key:用于标识值的名称。
- value:与该键关联的数据。
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 })
使用仅运行时键使用仅运行时键的直接链接
当你提供类型或 requestContextSchema 时,get、set、has 和 delete 方法只接受已声明的键。这能捕获拼写错误的键,并保持声明值的类型。
对于不属于 schema 的基础设施或中间件键,请使用 getRaw、setRaw、hasRaw 和 deleteRaw。原始值使用 unknown 类型,因此在使用前需要收窄类型。
const requestContext = new RequestContext<{ userId: string }>()
requestContext.set('userId', 'user-123')
requestContext.setRaw('session.cache', { hits: 0 })
const cache = requestContext.getRaw('session.cache')
if (typeof cache === 'object' && cache !== null && 'hits' in cache) {
console.log(cache.hits)
}
应用数据应优先使用 schema 声明的键。仅当某个键必须保留在 request context schema 之外时,才使用 raw 方法。
根据请求头设置值根据请求头设置值的直接链接
你可以在运行时服务器中间件中通过从请求提取信息来填充 requestContext。在此示例中,temperature-unit 根据 Cloudflare 的 CF-IPCountry 头设置,以确保响应匹配用户的区域设置。
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()
},
],
},
})
如何使用服务器中间件请访问中间件。
StudioStudio的直接链接
在本地开发时,你可以在 JSON 文件中定义预设,并使用 --request-context-presets CLI 标志将它们加载到 Studio 中。这会在 Studio 的请求上下文编辑器中添加一个下拉框,使你无需每次手动编辑 JSON 即可快速切换配置。
mastra dev --request-context-presets ./presets.json
{
"development": { "userId": "dev-user", "env": "development" },
"production": { "userId": "prod-user", "env": "production" }
}
从下拉框选择预设时,JSON 编辑器会填充该预设的值。手动编辑 JSON 会将下拉框切换回 "Custom"。
在 agent 中访问值在 agent 中访问值的直接链接
你可以从 agent 支持的任何配置选项中访问 requestContext 参数。这些函数可以是同步或 async。使用 .get() 方法从 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 }) => {},
})
你还可以将 requestContext 与其他选项一起使用,例如 agents、workflows、scorers、inputProcessors 和 outputProcessors。
动态指令动态指令的直接链接
通过异步函数提供 agent 指令,以便在运行时解析提示。结合 requestContext,这支持以下模式:
- 个性化:根据用户属性、偏好或层级定制指令
- 本地化:根据区域设置调整语气、语言或行为
- A/B 测试:为实验提供不同的提示变体
- 外部提示管理:从注册表服务获取提示而无需重新部署
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',
})
从提示注册表获取从提示注册表获取的直接链接
如果你的组织使用提示注册表服务进行集中提示管理,你可以在运行时获取指令。你可以在不重新部署的情况下更新提示、运行变体实验,并跟踪 agent 中的提示使用情况。
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',
})
完整的配置选项列表请访问 Agent。
从工作流步骤访问值从工作流步骤访问值的直接链接
你可以从工作流步骤的 execute 函数访问 requestContext 参数。该函数可以是同步或异步的。使用 .get() 方法从 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') {
}
},
})
完整的配置选项列表请访问 createStep()。
在工具中访问值在工具中访问值的直接链接
你可以从工具的 execute 函数访问 requestContext 参数。该函数是 async 的。使用 .get() 方法从 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') {
}
},
})
完整的配置选项列表请访问 createTool()。
保留键保留键的直接链接
Mastra 为服务器读取保留了特殊的上下文键。resource 和 thread 键优先于客户端提供的值:服务器会验证所有权,并在用户尝试访问其不拥有的资源时返回 403 错误。
设置 MASTRA_RESOURCE_ID_KEY 的最简单方式是在 auth 配置中使用 mapUserToResourceId 回调:
auth: {
authenticateToken: async token => verifyToken(token),
mapUserToResourceId: user => user.id,
}
当 resource ID 以这种方式派生时,客户端可以在 agent generate 和 stream 请求体中省略 memory.resource。服务器派生的值会被使用,并且始终优先于客户端提供的值。如果请求使用记忆,而请求体和请求上下文都没有提供 resource ID,服务器会返回 400 错误。
你也可以在中间件中手动设置这些键:
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)
| 键 | 用途 |
|---|---|
MASTRA_RESOURCE_ID_KEY | 强制所有记忆操作使用此 resource ID。服务器会验证访问的 thread 属于该 resource,否则返回 403。 |
MASTRA_THREAD_ID_KEY | 强制 thread 操作使用此 thread ID,覆盖客户端提供的值 |
MASTRA_SCOPES_KEY | 设置 agent 运行所代表的作用域,格式为 <type>:<value> 字符串数组。与 agent 的 scopes 和每次调用的 scopes 合并。与另一个 resource 或 thread 值冲突的 resource: 或 thread: 作用域会返回 400 错误。 |
MASTRA_MESSAGE_AUTHOR_KEY | 以 { id, name?, avatarUrl? } 指名用户消息的发送者。Agent-controller 会话将其持久化到 content.metadata.signal.author,并镜像到 providerMetadata.mastra.author 以保持兼容,因此多人共享的 thread 可以显示谁写了什么。 |
服务器所有权检查只读取 MASTRA_RESOURCE_ID_KEY 和 MASTRA_THREAD_ID_KEY。如果你的中间件通过 MASTRA_SCOPES_KEY 设置身份并希望这些检查生效,请同时设置 MASTRA_RESOURCE_ID_KEY:
import {
MASTRA_RESOURCE_ID_KEY,
MASTRA_THREAD_ID_KEY,
MASTRA_SCOPES_KEY,
} from '@mastra/core/request-context'
requestContext.set(MASTRA_SCOPES_KEY, [`org:${user.orgId}`, `resource:${user.id}`])
requestContext.set(MASTRA_RESOURCE_ID_KEY, user.id)
thread: 作用域同样如此:它设置运行的 thread 身份,但只有 MASTRA_THREAD_ID_KEY 驱动服务器的 thread 检查,因此当中间件固定 thread 时请同时设置两者:
requestContext.set(MASTRA_SCOPES_KEY, [`resource:${user.id}`, `thread:${threadId}`])
requestContext.set(MASTRA_RESOURCE_ID_KEY, user.id)
requestContext.set(MASTRA_THREAD_ID_KEY, threadId)
来自请求上下文的作用域和每次调用的 scopes 需要保留它们的 @mastra/server 版本。较旧的服务器会将这些值从请求体透传给 agent,因此当注册了作用域时,agent 会抛出 AGENT_SCOPES_SERVER_OUTDATED 错误而不是使用它们。agent 自身的 scopes 选项仍然有效。
这些键用于在多租户应用中实现用户隔离。使用示例请参阅授权中间件。
TypeScript 支持TypeScript 支持的直接链接
当你为 RequestContext 提供类型参数时,所有方法都完全类型化:
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())
}
}
Schema 验证Schema 验证的直接链接
使用 requestContextSchema 定义 Standard JSON Schema(Zod、Valibot、ArkType 等),在运行时验证请求上下文值。这能尽早捕获缺失或无效的上下文值并提供清晰的错误消息,同时在你的组件中提供类型推断。
Agent schema 验证Agent schema 验证的直接链接
在 agent 上定义 requestContextSchema 后,上下文会在 generate() 或 stream() 开始时进行验证。如果验证失败,agent 会在进行任何 LLM 调用之前抛出 MastraError。
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',
})
验证失败时,错误会包含 agent ID 以及哪些字段失败的详细信息:
Request context validation failed for agent 'validated-agent':
- apiKey: Required
工具 schema 验证工具 schema 验证的直接链接
在工具上定义 requestContextSchema 后,上下文会在 execute() 运行之前进行验证。与 agent 不同,工具会返回验证错误对象而不是抛出错误:
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}` }
},
})
验证失败时,工具会返回错误对象而不是抛出错误:
{
"error": true,
"message": "Request context validation failed for validated-tool. Please fix the following errors and try again:\n- userId: Required\n\nProvided context: {}"
}
工作流 schema 验证工作流 schema 验证的直接链接
在工作流上定义 requestContextSchema 后,上下文会在 run.start() 开始时进行验证。如果验证失败,工作流会在任何步骤执行之前抛出错误。
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()
验证失败时,工作流会抛出错误:
Request context validation failed for workflow 'validated-workflow':
- tenantId: Required
步骤也可以定义自己的 requestContextSchema 进行步骤级验证。步骤验证在步骤的 execute() 函数之前运行。
验证行为验证行为的直接链接
| 组件 | 属性 | 验证时机 | 失败时 |
|---|---|---|---|
| Agent | requestContextSchema | generate() / stream() 开始时 | 抛出 MastraError |
| Tool | requestContextSchema | execute() 之前 | 返回错误对象 |
| Workflow | requestContextSchema | run.start() 开始时 | 抛出 Error |
| Step | requestContextSchema | 步骤 execute() 之前 | 步骤因错误失败 |
最佳实践最佳实践的直接链接
与中间件保持一致:在 schema 中定义与中间件设置的相同的必填字段。这样,中间件与组件之间的契约就是显式且经过验证的。
// 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(),
})
对条件上下文使用可选字段:对可能不总是存在的值使用 .optional()。
requestContextSchema: z.object({
userId: z.string(), // Always required
experimentVariant: z.string().optional(), // May not be set
})
处理工具验证错误:由于工具返回错误对象而不是抛出错误,当工具执行至关重要时,请在 agent 或工作流逻辑中检查错误。
相关内容相关内容的直接链接
- Agent 生命周期:了解上下文值在 agent 运行期间何时可见
- Agent Request Context
- Workflow Request Context
- 服务器中间件
- 授权中间件