構造化出力
エージェントワークフローから検証済みのJSON結果を取得する
「structured outputs」(構造化出力)は、Claudeの応答が特定のスキーマに従うように制約し、下流の処理のために有効で解析可能な出力を保証します。構造化出力は、相互に補完する2つの機能を提供します。
- JSON出力(
output_config.format):Claudeの応答を特定のJSON形式で取得します - 厳密なツール使用(
strict: true):ツール名と入力に対するスキーマ検証を保証します
これらの機能は、同じリクエスト内で個別に使用することも、組み合わせて使用することもできます。
構造化出力を使用する理由
構造化出力がない場合、Claudeは不正な形式のJSON応答や無効なツール入力を生成し、アプリケーションを壊してしまう可能性があります。慎重にプロンプトを作成しても、次のような問題に遭遇することがあります。
- 無効なJSON構文による解析エラー
- 必須フィールドの欠落
- 一貫性のないデータ型
- エラー処理と再試行を必要とするスキーマ違反
構造化出力は、「constrained decoding」(制約付きデコーディング)によってスキーマに準拠した応答を保証します。
- 常に有効:
JSON.parse()エラーはもう発生しません - 型安全: フィールドの型と必須フィールドが保証されます
- 信頼性: スキーマ違反による再試行は不要です
JSON出力
JSON出力はClaudeの応答形式を制御し、Claudeがスキーマに一致する有効なJSONを返すことを保証します。次のような場合にJSON出力を使用してください。
- Claudeの応答形式を制御する
- 画像やテキストからデータを抽出する
- 構造化されたレポートを生成する
- API応答をフォーマットする
クイックスタート
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[
{
"role": "user",
"content": "Extract the key information from this email: John Smith (john@example.com) is interested in our Enterprise plan and wants to schedule a demo for next Tuesday at 2pm.",
}
],
output_config={
"format": {
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"email": {"type": "string"},
"plan_interest": {"type": "string"},
"demo_requested": {"type": "boolean"},
},
"required": ["name", "email", "plan_interest", "demo_requested"],
"additionalProperties": False,
},
}
},
)
print(next(block.text for block in response.content if block.type == "text"))応答形式: 応答のテキストコンテンツブロック内の、スキーマに一致する有効なJSON
{
"name": "John Smith",
"email": "john@example.com",
"plan_interest": "Enterprise",
"demo_requested": true
}仕組み
JSONスキーマを定義する
Claudeに従わせたい構造を記述するJSONスキーマを作成します。スキーマは標準のJSON Schema形式を使用しますが、いくつかの制限があります(JSON Schemaの制限を参照)。
output_config.formatパラメータを追加する
APIリクエストに
output_config.formatパラメータを含め、type: "json_schema"とスキーマ定義を指定します。応答を解析する
Claudeの応答はスキーマに一致する有効なJSONであり、応答のテキストコンテンツブロックで返されます。
SDKでのJSON出力の操作
SDKは、スキーマ変換、自動検証、一般的なスキーマライブラリとの統合など、JSON出力の操作を容易にするヘルパーを提供します。
ネイティブなスキーマ定義の使用
生のJSONスキーマを記述する代わりに、各言語で使い慣れたスキーマ定義ツールを使用できます。
- Python:
client.messages.parse()とPydanticモデル - TypeScript:
zodOutputFormat()とZodスキーマ、またはjsonSchemaOutputFormat()と型付きJSON Schemaリテラル - Java:
outputConfig(Class<T>)による自動スキーマ導出を備えたプレーンなJavaクラス - Ruby:
output_config: {format: Model}とAnthropic::BaseModelクラス - PHP:
outputConfig: ['format' => MyClass::class]とStructuredOutputModelを実装するクラス - C#: スキーマを自動的に導出するジェネリックな
Create<T>()オーバーロードとプレーンなC#クラス - Go: ベータAPIで自動的にJSONスキーマにリフレクションされるGo構造体、または
output_configを介した生のJSONスキーマ - CLI:
output_configを介して渡される生のJSONスキーマ
from pydantic import BaseModel
from anthropic import Anthropic
class ContactInfo(BaseModel):
name: str
email: str
plan_interest: str
demo_requested: bool
client = Anthropic()
response = client.messages.parse(
model="claude-opus-5",
max_tokens=1024,
messages=[
{
"role": "user",
"content": "Extract the key information from this email: John Smith (john@example.com) is interested in our Enterprise plan and wants to schedule a demo for next Tuesday at 2pm.",
}
],
output_format=ContactInfo,
)
print(response.parsed_output)SDK固有のメソッド
各SDKは、構造化出力の操作を容易にするヘルパーを提供します。詳細については、各SDKのページを参照してください。
client.messages.parse()(推奨)
parse()メソッドは、Pydanticモデルを自動的に変換し、応答を検証して、parsed_output属性を返します。
from pydantic import BaseModel
class ContactInfo(BaseModel):
name: str
email: str
plan_interest: str
response = client.messages.parse(
model="claude-opus-5",
max_tokens=1024,
messages=[
{
"role": "user",
"content": "Extract contact info: John Smith, john@example.com, interested in the Pro plan",
}
],
output_format=ContactInfo,
)
# パース済みの出力に直接アクセスします
contact = response.parsed_output
print(contact.name, contact.email)transform_schema()ヘルパー
送信前にスキーマを手動で変換する必要がある場合や、Pydanticが生成したスキーマを変更したい場合に使用します。提供されたスキーマを自動的に変換するclient.messages.parse()とは異なり、このヘルパーは変換後のスキーマを返すため、さらにカスタマイズできます。
from anthropic import transform_schema
from pydantic import TypeAdapter
# まずPydanticモデルをJSONスキーマに変換し、その後変換処理を行う
schema = TypeAdapter(ContactInfo).json_schema()
schema = transform_schema(schema)
# 必要に応じてスキーマを変更する
schema["properties"]["custom_field"] = {"type": "string"}
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[{"role": "user", "content": "..."}],
output_config={
"format": {"type": "json_schema", "schema": schema},
},
)SDK変換の仕組み
Python、TypeScript、Ruby、PHPのSDKは、サポートされていない機能を持つスキーマを自動的に変換します。C#とGoのSDKは、スキーマがネイティブ型から導出される場合(C#ではCreate<T>()、GoのベータAPIでは構造体リフレクションまたはBetaJSONSchemaOutputFormat())に同じ変換を適用します。変換の手順は次のとおりです。
- サポートされていない制約を削除する(例:
minimum、maximum、minLength、maxLength) - 制約が構造化出力で直接サポートされていない場合、制約情報で説明を更新する(例:「Must be at least 100」)
- すべてのオブジェクトに**
additionalProperties: falseを追加する** - 文字列フォーマットをフィルタリングしてサポートされているリストのみにする
- 元のスキーマ(すべての制約を含む)に対して応答を検証する
つまり、Claudeは簡略化されたスキーマを受け取りますが、コードは検証を通じてすべての制約を引き続き強制します。
例: minimum: 100を持つPydanticフィールドは、送信されるスキーマではプレーンな整数になりますが、SDKは説明を「Must be at least 100」に更新し、元の制約に対して応答を検証します。
一般的なユースケース
非構造化テキストから構造化データを抽出します。
from pydantic import BaseModel
class Invoice(BaseModel):
invoice_number: str
date: str
total_amount: float
line_items: list[dict]
customer_name: str
client = anthropic.Anthropic()
invoice_text = "Invoice #12345, Date: 2024-01-15, Total: $500.00"
response = client.messages.parse(
model="claude-opus-5",
max_tokens=4096,
output_format=Invoice,
messages=[
{"role": "user", "content": f"Extract invoice data from: {invoice_text}"}
],
)
print(response.parsed_output)構造化されたカテゴリでコンテンツを分類します。
from pydantic import BaseModel
client = Anthropic()
class Classification(BaseModel):
category: str
confidence: float
tags: list[str]
sentiment: str
feedback_text = "Great product, but the delivery was slow."
response = client.messages.parse(
model="claude-opus-5",
max_tokens=1024,
output_format=Classification,
messages=[{"role": "user", "content": f"Classify this feedback: {feedback_text}"}],
)
print(response.parsed_output)APIですぐに使える応答を生成します。
from pydantic import BaseModel
client = Anthropic()
class APIResponse(BaseModel):
status: str
data: dict
errors: list[dict] | None
metadata: dict
response = client.messages.parse(
model="claude-opus-5",
max_tokens=1024,
output_format=APIResponse,
messages=[{"role": "user", "content": "Process this request: ..."}],
)
print(response.parsed_output)厳密なツール使用
文法制約付きサンプリングによってツール入力にJSON Schema準拠を強制するには、厳密なツール使用を参照してください。
両方の機能を組み合わせて使用する
JSON出力と厳密なツール使用は異なる問題を解決し、連携して動作します。
- JSON出力はClaudeの応答形式(Claudeが何を言うか)を制御します
- 厳密なツール使用はツールパラメータ(Claudeが関数をどのように呼び出すか)を検証します
組み合わせると、Claudeは有効性が保証されたパラメータでツールを呼び出し、かつ構造化されたJSON応答を返すことができます。これは、信頼性の高いツール呼び出しと構造化された最終出力の両方が必要なエージェントワークフローに役立ちます。
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[
{
"role": "user",
"content": "Help me plan a trip to Paris departing May 15, 2026",
}
],
# JSON出力: 構造化されたレスポンス形式
output_config={
"format": {
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"summary": {"type": "string"},
"next_steps": {"type": "array", "items": {"type": "string"}},
},
"required": ["summary", "next_steps"],
"additionalProperties": False,
},
}
},
# 厳密なツール使用: 保証されたツールパラメータ
tools=[
{
"name": "search_flights",
"strict": True,
"input_schema": {
"type": "object",
"properties": {
"destination": {"type": "string"},
"date": {"type": "string", "format": "date"},
},
"required": ["destination", "date"],
"additionalProperties": False,
},
}
],
)
print(response)重要な考慮事項
文法のコンパイルとキャッシング
構造化出力は、コンパイルされた文法アーティファクトによる制約付きサンプリングを使用します。これにより、注意すべきいくつかのパフォーマンス特性が生じます。
- 初回リクエストのレイテンシ: 特定のスキーマを初めて使用する際、文法のコンパイル中に追加の「latency」(レイテンシ)が発生します
- 自動キャッシング: コンパイルされた文法は最後の使用から24時間キャッシュされるため、後続のリクエストは大幅に高速になります
- キャッシュの無効化: 次のものを変更するとキャッシュが無効化されます。
- JSONスキーマの構造
- リクエスト内のツールのセット(構造化出力とツール使用の両方を使用している場合)
nameまたはdescriptionフィールドのみを変更してもキャッシュは無効化されません
プロンプトの変更とトークンコスト
構造化出力を使用する場合、Claudeは期待される出力形式を説明する追加のシステムプロンプトを自動的に受け取ります。これは次のことを意味します。
- 入力トークン数がわずかに増加します
- 挿入されたプロンプトは、他のシステムプロンプトと同様にトークンを消費します
output_config.formatパラメータを変更すると、その会話スレッドのプロンプトキャッシングが無効化されます
JSON Schemaの制限
構造化出力は標準のJSON Schemaをサポートしますが、いくつかの制限があります。JSON出力と厳密なツール使用の両方がこれらの制限を共有します。
- すべての基本型:object、array、string、integer、number、boolean、null
enum(文字列、数値、真偽値、またはnullのみ。複雑な型は不可。大文字小文字に関する注意点については無効な出力を参照)constanyOfとallOf(制限あり。$refを含むallOfはサポートされません)$ref、$def、およびdefinitions(外部$refはサポートされません)- サポートされているすべての型の
defaultプロパティ requiredとadditionalProperties(オブジェクトではfalseに設定する必要があります)- 文字列フォーマット:
date-time、time、date、duration、email、hostname、uri、ipv4、ipv6、uuid - 配列の
minItems(値0と1のみサポート)
- 再帰的スキーマ
- enum内の複雑な型
- 外部
$ref(例:'$ref': 'http://...') - 数値制約(
minimum、maximum、multipleOfなど) - 文字列制約(
minLength、maxLength) minItemsの0または1以外の配列制約false以外に設定されたadditionalProperties
サポートされていない機能を使用すると、詳細を含む400エラーが返されます。
サポートされている正規表現機能:
- 完全一致(
^...$)と部分一致 - 量指定子:
*、+、?、単純な{n,m}のケース - 文字クラス:
[]、.、\d、\w、\s - グループ:
(...)
サポートされていないもの:
- グループへの後方参照(例:
\1、\2) - 先読み/後読みアサーション(例:
(?=...)、(?!...)) - 単語境界:
\b、\B - 大きな範囲を持つ複雑な
{n,m}量指定子
単純な正規表現パターンは問題なく動作します。複雑なパターンは400エラーになる可能性があります。
プロパティの順序
構造化出力を使用する場合、オブジェクト内のプロパティはスキーマで定義された順序を維持しますが、1つ重要な注意点があります。必須プロパティが最初に表示され、その後にオプションプロパティが続きます。
例えば、次のスキーマの場合:
{
"type": "object",
"properties": {
"notes": { "type": "string" },
"name": { "type": "string" },
"email": { "type": "string" },
"age": { "type": "integer" }
},
"required": ["name", "email"],
"additionalProperties": false
}出力ではプロパティが次の順序になります。
name(必須、スキーマ順)email(必須、スキーマ順)notes(オプション、スキーマ順)age(オプション、スキーマ順)
つまり、出力は次のようになる可能性があります。
{
"name": "John Smith",
"email": "john@example.com",
"notes": "Interested in enterprise plan",
"age": 35
}出力内のプロパティの順序がアプリケーションにとって重要な場合は、すべてのプロパティを必須としてマークするか、解析ロジックでこの並べ替えを考慮してください。
無効な出力
構造化出力はほとんどの場合スキーマ準拠を保証しますが、出力がスキーマに一致しない可能性があるシナリオがあります。
拒否(stop_reason: "refusal")
Claudeは構造化出力を使用している場合でも、安全性と有用性の特性を維持します。Claudeが安全上の理由でリクエストを拒否した場合:
- 応答は
stop_reason: "refusal"になります - 200ステータスコードが返されます
- 生成されたトークンに対して課金されます
- 拒否メッセージがスキーマ制約よりも優先されるため、出力がスキーマに一致しない可能性があります
トークン制限に到達(stop_reason: "max_tokens")
max_tokens制限に達したために応答が途中で切れた場合:
- 応答は
stop_reason: "max_tokens"になります - 出力が不完全でスキーマに一致しない可能性があります
- 完全な構造化出力を得るには、より大きな
max_tokens値で再試行してください
enum値の大文字小文字
構造化出力は文字列のenumおよびconst値の大文字小文字を保証しません。Claudeは、スキーマと大文字小文字のみが異なる値を返すことがあり、通常はスペースに続く単語の最初の文字で発生します。例えば、次のスキーマの場合:
{
"type": "string",
"enum": ["Conversation Topic 1", "Conversation Topic 2", "Conversation topic 3"]
}その正確な値がenumに含まれていなくても、出力に"Conversation Topic 3"(大文字の「T」)が含まれる可能性があります。応答はエラーも特別なstop_reasonもなく正常に完了します。これはJSON出力と厳密なツール使用の両方に当てはまります。enum値は大文字小文字を区別せずに比較し、大文字小文字のみが異なるenum値は避けてください。
スキーマの複雑さの制限
構造化出力は、JSONスキーマをClaudeの出力を制約する文法にコンパイルすることで機能します。より複雑なスキーマはより大きな文法を生成し、コンパイルに時間がかかります。過度なコンパイル時間を防ぐため、APIはいくつかの複雑さの制限を適用します。
明示的な制限
次の制限は、output_config.formatまたはstrict: trueを含むすべてのリクエストに適用されます。
| 制限 | 値 | 説明 |
|---|---|---|
| リクエストあたりの厳密なツール数 | 20 | strict: trueを持つツールの最大数。厳密でないツールはこの制限にカウントされません。 |
| オプションパラメータ | 24 | すべての厳密なツールスキーマとJSON出力スキーマにわたるオプションパラメータの合計。requiredに記載されていない各パラメータがこの制限にカウントされます。 |
| ユニオン型を持つパラメータ | 16 | すべての厳密なスキーマにわたってanyOfまたは型配列(例:"type": ["string", "null"])を使用するパラメータの合計。これらは指数的なコンパイルコストを生むため、特にコストが高くなります。 |
追加の内部制限
前述の表の明示的な制限に加えて、コンパイルされた文法のサイズに関する追加の内部制限があります。これらの制限が存在するのは、スキーマの複雑さが単一の次元に還元できないためです。オプションパラメータ、ユニオン型、ネストされたオブジェクト、ツールの数などの機能は相互に作用し、コンパイルされた文法を不釣り合いに大きくする可能性があります。
これらの制限を超えると、「Schema is too complex for compilation.」というメッセージを含む400エラーが返されます。これらのエラーは、前述の表の個々の制限がすべて満たされていても、スキーマの合計の複雑さが効率的にコンパイルできる範囲を超えていることを意味します。最後の安全策として、APIは180秒のコンパイルタイムアウトも適用します。すべての明示的なチェックを通過しても非常に大きなコンパイル済み文法を生成するスキーマは、このタイムアウトに達する可能性があります。
スキーマの複雑さを軽減するためのヒント
複雑さの制限に達している場合は、次の戦略を順番に試してください。
-
重要なツールのみを厳密としてマークする。 多くのツールがある場合は、スキーマ違反が実際に問題を引き起こすツールにのみ適用し、より単純なツールについてはClaudeの自然な準拠に頼ってください。
-
オプションパラメータを減らす。 可能な限りパラメータを
requiredにしてください。各オプションパラメータは文法の状態空間の一部をおおよそ2倍にします。パラメータに常に妥当なデフォルト値がある場合は、必須にしてClaudeにそのデフォルト値を明示的に提供させることを検討してください。 -
ネスト構造を簡素化する。 オプションフィールドを持つ深くネストされたオブジェクトは複雑さを増大させます。可能な限り構造をフラットにしてください。
-
複数のリクエストに分割する。 多くの厳密なツールがある場合は、それらを別々のリクエストやサブエージェントに分割することを検討してください。
有効なスキーマで問題が解決しない場合は、スキーマ定義を添えてサポートにお問い合わせください。
データ保持
構造化出力を使用する場合、プロンプトと応答はZDRで処理されます。ただし、JSONスキーマ自体は最適化のために最後の使用から最大24時間一時的にキャッシュされます。プロンプトや応答のデータはAPI応答を超えて保持されません。
構造化出力はHIPAA適格ですが、PHIをJSONスキーマ定義に含めてはなりません。APIはJSONスキーマをメッセージコンテンツとは別にキャッシュされる文法にコンパイルし、これらのキャッシュされたスキーマはプロンプトや応答と同じPHI保護を受けません。スキーマのプロパティ名、enum値、const値、またはpattern正規表現にPHIを含めないでください。PHIは、HIPAAの保護措置の下で保護されるメッセージコンテンツ(プロンプトと応答)にのみ含めるべきです。
すべての機能にわたるZDRおよびHIPAAの適格性については、APIとデータ保持を参照してください。
機能の互換性
併用可能:
- バッチ処理: 50%割引で構造化出力を大規模に処理します
- トークンカウント: コンパイルなしでトークンをカウントします
- ストリーミング: 通常の応答と同様に構造化出力をストリーミングします
- 組み合わせ使用: JSON出力(
output_config.format)と厳密なツール使用(strict: true)を同じリクエストで併用します
互換性なし:
- 引用: 引用は引用ブロックをテキストと交互に配置する必要があり、これは厳密なJSONスキーマ制約と競合します。
output_config.formatで引用が有効になっている場合は400エラーが返されます。 - メッセージのプリフィル: JSON出力と互換性がありません
次のステップ
提供されたドキュメントに関する質問に答える際に、Claudeに出典を引用させます。
文法制約付きサンプリングによって、ClaudeのツールインプットにJSON Schema準拠を強制します。
Claudeを外部ツールやAPIに接続します。ツールがどこで実行され、エージェントループがどのように機能するかを学びます。
モデルと機能に関するAnthropicの価格体系について学びます。
Compatibility
| Supported models |
|
|---|---|
| Supported platforms |
|
- Amazon Bedrockでは、構造化出力はClaude Opus 4.6、Claude Sonnet 4.6、Claude Sonnet 4.5、Claude Opus 4.5、およびClaude Haiku 4.5で利用できます。 ↩
Was this page helpful?