结构化输出
🌐 Structured Output
结构化输出让代理返回一个符合模式定义形状的对象,而不是返回文本。模式告诉模型需要生成哪些字段,模型则确保最终结果符合该形状。
🌐 Structured output lets an agent return an object that matches the shape defined by a schema instead of returning text. The schema tells the model what fields to produce, and the model ensures the final result fits that shape.
何时使用结构化输出Direct link to 何时使用结构化输出
🌐 When to use structured output
当你需要代理返回数据对象而不是文本时,请使用结构化输出。定义良好的字段可以让你更容易提取用于 API 调用、用户界面渲染或应用逻辑的值。
🌐 Use structured output when you need an agent to return a data object rather than text. Having well defined fields can make it simpler to pull out the values you need for API calls, UI rendering, or application logic.
定义模式Direct link to 定义模式
🌐 Defining schemas
代理可以通过使用 Zod 或 JSON Schema 定义预期输出,从而返回结构化数据。推荐使用 Zod,因为它提供 TypeScript 类型推断和运行时验证,而当你需要一种语言无关的格式时,JSON Schema 则非常有用。
🌐 Agents can return structured data by defining the expected output with either Zod or JSON Schema. Zod is recommended because it provides TypeScript type inference and runtime validation, while JSON Schema is useful when you need a language agnostic format.
- Zod
- JSON Schema
使用 Zod 定义 output 形状:
🌐 Define the output shape using Zod:
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);
你也可以使用 JSON Schema 来定义你的输出结构:
🌐 You can also use JSON Schema to define your output structure:
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() 获取完整的配置选项列表。
🌐 Visit .generate() for a full list of configuration options.
示例输出Direct link to 示例输出
🌐 Example output
response.object 将包含由模式定义的结构化数据。
🌐 The response.object will contain the structured data as defined by the 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"]
}
]
流Direct link to 流
🌐 Streaming
流式传输也支持结构化输出。最终的结构化对象可在 stream.fullStream 获得,并在流完成后可在 stream.object 获取。文本流块仍然会被发送,但它们包含的是自然语言文本,而不是结构化数据。
🌐 Streaming also supports structured output. The final structured object is available on stream.fullStream and after the stream completes on stream.object. Text stream chunks are still emitted, but they contain natural language text rather than structured data.
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);
}
结构剂Direct link to 结构剂
🌐 Structuring agent
当你的主代理在创建结构化输出方面不够熟练时,你可以提供一个 model 到 structuredOutput。在这种情况下,Mastra 会在后台使用第二个代理,从主代理的自然语言响应中提取结构化数据。这会进行两次大型语言模型调用,一次生成响应,另一次将该响应转化为结构化对象,这会增加一些延迟和成本,但可以提高复杂结构化任务的准确性。
🌐 When your main agent isn't proficient at creating structured output you can provide a model to structuredOutput. In this case, Mastra uses a second agent under the hood to extract structured data from the main agent's natural language response. This makes two LLM calls, one to generate the response and another to turn that response into the structured object, which adds some latency and cost but can improve accuracy for complex structuring tasks.
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-4o",
},
});
console.log(response.object);
结合工具与结构化输出Direct link to 结合工具与结构化输出
🌐 Combining tools and structured output
当代理同时配置了工具和结构化输出时,某些模型可能不支持同时使用这两项功能。这是底层模型 API 的限制,而不是 Mastra 本身的限制。
🌐 When an agent has both tools and structured output configured, some models may not support using both features together. This is a limitation of the underlying model APIs, not Mastra itself.
如果在启用结构化输出时工具没有被调用,或者在同时使用这两个功能时收到错误,请尝试以下解决方法之一。
🌐 If your tools aren't being called when structured output is enabled, or you receive an error when combining both features, try one of the workarounds below.
解决方法选项Direct link to 解决方法选项
🌐 Workaround options
当你的模型不支持工具和结构化输出同时使用时,你有三种选择:
🌐 When your model doesn't support tools and structured output together, you have three options:
- 使用
jsonPromptInjection: true- 将模式注入到提示中,而不是使用 API 的response_format参数 - 使用单独的结构化模型 - 将
model传递给structuredOutput以使用第二个 LLM 进行结构化 - 使用
prepareStep- 将工具和结构化输出分开处理
每种方法将在下面的部分中详细说明。
🌐 Each approach is detailed in the sections below.
LLM 结构化输出支持Direct link to LLM 结构化输出支持
🌐 LLM structured output support
由于各大语言模型的 API 存在差异,结构化输出支持程度各不相同。下面的章节介绍了对于不完全支持结构化输出的模型,或将其与工具结合使用的解决方法。
🌐 Structured output support varies across LLMs due to differences in their APIs. The sections below cover workarounds for models that don't fully support structured output or combining it with tools.
jsonPromptInjectionDirect link to jsonpromptinjection
默认情况下,Mastra 使用 response_format API 参数将模式传递给模型提供商。大多数模型提供商都内置了对此的支持,从而可靠地强制执行该模式。
🌐 By default, Mastra passes the schema to the model provider using the response_format API parameter. Most model providers have built-in support for this, which reliably enforces the schema.
如果你的模型提供商不支持 response_format,你将会收到 API 的错误提示。出现这种情况时,请设置 jsonPromptInjection: true。这会将模式添加到系统提示中,指示模型输出 JSON。这种方法的可靠性不如使用 API 参数的方法。
🌐 If your model provider doesn't support response_format, you'll get an error from the API. When this happens, set jsonPromptInjection: true. This adds the schema to the system prompt instead, instructing the model to output JSON. This is less reliable than the API parameter approach.
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: true,
},
});
console.log(response.object);
Gemini 2.5 模型不支持在同一次 API 调用中将 response_format(结构化输出)与函数调用(工具)结合使用。如果你的智能体有工具,并且你正在使用 Gemini 2.5 模型的 structuredOutput,你必须设置 jsonPromptInjection: true 以避免出现错误 Function calling with a response mime type: 'application/json' is unsupported。
🌐 Gemini 2.5 models do not support combining response_format (structured output) with function calling (tools) in the same API call. If your agent has tools and you're using structuredOutput with a Gemini 2.5 model, you must set jsonPromptInjection: true to avoid the error 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
},
});
使用独立的结构化模型Direct link to 使用独立的结构化模型
🌐 Using a separate structuring model
当将 model 提供给 structuredOutput 属性时,Mastra 会使用一个独立的内部代理来处理结构化输出。主代理将处理所有步骤(包括工具调用),而结构化输出模型只处理结构化输出的生成。
🌐 When model is provided to the structuredOutput property, Mastra uses a separate internal agent to handle the structured output. The main agent will handle all of the steps (including tool calling) and the structured output model will handle only the generation of structured output.
const response = await testAgent.generate("Tell me about TypeScript.", {
structuredOutput: {
schema: yourSchema
model: 'openai/gpt-4o'
}
});
使用 prepareStep 的多步骤方法Direct link to multi-step-approach-with-preparestep
🌐 Multi-step approach with prepareStep
对于不支持工具和结构化输出同时使用的模型,你可以使用 prepareStep 将它们分步处理。
🌐 For models that don't support tools and structured outputs together, you can use prepareStep to handle them in separate steps.
const result = await agent.stream("weather in vancouver?", {
prepareStep: async ({ stepNumber }) => {
if (stepNumber === 0) {
return {
model: "anthropic/claude-sonnet-4-20250514",
tools: {
weatherTool,
},
toolChoice: "required",
};
}
return {
model: "anthropic/claude-sonnet-4-20250514",
tools: undefined,
structuredOutput: {
schema: z.object({
temperature: z.number(),
humidity: z.number(),
windSpeed: z.number(),
}),
},
};
},
});
错误处理Direct link to 错误处理
🌐 Error handling
当模式验证失败时,你可以使用 errorStrategy 控制错误的处理方式。默认的 strict 策略会抛出错误,而 warn 会记录警告并继续。fallback 策略会返回使用 fallbackValue 提供的值。
🌐 When schema validation fails, you can control how errors are handled using errorStrategy. The default strict strategy throws an error, while warn logs a warning and continues. The fallback strategy returns the values provided using fallbackValue.
import { z } from "zod";
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);
相关Direct link to 相关
🌐 Related