跳到主要内容
非官方简体中文翻译,内容版权归 Mastra 所有,遵循 Apache-2.0 许可。

Request context

Agent、工具和工作流都可以接受 RequestContext 作为参数,使请求特定的值对底层原语可用。

何时使用 RequestContext
何时使用-requestcontext的直接链接

当某个原语的行为应随运行时条件变化时,请使用 RequestContext。例如,你可能根据用户属性切换模型或存储后端,或根据语言调整指令和工具选择。

备注

RequestContext 主要用于将数据传入特定请求。它与 agent 记忆不同,后者处理多次调用之间的对话历史和状态持久化。

设置值
设置值的直接链接

将 requestContext 传入 agent、network、workflow 或 tool 调用,使值在执行期间对所有底层原语可用。在调用之前使用 .set() 定义值。

.set() 方法接受两个参数:

  1. key:用于标识值的名称。
  2. 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 头设置,以确保响应匹配用户的区域设置。

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()
},
],
},
})

如何使用服务器中间件请访问中间件。

Studio
Studio的直接链接

在本地开发时,你可以在 JSON 文件中定义预设,并使用 --request-context-presets CLI 标志将它们加载到 Studio 中。这会在 Studio 的请求上下文编辑器中添加一个下拉框,使你无需每次手动编辑 JSON 即可快速切换配置。

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

从下拉框选择预设时,JSON 编辑器会填充该预设的值。手动编辑 JSON 会将下拉框切换回 "Custom"。

在 agent 中访问值
在 agent 中访问值的直接链接

你可以从 agent 支持的任何配置选项中访问 requestContext 参数。这些函数可以是同步或 async。使用 .get() 方法从 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 }) => {},
})

你还可以将 requestContext 与其他选项一起使用,例如 agents、workflows、scorers、inputProcessors 和 outputProcessors。

动态指令
动态指令的直接链接

通过异步函数提供 agent 指令,以便在运行时解析提示。结合 requestContext,这支持以下模式:

  • 个性化:根据用户属性、偏好或层级定制指令
  • 本地化:根据区域设置调整语气、语言或行为
  • A/B 测试:为实验提供不同的提示变体
  • 外部提示管理:从注册表服务获取提示而无需重新部署
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',
})

从提示注册表获取
从提示注册表获取的直接链接

如果你的组织使用提示注册表服务进行集中提示管理,你可以在运行时获取指令。你可以在不重新部署的情况下更新提示、运行变体实验,并跟踪 agent 中的提示使用情况。

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',
})

完整的配置选项列表请访问 Agent。

从工作流步骤访问值
从工作流步骤访问值的直接链接

你可以从工作流步骤的 execute 函数访问 requestContext 参数。该函数可以是同步或异步的。使用 .get() 方法从 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') {
}
},
})

完整的配置选项列表请访问 createStep()。

在工具中访问值
在工具中访问值的直接链接

你可以从工具的 execute 函数访问 requestContext 参数。该函数是 async 的。使用 .get() 方法从 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') {
}
},
})

完整的配置选项列表请访问 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。

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',
})

验证失败时,错误会包含 agent ID 以及哪些字段失败的详细信息:

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

工具 schema 验证
工具 schema 验证的直接链接

在工具上定义 requestContextSchema 后,上下文会在 execute() 运行之前进行验证。与 agent 不同,工具会返回验证错误对象而不是抛出错误:

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}` }
},
})

验证失败时,工具会返回错误对象而不是抛出错误:

{
"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() 开始时进行验证。如果验证失败,工作流会在任何步骤执行之前抛出错误。

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()

验证失败时,工作流会抛出错误:

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

步骤也可以定义自己的 requestContextSchema 进行步骤级验证。步骤验证在步骤的 execute() 函数之前运行。

验证行为
验证行为的直接链接

组件属性验证时机失败时
AgentrequestContextSchemagenerate() / stream() 开始时抛出 MastraError
ToolrequestContextSchemaexecute() 之前返回错误对象
WorkflowrequestContextSchemarun.start() 开始时抛出 Error
SteprequestContextSchema步骤 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 或工作流逻辑中检查错误。

相关内容
相关内容的直接链接