Claude Media
Claude JSONモードの使い方 — structured outputsでJSON出力を固定する

Claude JSONモードの使い方 — structured outputsでJSON出力を固定する

ClaudeでJSONを確実に返す機能はstructured outputsという名前で提供されます。output_config.formatの実装手順と、tool use・Claude Codeとの違いを扱います。

ClaudeでJSON出力を確実に固定する公式機能は、「JSONモード」という名前ではなくstructured outputsです。リクエストにoutput_config.formatを1つ加えるだけで、JSON Schemaに沿った応答が返ります。この記事ではAPIでの実装手順、tool useとの使い分け、Agent SDK・Claude Code CLIでの指定方法の違いまで扱います。

Claude JSONモードの正体 — structured outputsとの関係

structured outputsとは、Claudeの応答を指定したJSON Schemaへ強制的に一致させる機能です。中身はJSON outputs(output_config.format)とStrict tool use(strict: true)という2つの独立した仕組みの総称で、片方だけでも両方同時にでも使えます。プロンプトでいくら「JSON形式で返して」と頼んでも、Claudeは崩れたJSONや必須フィールド欠けを返すことがあります。プロンプトだけでは足りません。structured outputsは制約付きデコーディングでこれを構造から防ぎ、JSON.parse()失敗のリトライ処理そのものを不要にします。

Claude APIでは、Claude 4.5以降のモデルとClaude Mythos Previewが対応します。Amazon Bedrock・Google Cloud Vertex AI・Microsoft Foundryでも使えますが、対応モデルの範囲は面ごとに異なります。Amazon BedrockはOpus 5・Opus 4.8・Opus 4.6・Sonnet 4.6・Sonnet 4.5・Opus 4.5・Haiku 4.5が対応し、Sonnet 5・Opus 4.7・Mythos PreviewはClaude in Amazon Bedrock経由での提供です。Google CloudはFable 5・Mythos 5・Opus 5などが対応します。Microsoft Foundryで使うにはHosted on Anthropicデプロイが必要です。

旧来はoutput_formatという単体パラメータでしたが、現在はoutput_config.formatに統合されています。旧パラメータと旧ベータヘッダー(structured-outputs-2025-11-13)は移行期間中は動作を続けますが、新規実装ではoutput_config.formatを使います。

output_config.formatでJSON出力を固定する手順

前提はAnthropic APIキーと、対応モデル(Opus 5・Sonnet 5・Haiku 4.5などのClaude 4.5以降、またはMythos Preview)です。SDKは最新版を使います。output_configは新しいパラメータ形状のため、古いバージョンのSDKでは認識されません。

手順は3つです。JSON Schemaを定義し、output_config.formattype: "json_schema"と一緒に渡し、返ってきたテキストブロックをスキーマ通りのJSONとして扱います。

curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-opus-5",
    "max_tokens": 1024,
    "messages": [
      {"role": "user", "content": "田中太郎(tanaka@example.com)がEnterpriseプランのデモを来週火曜14時に希望しています"}
    ],
    "output_config": {
      "format": {
        "type": "json_schema",
        "schema": {
          "type": "object",
          "properties": {
            "name": {"type": "string"},
            "email": {"type": "string", "format": "email"},
            "plan_interest": {"type": "string"},
            "demo_requested": {"type": "boolean"}
          },
          "required": ["name", "email", "plan_interest", "demo_requested"],
          "additionalProperties": false
        }
      }
    }
  }'

応答のcontentにあるtextブロックには、スキーマに一致する値だけが入ります。requiredadditionalPropertiesはどちらもサポート対象で、additionalPropertiesだけがfalse固定です。false以外を指定すると400エラーになります。

