先に結論:Structured Output は「JSON を返してください」というプロンプトではありません。API がデコード時に JSON Schema で不正な token を遮断し、最終返答をプログラムがそのままパースできるようにする仕組みです。GPT、Gemini、Claude がこれを第一級の機能にしたのは、スライド映えするからではなく、Agent、抽出、フォーム入力がモデルをパイプラインに接続しなければならないからです。散文は JSON.parse を通りません。下流の Schema はさらに通りません。
本稿は2026年9月8日時点の内容です。三社ともいま、ユーザーまたは次のサービスへ渡す最終 JSON を制約できます:OpenAI は response_format.json_schema(strict)、Gemini は responseMimeType + responseJsonSchema、Claude は GA 済みの output_config.format(旧 beta の output_format は移行期間中も使えます)。フィールドの書き方とサブセットの差は、8月にすでに整理しました。本稿が答えるのは二つだけです:それは何か、そして三社がなぜ出さざるを得なかったか。手順は《Prompt から Structured Output へ》を見てください。OpenAI と Gemini の対照は《Structured Output API 比較》です。
Structured Output とは何か
Structured Output とは:先に JSON Schema を渡し、モデルの最終返答がその Schema に合う JSON でなければならない、ということです。保証は各 token を生成するときに起きます。「JSON らしく見せよう」としたあとではありません。名前は違います:OpenAI は Structured Outputs、Google は Structured Output、Anthropic は structured outputs / JSON outputs と書きます。余分な s はブランディングです。仕事は同じです。
コンパイラと型検査だと思ってください。プロンプトはコメントです——モデルは聞くかもしれません。Schema は型システムです——誤ったフィールド名、欠けた required、数値であるべき場所の文字列は、そもそも出てきません。プログラムが受け取るのはオブジェクトであり、```json フェンスに包まれた散文ではありません。
| 言い方 | 実際の意味 | よくある誤読 |
|---|---|---|
| Structured Output | 最終返答を JSON Schema に対して制約デコードする | モデルが賢くなった、あるいは「JSON が書ける」 |
| JSON Schema | フィールド、型、必須、enum の契約 | より長いプロンプトと同じ |
| 制約デコード | 生成中に不正な token をフィルタする | 生成後に正規表現で直す |
| strict / ハード制約 | API がより厳しい Schema サブセットで形を保証する | 事実が正しく、数字が捏造されていないこと |
三社が読める Schema は、だいたい扁平です:ルートは object、properties / required を明示し、additionalProperties: false。OpenAI の strict では、「任意」は required から外すのではなく、nullable にすることが多いです。サブセットは同一ではありません。先に交差を取ってください。
{
"type": "object",
"additionalProperties": false,
"properties": {
"task": { "type": "string", "enum": ["extract", "classify", "summarize"] },
"ok": { "type": "boolean" },
"fields": {
"type": "object",
"additionalProperties": false,
"properties": {
"orderId": { "type": "string" },
"total": { "type": "number" },
"note": { "type": ["string", "null"] }
},
"required": ["orderId", "total", "note"]
}
},
"required": ["task", "ok", "fields"]
}
JSON Mode でも、Tool Calling でもない
三つの名前が一つに潰されがちです。層が違います:
| 能力 | 保証すること | 保証しないこと |
|---|---|---|
| プロンプト「JSON を返せ」 | 確率が上がること | 構文、フィールド名、必須リスト |
| JSON Mode | テキストがパース可能な JSON であること | 形、型、enum |
| Structured Output | 最終返答が Schema に合うこと | 意味が真実であること、ツールが実行されたこと |
| Tool Calling | ツール引数が Schema に合い、Host が実行すること | ユーザー向け最終返答の形 |
JSON Mode が保証するのは、括弧が対応し、JSON.parse が通ることだけです。モデルは、あなたが orderId を求めても order_id を発明できますし、金額を文字列で出せます。本番では、「パースできる」は「INSERT できる」ではありません。
Tool Calling / Function Calling が制約するのは、ツールへ伸ばす手であり、ユーザーへの最後の一文ではありません。在庫照会、ファイル書き込み、MCP の tools/call はツール側 Schema です。メール抽出、チケット分類、下流 API 向け JSON の出力は Structured Output です。本格的な Agent はしばしば両方を開きます——引数は tools、最終返答は出力 Schema。層の分け方は《MCP とは》と《Agent の JSON データフロー》を見てください。
三社がそろって対応し始めた理由
2023年なら、プロンプトに賭けることもまだできました。2026年の Agent はモデルをループに埋め込みます:出力はデータベースへ、次のツールへ、別ベンダーのモデルへ入ります。三社がプレスを合わせて出したわけではありません。同じ製品圧力と、同じ契約——JSON Schema——にぶつかったのです。
- 下流の消費者は読者ではなく、プログラムです。チャットは散文でよい。パイプラインはオブジェクトが要ります。カンマが一つ欠け、フィールド名が一つ変われば、夜間の再試行キューが埋まります。ベンダーは、顧客一人ひとりに修復ロジックを書かせるより、デコーダで不正な経路を切りたいのです。
- Agent が「形が安定していること」を必須にしました。多段ループでは、前ターンの JSON が今ターンの入力です。一度ドリフトすれば、その先は全部違います。Tool Calling が答えるのは「どう手を伸ばすか」。Structured Output が答えるのは「結論をどう返すか」。どちらも Schema が要ります——《JSON Schema は Agent の Contract になるか》を見てください。
- プロンプトでは足りないことが証明されました。「JSON のみ、markdown なし」はベンチではよく見えます。しかし長いコンテキスト、ツールの再注入、言語の混在では、フィールドを落とし、フェンスを足し、enum を類義語に言い換えます。制約デコードは「ときどき」を API 400 か、再試行できる Schema エラーに変えます。
- JSON Schema はすでに最小公約数でした。OpenAPI、MCP の
inputSchema、Pydantic / Zod のエクスポート——どれもそれです。モデル側に別の独自 IDL を置けば、Host は二重に翻訳しなければなりません。最終返答を同じ Schema に繋ぐことこそ、ベンダー入れ替えを安くします。 - 競争は「チャットできるか」ではなく、「本番に出せるか」になりました。一社がハード制約を出すと、ゲートウェイ、Agent フレームワーク、調達リストは必須項目に書きます。残る二社は追随するか、同じ編成に差し込めなくなります。2026年9月、Structured Output のないフラッグシップ API は、行を INSERT する顧客には売りにくいです。
だから日付が固まります:OpenAI は 2024年8月に Structured Outputs を GA にしました。Gemini は MIME + Schema を生成設定に取り込みました。Claude は 2025年末まで beta ヘッダのままで、いまは output_config.format を安定フィールドとして出しています。名前は一度も揃いませんでした。圧力は揃いました。
GPT、Gemini、Claude それぞれの開き方
概念は揃えてください。フィールドをベンダー横断で貼り付けないでください。下表は 2026年9月8日にドキュメントへ書ける入口であり、完全な SDK チュートリアルではありません。
| ベンダー | 入口 | Schema の付け先 | 2026年に注意すること |
|---|---|---|---|
| OpenAI(GPT-5.5 など) | Chat Completions の response_format;Responses API の text.format | type: json_schema + strict: true | strict では各 object に additionalProperties: false が要り、プロパティは通常すべて required に入る;任意は nullable にする |
| Google(Gemini 3.7 Flash など) | 生成設定の MIME + Schema | responseMimeType: application/json + responseJsonSchema(SDK ではよく response_schema) | strict という名前のスイッチはない;旧 responseSchema は OpenAPI の大文字型を使っていた;新しい経路は JSON Schema の小文字型 |
| Anthropic(Claude 4.6 / 4.8 など) | Messages API の output_config.format | type: json_schema + schema | すでに GA。structured-outputs-2025-11-13 ヘッダは不要;旧 output_format は移行期間中も使える。ツール側の strict: true は Tool Calling であり、最終返答ではない |
ラッパーは違います。Schema 本体は同じファイルであるべきです。モデルを替えるのは封筒であり、orderId と required ではありません。Claude の例(仕様フィールド。業務 Schema は差し替えてください):
{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Extract orderId and total from the order text"}
],
"output_config": {
"format": {
"type": "json_schema",
"schema": {
"type": "object",
"additionalProperties": false,
"properties": {
"orderId": { "type": "string" },
"total": { "type": "number" }
},
"required": ["orderId", "total"]
}
}
}
}
OpenAI は同じ schema を response_format.json_schema に置き、strict を入れます。Gemini は responseJsonSchema に置き、JSON MIME を宣言します。完全な Python 対照は、いまも《OpenAI vs Gemini》にあります。製品面(ChatGPT / claude.ai / Gemini ウェブ)が同じハード制約を出すとは限りません。SLA は、実際に呼ぶその API に対して書いてください。
制約デコードが実際に止めるもの
Structured Output がないとき、モデルは語彙全体からサンプリングし、プロンプトで JSON らしく見えることを期待します。Structured Output があるとき、デコーダは Schema から合法な接頭辞を維持します:次の token はまだ合法なものだけ——"、orderId、true、または }。不正な経路の確率はゼロになります。
止めるのは形です:末尾カンマ、markdown フェンス、必須の欠落、型のドリフト、additionalProperties が false のときの余分なキー。止めないのは捏造です:total は number でも、値は作り出せます。合法な enum 値でも、間違ったものを選べます。本番では同じ Schema を検証器に通し、失敗したら再試行、劣化、または人手へ回します。制約デコードが減らすのはパース事故であり、幻覚ではありません。
窓が大きくても同じです。1M token は見える材料を増やすだけで、出力の形は縛りません。ダンプを詰め込んでも、Schema は要ります——《1M Token コンテキストウィンドウ》を見てください。
いまどう使うか
- 先に Schema を書き、それからモデルを選んでください。フィールド名、必須、enum は製品契約です。GPT / Gemini / Claude は入れ替え可能なバックエンドです。契約はリポジトリに置き、プロンプトに書かないでください。
- 抽出、分類、フォーム入力は Structured Output。副作用は Tool Calling。Structured Output が在庫 API をすでに叩いたかのように装わないでください。プロセスをまたいでツールを再利用するなら、そこで MCP を足します。
- ベンダー横断では Schema の交差を取る:扁平な object、
additionalProperties: false、浅い$ref、ルートのanyOfは使わない。OpenAI の strict は「任意」を nullable にします。三社それぞれがドリフトするフィールド表を持たないでください。 - API が通っても、それが最後の検査ではありません。Schema と 2〜3 組の正 / 反フィクスチャを JSON として保存し、本サイトで検証と Diff をしてください。何もアップロードされません。制約デコードのあとの第二関門です。
- 失敗は構造化して戻す:パースや二次検証が失敗したら、オブジェクトで返す(どのフィールド、期待型)。生のスタックトレースを次のターンに流し込まないでください。
FAQ
Structured Output は「モデルに JSON を出させる」だけですか?
いいえ。プロンプトや JSON Mode でも JSON テキストは出せます。Structured Output はデコード時に JSON Schema で token をフィルタします。フィールド名、型、必須は API が強制するのであり、モデルが素直に振る舞うことではありません。
なぜ GPT、Gemini、Claude がみな出すのか——一社では足りないのか?
顧客はマルチモデルのフェイルオーバーと価格比較を求めます。ゲートウェイと Agent フレームワークはすでに「Schema を入れ、JSON を出す」で配線しています。ハード制約のないベンダーは、そのパイプラインに差し込めません。競争圧力と工学上の必要は同じ事実です。
Claude はまだ偽のツールで Structured Output のふりをする必要がありますか?
主経路としては不要です。2026年の Messages API は output_config.format で JSON Schema 出力を出しています。ツール側の strict は、いまもツール引数だけをカバーします。旧 beta ヘッダと output_format は移行期間に残っています。新しいコードは output_config を使ってください。
Structured Output を入れても、自分で検証しますか?
します。保証するのは形と型であり、値の真実やビジネス規則ではありません。同じ Schema をアプリ層でもう一度走らせ、失敗したら再試行または人手へ上げます。ブラウザでは、先に JSON ツールボックスでフィクスチャを見てください。
これと MCP、Tool Calling はどう選びますか?
プログラム向けの最終返答:Structured Output。外部アクション:Tool Calling。別プロセスのツールを Host 横断で再利用:MCP。三層は重ねられます。一層で別の層のふりをさせないでください。
同じ JSON Schema を三社にそのまま送れますか?
本体は共有できます。リクエストのラッパーはできません。扁平な object、余分なプロパティなし、任意は nullable——これが最も通りやすいです。OpenAI の strict サブセットが一番狭いので、先にそれを通し、同じファイルを Gemini / Claude に渡す方が、三社でドリフトする Schema を持つより安いです。
まとめ
Structured Output は 2026年フラッグシップ API の標準ソケットです:最終返答は JSON Schema に対してデコードされ、プログラムはプロンプトの括弧に賭けるのをやめます。GPT、Gemini、Claude がみな出したのは、Agent と抽出が「形が安定していること」を受け入れ条件に書き、JSON Schema が三社ともすでに話していた契約だったからです。JSON Mode ではありません。Tool Calling や MCP の代わりにもなりません。
モデルを替えるなら、ラッパーのフィールドだけを替えてください。フィールド名と required はリポジトリに置き、本番前に同じ Schema でサンプルをローカル検証してください。各社 API の設定と、ツール層との分担は、本サイトですでに書いています。本稿は「何か、なぜか」だけをはっきりさせます。