構造化出力を使用すると、エージェントから返してほしいデータの正確な形状を定義できます。エージェントはタスクを完了するために必要なツールを使用でき、最終的にスキーマに一致するバリデーション済みのJSONを取得できます。必要な構造のJSON Schemaを定義すると、SDKが出力がそれに一致することを保証します。
完全な型安全性のためには、Zod(TypeScript)またはPydantic(Python)を使用してスキーマを定義し、強く型付けされたオブジェクトを取得します。
エージェントはデフォルトで自由形式のテキストを返しますが、これはチャットには適していますが、出力をプログラム的に使用する必要がある場合には適していません。構造化出力は、アプリケーションロジック、データベース、またはUIコンポーネントに直接渡せる型付きデータを提供します。
エージェントがウェブを検索してレシピを持ち帰るレシピアプリを考えてみましょう。構造化出力がなければ、自分でパースする必要がある自由形式のテキストが返されます。構造化出力があれば、必要な形状を定義し、アプリで直接使用できる型付きデータを取得できます。
構造化出力を使用するには、必要なデータの形状を記述するJSON Schemaを定義し、outputFormatオプション(TypeScript)またはoutput_formatオプション(Python)を介してquery()に渡します。エージェントが完了すると、結果メッセージにスキーマに一致するバリデーション済みデータを含むstructured_outputフィールドが含まれます。
以下の例では、エージェントにAnthropicについて調査し、会社名、設立年、本社所在地を構造化出力として返すよう依頼しています。
import { query } from '@anthropic-ai/claude-agent-sdk'
// 返してほしいデータの形状を定義
const schema = {
type: 'object',
properties: {
company_name: { type: 'string' },
founded_year: { type: 'number' },
headquarters: { type: 'string' }
},
required: ['company_name']
}
for await (const message of query({
prompt: 'Research Anthropic and provide key company information',
options: {
outputFormat: {
type: 'json_schema',
schema: schema
}
}
})) {
// 結果メッセージにはバリデーション済みデータを含むstructured_outputが含まれる
if (message.type === 'result' && message.structured_output) {
console.log(message.structured_output)
// { company_name: "Anthropic", founded_year: 2021, headquarters: "San Francisco, CA" }
}
}JSON Schemaを手書きする代わりに、Zod(TypeScript)またはPydantic(Python)を使用してスキーマを定義できます。これらのライブラリはJSON Schemaを自動生成し、コードベース全体でオートコンプリートと型チェック付きで使用できる完全に型付けされたオブジェクトにレスポンスをパースできます。
以下の例では、サマリー、ステップのリスト(各ステップに複雑度レベル付き)、潜在的なリスクを含む機能実装計画のスキーマを定義しています。エージェントが機能を計画し、型付きのFeaturePlanオブジェクトを返します。その後、plan.summaryのようなプロパティにアクセスしたり、完全な型安全性を持ってplan.stepsを反復処理したりできます。
import { z } from 'zod'
import { query } from '@anthropic-ai/claude-agent-sdk'
// Zodでスキーマを定義
const FeaturePlan = z.object({
feature_name: z.string(),
summary: z.string(),
steps: z.array(z.object({
step_number: z.number(),
description: z.string(),
estimated_complexity: z.enum(['low', 'medium', 'high'])
})),
risks: z.array(z.string())
})
type FeaturePlan = z.infer<typeof FeaturePlan>
// JSON Schemaに変換
const schema = z.toJSONSchema(FeaturePlan)
// クエリで使用
for await (const message of query({
prompt: 'Plan how to add dark mode support to a React app. Break it into implementation steps.',
options: {
outputFormat: {
type: 'json_schema',
schema: schema
}
}
})) {
if (message.type === 'result' && message.structured_output) {
// バリデーションして完全に型付けされた結果を取得
const parsed = FeaturePlan.safeParse(message.structured_output)
if (parsed.success) {
const plan: FeaturePlan = parsed.data
console.log(`Feature: ${plan.feature_name}`)
console.log(`Summary: ${plan.summary}`)
plan.steps.forEach(step => {
console.log(`${step.step_number}. [${step.estimated_complexity}] ${step.description}`)
})
}
}
}メリット:
safeParse()またはmodel_validate()によるランタイムバリデーションoutputFormat(TypeScript)またはoutput_format(Python)オプションは、以下のプロパティを持つオブジェクトを受け取ります:
type:構造化出力の場合は"json_schema"に設定schema:出力構造を定義するJSON Schemaオブジェクト。Zodスキーマからz.toJSONSchema()で、またはPydanticモデルから.model_json_schema()で生成できますSDKは、すべての基本型(object、array、string、number、boolean、null)、enum、const、required、ネストされたオブジェクト、$ref定義を含む標準的なJSON Schema機能をサポートしています。サポートされている機能と制限の完全なリストについては、JSON Schemaの制限を参照してください。
この例は、マルチステップのツール使用で構造化出力がどのように機能するかを示しています。エージェントはコードベース内のTODOコメントを見つけ、それぞれのgit blame情報を調べる必要があります。エージェントは使用するツール(検索用のGrep、gitコマンド実行用のBash)を自律的に決定し、結果を単一の構造化レスポンスにまとめます。
スキーマにはオプションフィールド(authorとdate)が含まれています。これは、すべてのファイルでgit blame情報が利用できるとは限らないためです。エージェントは見つけられた情報を埋め、残りは省略します。
import { query } from '@anthropic-ai/claude-agent-sdk'
// TODO抽出用の構造を定義
const todoSchema = {
type: 'object',
properties: {
todos: {
type: 'array',
items: {
type: 'object',
properties: {
text: { type: 'string' },
file: { type: 'string' },
line: { type: 'number' },
author: { type: 'string' },
date: { type: 'string' }
},
required: ['text', 'file', 'line']
}
},
total_count: { type: 'number' }
},
required: ['todos', 'total_count']
}
// エージェントはGrepでTODOを検索し、Bashでgit blame情報を取得
for await (const message of query({
prompt: 'Find all TODO comments in this codebase and identify who added them',
options: {
outputFormat: {
type: 'json_schema',
schema: todoSchema
}
}
})) {
if (message.type === 'result' && message.structured_output) {
const data = message.structured_output
console.log(`Found ${data.total_count} TODOs`)
data.todos.forEach(todo => {
console.log(`${todo.file}:${todo.line} - ${todo.text}`)
if (todo.author) {
console.log(` Added by ${todo.author} on ${todo.date}`)
}
})
}
}エージェントがスキーマに一致する有効なJSONを生成できない場合、構造化出力の生成は失敗する可能性があります。これは通常、スキーマがタスクに対して複雑すぎる場合、タスク自体が曖昧な場合、またはエージェントがバリデーションエラーの修正を試みるリトライ上限に達した場合に発生します。
エラーが発生した場合、結果メッセージには何が問題だったかを示すsubtypeがあります:
| Subtype | 意味 |
|---|---|
success | 出力が正常に生成され、バリデーションされた |
error_max_structured_output_retries | エージェントが複数回の試行後も有効な出力を生成できなかった |
以下の例では、subtypeフィールドをチェックして、出力が正常に生成されたか、失敗を処理する必要があるかを判断しています:
for await (const msg of query({
prompt: 'Extract contact info from the document',
options: {
outputFormat: {
type: 'json_schema',
schema: contactSchema
}
}
})) {
if (msg.type === 'result') {
if (msg.subtype === 'success' && msg.structured_output) {
// バリデーション済みの出力を使用
console.log(msg.structured_output)
} else if (msg.subtype === 'error_max_structured_output_retries') {
// 失敗を処理 - よりシンプルなプロンプトでリトライ、非構造化にフォールバックなど
console.error('Could not produce valid output')
}
}
}エラーを避けるためのヒント:
Was this page helpful?