PythonやTypeScriptではPydantic・Zodをそのまま使えます。client.messages.parse()にモデルを渡すと、SDKがJSON Schemaへの変換とレスポンスの検証を自動でやってくれます。Python SDKのclient.messages.parse()は利便性のためoutput_format引数を今も受け付け、内部でoutput_config.formatへ変換します。他のSDKではoutput_configを直接指定します。

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": "田中太郎(tanaka@example.com)がEnterpriseプランのデモを来週火曜14時に希望しています"}],
    output_format=ContactInfo,
)
print(response.parsed_output.name, response.parsed_output.email)

TypeScriptならzodOutputFormat()でZodスキーマをそのまま渡せます。生のJSON Schemaを直接書きたいときはjsonSchemaOutputFormat()が使えますが、型推論を効かせるにはas constでリテラル宣言する必要があります。

structured outputsとtool useの使い分け

JSON出力全体を固定したいならJSON outputs、個別のツール呼び出しの引数だけを保証したいならStrict tool useを使います。目的が違う2つの仕組みなので、同じリクエストで両方を有効にすることもできます。

目的使う機能指定方法
Claudeの最終応答をJSON Schemaに固定する使う機能JSON outputs指定方法output_config.format
ツール呼び出しの引数(input)をスキーマ通りに保証する使う機能Strict tool use指定方法ツール定義にstrict: true
ツールを使った後の最終成果物も固定する使う機能両方併用指定方法output_config.formatとツールのstrict: trueを同一リクエストに含める

たとえば旅行計画エージェントなら、search_flightsツールの引数をstrict: trueで保証しつつ、Claudeが最後にまとめるsummarynext_stepsoutput_config.formatで固定できます。Claudeは先にツールを呼ぶことも、直接JSONで応答することもあり、stop_reasonを見てどちらが起きたかを判定します。グラマーによる制約はClaudeの直接出力にだけかかり、ツール呼び出しや思考(thinking)の中身には及びません。セクションが切り替わるたびにグラマーの状態はリセットされるので、Claudeは自由に考えてから、最後だけ構造化して答えられます。

API・Agent SDK・Claude Code CLIで指定方法が異なる

同じstructured outputsでも、呼び出す面によって指定方法とふるまいが変わります。単発リクエストのAnthropic API、ツール呼び出しを挟む複数ターンのAgent SDK、ターミナルから叩くClaude Code CLIの3つで、それぞれ違います。

指定方法特徴
Anthropic API(単発)指定方法output_config.format特徴Messages APIへの1リクエストで完結する
Agent SDK query()指定方法TS: outputFormat / Python: output_format特徴複数ターンのツール呼び出しを経て、完了時にstructured_outputフィールドで返る。検証失敗時は自動で再プロンプトする
Claude Code CLI(-p)指定方法--json-schema特徴print modeでの単発実行。v2.1.205以降はスキーマが不正だと起動時にエラーで停止する(それ以前はエラーを出さずに無構造の出力に戻っていた)

Agent SDKはツール呼び出しを挟む分、検証の失敗をリトライで吸収します。リトライ上限に達するとstructured_outputを返さず、error_max_structured_output_retriesというsubtypeで終了します。モデルフォールバックが出力を取り消し、代わりのリトライが無かった場合も同じsubtypeになるため、原因を切り分けるには結果メッセージのerrors一覧を見ます。

JSON Schemaの落とし穴とエラー処理

