構造化出力
構造化出力を使うと、Agent はテキストではなく、スキーマで定義した形状に一致するオブジェクトを返せます。スキーマは生成するフィールドをモデルに伝え、モデルは最終結果がその形状に合うようにします。
構造化出力を使用する場面構造化出力を使用する場面への直接リンク
Agent からテキストではなくデータオブジェクトを返す必要がある場合に使用します。明確に定義されたフィールドがあれば、API 呼び出し、UI のレンダリング、アプリケーションロジックに必要な値を簡単に取り出せます。
スキーマを定義するスキーマを定義するへの直接リンク
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 には、スキーマで定義した構造化データが格納されます。
[
{
"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 は内部で2つ目の Agent を使用し、メイン Agent の自然言語レスポンスから構造化データを抽出します。レスポンス生成と構造化オブジェクトへの変換で LLM を2回呼び出すため、レイテンシーとコストは増えますが、複雑な構造化タスクの精度が向上する場合があります。
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 と構造化出力の両方を設定すると、一部のモデルでは両機能を同時に使用できない場合があります。これは Mastra ではなく、基盤となるモデル API の制限です。
構造化出力を有効にしたときに Tool が呼び出されない場合や、両機能を組み合わせてエラーが発生する場合は、次の回避策を試してください。
回避策回避策への直接リンク
モデルが Tool と構造化出力の併用をサポートしていない場合、次の3つの方法があります。
jsonPromptInjectionを使用する:'auto'を設定し、サポートされる場合はネイティブの構造化出力、それ以外はインラインのプロンプト挿入を選択するか、挿入モードを明示します- 別の構造化モデルを使用する:
structuredOutputにmodelを渡し、2つ目の LLM で構造化します prepareStepを使用する: Tool と構造化出力を別々のステップで処理します
各方法の詳細は以下で説明します。
LLM の構造化出力サポートLLM の構造化出力サポートへの直接リンク
API の違いにより、構造化出力のサポート状況は LLM ごとに異なります。以下では、構造化出力や Tool との併用を完全にはサポートしないモデル向けの回避策を説明します。
jsonPromptInjectionjsonpromptinjectionへの直接リンク
デフォルトでは、Mastra は response_format API パラメーターを使ってスキーマをモデル Provider に渡します。jsonPromptInjection: 'auto' を設定すると、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': 最新のユーザーメッセージにスキーマの指示を追加します。trueまたは'system': system message にスキーマの指示を追加します。'auto': モデルがサポートしていればネイティブの構造化出力を使用し、それ以外はインラインのプロンプト挿入を使用します。
Gemini 2.5 モデルは、同じ API 呼び出しで response_format(構造化出力)と function calling(Tool)を組み合わせることをサポートしていません。Agent に Tool があり、Gemini 2.5 モデルで structuredOutput を使用する場合は、Function calling with a response mime type: 'application/json' is unsupported エラーを避けるため、jsonPromptInjection: true を設定する必要があります。
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 を再利用し、thread が利用できる場合は読み取り専用の 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(),
}),
},
}
},
})
エラーを処理するエラーを処理するへの直接リンク
スキーマ検証に失敗した場合は、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)