结构化输出
结构化输出让 Agent 返回符合 schema 所定义形状的对象,而不是文本。schema 会告诉模型要生成哪些字段,模型则确保最终结果符合该形状。
何时使用结构化输出何时使用结构化输出的直接链接
当你需要 Agent 返回数据对象而不是文本时,请使用结构化输出。定义明确的字段可以简化提取所需值的过程,以便用于 API 调用、UI 渲染或应用逻辑。
定义 schema定义 schema的直接链接
Agent 可以使用 Standard JSON Schema(Zod、Valibot、ArkType 等)或 JSON Schema 定义预期输出,从而返回结构化数据。推荐使用 Zod 等库,因为它们提供 TypeScript 类型推断和运行时验证;当你需要与语言无关的格式时,JSON Schema 更适合。
- Zod
- Valibot
- ArkType
- JSON Schema
使用 Zod 定义 output 形状:
import { z } from 'zod'
const response = await testAgent.generate('Help me plan my day.', {
structuredOutput: {
schema: z.array(
z.object({
name: z.string(),
activities: z.array(z.string()),
}),
),
},
})
console.log(response.object)
使用 Valibot 定义 output 形状:
import * as v from 'valibot'
import { toStandardJsonSchema } from '@valibot/to-json-schema'
const response = await testAgent.generate('Help me plan my day.', {
structuredOutput: {
schema: toStandardJsonSchema(
v.array(
v.object({
name: v.string(),
activities: v.array(v.string()),
}),
),
),
},
})
console.log(response.object)
使用 ArkType 定义 output 形状:
import { type } from 'arktype'
const response = await testAgent.generate('Help me plan my day.', {
structuredOutput: {
schema: type({
name: 'string',
activities: 'string[]',
}).array(),
},
})
console.log(response.object)
你也可以使用 JSON Schema 定义输出结构:
const response = await testAgent.generate('Help me plan my day.', {
structuredOutput: {
schema: {
type: 'array',
items: {
type: 'object',
properties: {
name: { type: 'string' },
activities: {
type: 'array',
items: { type: 'string' },
},
},
required: ['name', 'activities'],
},
},
},
})
console.log(response.object)
有关完整配置选项列表,请参阅 .generate()。
输出示例: response.object 将包含 schema 定义的结构化数据。
[
{
"name": "Morning Routine",
"activities": ["Wake up at 7am", "Exercise", "Shower", "Breakfast"]
},
{
"name": "Work",
"activities": ["Check emails", "Team meeting", "Lunch break"]
},
{
"name": "Evening",
"activities": ["Dinner", "Relax", "Read a book", "Sleep by 10pm"]
}
]
流式传输结构化输出流式传输结构化输出的直接链接
流式传输也支持结构化输出。最终的结构化对象可在 stream.fullStream 中获取,流完成后也可在 stream.object 中获取。文本流块仍会发出,但其中包含自然语言文本,而不是结构化数据。
import { z } from 'zod'
const stream = await testAgent.stream('Help me plan my day.', {
structuredOutput: {
schema: z.array(
z.object({
name: z.string(),
activities: z.array(z.string()),
}),
),
},
})
for await (const chunk of stream.fullStream) {
if (chunk.type === 'object-result') {
console.log('\n', JSON.stringify(chunk, null, 2))
}
process.stdout.write(JSON.stringify(chunk))
}
console.log(await stream.object)
for await (const chunk of stream.textStream) {
process.stdout.write(chunk)
}
结构化 Agent结构化 Agent的直接链接
当主 Agent 不擅长创建结构化输出时,可以向 structuredOutput 提供 model。在这种情况下,Mastra 会在底层使用第二个 Agent,从主 Agent 的自然语言响应中提取结构化数据。这会发起两次 LLM 调用:一次生成响应,另一次将响应转换为结构化对象。这样会增加一些延迟和成本,但可以提高复杂结构化任务的准确性。
import { z } from 'zod'
const response = await testAgent.generate('Analyze the TypeScript programming language.', {
structuredOutput: {
schema: z.object({
overview: z.string(),
strengths: z.array(z.string()),
weaknesses: z.array(z.string()),
useCases: z.array(
z.object({
scenario: z.string(),
reasoning: z.string(),
}),
),
comparison: z.object({
similarTo: z.array(z.string()),
differentiators: z.array(z.string()),
}),
}),
model: 'openai/gpt-5.6-sol',
},
})
console.log(response.object)
组合 Tool 与结构化输出组合 Tool 与结构化输出的直接链接
当 Agent 同时配置了 Tool 和结构化输出时,某些模型可能不支持同时使用这两项功能。这是底层模型 API 的限制,并非 Mastra 本身的限制。
如果启用结构化输出后未调用 Tool,或组合两项功能时收到错误,请尝试以下解决方法之一。
解决方法解决方法的直接链接
当模型不支持同时使用 Tool 和结构化输出时,有三种选择:
- 使用
jsonPromptInjection:将其设为'auto',在支持时选择原生结构化输出,否则使用内联提示词注入;也可以明确选择注入模式 - 使用单独的结构化模型:向
structuredOutput传入model,使用第二个 LLM 进行结构化 - 使用
prepareStep:在不同步骤中分别处理 Tool 和结构化输出
以下各节详细介绍每种方法。
LLM 结构化输出支持LLM 结构化输出支持的直接链接
由于 API 不同,各 LLM 对结构化输出的支持也不同。以下各节介绍不完全支持结构化输出或不支持将其与 Tool 组合使用的模型所对应的解决方法。
jsonPromptInjectionjsonpromptinjection的直接链接
默认情况下,Mastra 使用 response_format API 参数将 schema 传递给模型 Provider。将 jsonPromptInjection: 'auto' 设置为让 Mastra 根据模型能力数据选择模式。Mastra 对受支持模型使用原生结构化输出,对不受支持的模型或没有能力数据的模型使用内联提示词注入。
import { z } from 'zod'
const response = await testAgent.generate('Help me plan my day.', {
structuredOutput: {
schema: z.array(
z.object({
name: z.string(),
activities: z.array(z.string()),
}),
),
jsonPromptInjection: 'auto',
},
})
console.log(response.object)
需要覆盖根据能力作出的选择时,请使用明确模式:
false或省略:使用 Provider 的原生结构化输出。'inline':将 schema 指令添加到最新的用户消息中。true或'system':将 schema 指令添加到系统消息中。'auto':模型支持时使用原生结构化输出,否则使用内联提示词注入。
Gemini 2.5 模型不支持在同一 API 调用中组合使用 response_format(结构化输出)和函数调用(Tool)。如果 Agent 有 Tool,并且你在 Gemini 2.5 模型中使用 structuredOutput,则必须设置 jsonPromptInjection: true,以避免出现 Function calling with a response mime type: 'application/json' is unsupported 错误。
const response = await agentWithTools.generate('Your prompt', {
structuredOutput: {
schema: yourSchema,
jsonPromptInjection: true, // Required for Gemini 2.5 when tools are present
},
})
使用单独的结构化模型使用单独的结构化模型的直接链接
向 structuredOutput 属性提供 model 后,Mastra 会使用单独的内部 Agent 来处理结构化输出。主 Agent 会处理所有步骤(包括 Tool 调用),结构化输出模型只负责生成结构化输出。
const response = await testAgent.generate('Tell me about TypeScript.', {
structuredOutput: {
schema: yourSchema,
model: 'openai/gpt-5.6-sol',
},
})
如果希望该结构化模型也能看到当前对话历史,请在 model 旁设置 useAgent: true。Mastra 会使用单独的结构化模型复用父 Agent,并在线程可用时附加只读 Memory 上下文。
const response = await testAgent.generate('Return my profile as structured data.', {
memory: {
thread: 'thread-123',
resource: 'user-123',
},
structuredOutput: {
schema: z.object({
favoriteColor: z.string(),
hometown: z.string(),
petName: z.string(),
}),
model: 'openai/gpt-5.6-sol',
useAgent: true,
},
})
如果希望单独的结构化模型仅根据当前响应工作,而不继承之前的对话 Memory,请不要设置 useAgent。
使用 prepareStep 的多步骤方法multi-step-approach-with-preparestep的直接链接
对于不支持同时使用 Tool 和结构化输出的模型,可以使用 prepareStep 在不同步骤中分别处理它们。
const result = await agent.stream('weather in vancouver?', {
prepareStep: async ({ stepNumber }) => {
if (stepNumber === 0) {
return {
model: 'openai/gpt-5.6-sol',
tools: {
weatherTool,
},
toolChoice: 'required',
}
}
return {
model: 'openai/gpt-5.6-sol',
tools: undefined,
structuredOutput: {
schema: z.object({
temperature: z.number(),
humidity: z.number(),
windSpeed: z.number(),
}),
},
}
},
})
处理错误处理错误的直接链接
schema 验证失败时,可以使用 errorStrategy 控制错误处理方式。默认的 strict 策略会抛出错误,而 warn 会记录警告并继续。fallback 策略会返回通过 fallbackValue 提供的值。
const response = await testAgent.generate('Tell me about TypeScript.', {
structuredOutput: {
schema: z.object({
summary: z.string(),
keyFeatures: z.array(z.string()),
}),
errorStrategy: 'fallback',
fallbackValue: {
summary: 'TypeScript is a typed superset of JavaScript',
keyFeatures: ['Static typing', 'Compiles to JavaScript', 'Better tooling'],
},
},
})
console.log(response.object)