structured outputsが対応するJSON Schemaは標準の一部だけです。保存前に次の点を確認します。

  • additionalPropertiesはfalse固定で、オブジェクトにそれ以外の値を指定すると400エラーになる
  • String formatsはdate-timetimedatedurationemailhostnameuriipv4ipv6uuidに対応する。メールアドレスのような項目にはこれらを指定すると検証精度が上がる
  • 数値・文字列の制約は非対応。minimummaximummultipleOfminLengthmaxLengthはそのまま送ると拒否される。Pydantic・Zod経由ならSDKが制約を自動で取り除きdescriptionへ言い換えて送るため、この変換を手作業でやらずに済む
  • 再帰スキーマ・外部$ref・enum内の複合型は非対応。$ref$defはスキーマ内で完結する参照のみ使える
  • 配列のminItemsは0か1のみ対応する。2件以上を必須にしたいときはdescriptionで指示するか、応答後にアプリ側で件数を検証する
  • enum・constの文字列は大文字小文字がずれることがある。スペースに続く単語の先頭文字で起きやすい既知の挙動で、比較は大文字小文字を無視して行う
  • プロパティの並び順はrequiredが先になる。スキーマでnotesを先に書いても、requiredに含めたnameemailが先に出力されるため、順序に依存するならすべてrequiredにする
  • 拒否(refusal)とmax_tokens超過はスキーマの外側になる。安全上の理由でClaudeが拒否するとstop_reasonrefusalになり、200が返って課金も発生するが本文はスキーマに従わない。max_tokensで切れた場合は出力が不完全なまま終わるため、上限を上げて再試行する
  • スキーマの複雑さには上限がある。strict: trueのツールは1リクエストあたり20個まで、required外の任意プロパティは全スキーマ合計で24個まで、anyOfや型配列を使う項目は16個までで、超えると「Schema is too complex for compilation」という400エラーになる。コンパイルのタイムアウトは180秒で、項目を減らす・ネストを浅くする・複数リクエストに分けるのが対処になる
  • 初回はコンパイルで少し遅くなる。コンパイル済みグラマーは最終利用から24時間キャッシュされ、スキーマ構造やツール構成を変えると無効になる(namedescriptionだけの変更では無効にならない)。structured outputsは出力形式を説明する追加のシステムプロンプトを挿入するため入力トークンがわずかに増え、output_config.formatを変更するとその会話のプロンプトキャッシュも無効になる
  • Citationsとは併用できず、有効にすると400エラーになる。Message prefillingとも併用できない。一方でストリーミング・トークンカウント・50%割引のBatch処理とは組み合わせられる
  • Agent SDKでZodスキーマを渡すときはz.toJSONSchema(schema, { target: "draft-7" })でdraft-07に変換してから渡す。Zodは既定でdraft 2020-12形式のスキーマを出力するため、変換しないままだとAgent SDK側のバリデーションで弾かれる

まとめ

Claudeに「json mode」という機能名はありません。実装はstructured outputsのoutput_config.formatにJSON Schemaを渡す形に集約されており、ツールの引数まで保証したいならStrict tool useを重ねます。単発のAPI呼び出しか、ツールを挟むAgent SDKか、ターミナルから叩くClaude Code CLIかで指定方法だけが変わり、検証の仕組み自体は共通です。既存のtool useの実装は高度なTool use、Anthropic API全体の構造はAnthropic API完全ガイド、Agent SDKでの組み方はAgent SDKクイックスタートにまとめています。

よくある質問

output_formatパラメータはまだ使えますか

移行期間中は動作を続けます。ただし新規実装ではoutput_config.formatを使う設計にします。挙動が変わるわけではなく、パラメータの置き場所が変わっただけです。

JSON以外の形式(YAMLやXMLなど)も強制できますか

できません。structured outputsが保証するのはJSON Schemaに一致するJSONだけです。他形式が必要なら、JSONで受け取ってからアプリ側で変換します。

ストリーミングと併用できますか

できます。ただしスキーマに従ったJSONかどうかはストリームの断片単位では判定できないため、レスポンスを最後まで蓄積してからパースします。

HIPAA環境でPHI(医療に関する個人情報)を扱えますか

structured outputs自体はHIPAA適格ですが、JSON Schemaの定義にPHIを含めてはいけません。スキーマはグラマーとしてメッセージ本文とは別にキャッシュされ、本文と同じ保護を受けないためです。PHIはプロンプトと応答の中身だけに置きます。

Batch APIの50%割引は構造化出力にも適用されますか

適用されます。大量の抽出・分類タスクをスキーマ固定で流したいときは、Batch処理と組み合わせるとコストを抑えられます。

この記事を共有:XはてブLinkedIn