いずみこんな悩みを解決できる記事を書きました!
僕は現役フリーランスエンジニア(歴10年)で、資格は13個保有しています。
「Claude APIの返答を決まったJSON形式で確実に受け取りたい」とお考えではありませんか?
プロンプトで「JSONで返して」と指示しても、前後に説明文が付いたりキーが抜けたりして、json.loads()で例外が出ることがあります。
Structured Outputsを使うと、指定したJSONスキーマに必ず一致した出力が返ります。



パースの失敗やリトライ処理を書かずに済むので、実装がかなり楽になります。
ということで、本記事ではClaude APIのStructured Outputsで出力をJSONに固定する方法を解説します。



すぐ読み終わるので、ぜひ最後まで読んでくださいませ。
| 【当サイト】おすすめフリーランスエージェント3選 | |||
|---|---|---|---|
| エージェント | 評価 | ポイント | 公式サイト |
レバテックフリーランス | 5.0 | 業界最大級のエージェント。 高単価案件が豊富。 | 公式 |
Midworks | 4.8 | 満足度調査で 3年連続3冠を達成。 | 公式 |
ITプロパートナーズ | 4.6 | 週2〜3向けの案件が豊富。 | 公式 |
【AI】Claude APIのStructured Outputsで出力をJSONに固定する
早速、Claude APIのStructured Outputsで出力をJSONに固定する手順を見ていきます。
Structured Outputsとは
Structured Outputsは、Claudeの生成結果を指定したJSONスキーマに強制的に一致させる機能です。
スキーマをプロンプトに書いて「従ってください」とお願いするのではなく、推論中のトークン生成をスキーマから作った文法で制限するしくみになっています。
結果として、キーの抜けや型の違い、前後に余計なテキストが混ざる問題が起きません。
機能は大きく2つに分かれます。
- JSONアウトプット(output_configで応答全体を指定のJSONにする)
- 厳密なツール使用(strictでツール引数をスキーマ通りにする)



「だいたいJSON」ではなく「必ずスキーマ通りのJSON」になるのが従来との違いです。
事前準備
Python用のSDKをインストールします。
pip install anthropicAPIキーを環境変数に設定します。
export ANTHROPIC_API_KEY="your_api_key"anthropicライブラリは環境変数ANTHROPIC_API_KEYを自動で読み込みます。
JSONスキーマで出力を固定する
一番基本的な使い方は、messages.createにoutput_configを渡す方法です。
import json
import anthropic
client = anthropic.Anthropic()
schema = {
"type": "object",
"properties": {
"title": {"type": "string"},
"tags": {"type": "array", "items": {"type": "string"}},
"priority": {"type": "integer"},
},
"required": ["title", "tags", "priority"],
"additionalProperties": False,
}
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
messages=[
{"role": "user", "content": "次の問い合わせを分類して: ログイン画面でエラーが出て入れない"}
],
output_config={
"format": {"type": "json_schema", "schema": schema}
},
)
text = next(block.text for block in response.content if block.type == "text")
data = json.loads(text)
print(data["title"], data["tags"], data["priority"])output_config.format.typeにjson_schemaを指定し、schemaに受け取りたい形を書きます。
additionalPropertiesをfalseにして、requiredに必須キーを並べるのがポイントです。
返ってきたテキストブロックはスキーマ通りのJSON文字列なので、json.loads()でそのまま辞書へ変換できます。



「説明文が先頭に付いてパースに失敗する」といった定番のトラブルが消えます。
Pydanticモデルで受け取る
PythonではPydanticモデルを使うと、辞書ではなく型付きオブジェクトで受け取れます。
messages.parseにoutput_formatとしてモデルクラスを渡します。
from pydantic import BaseModel
import anthropic
class Ticket(BaseModel):
title: str
tags: list[str]
priority: int
client = anthropic.Anthropic()
response = client.messages.parse(
model="claude-sonnet-5",
max_tokens=1024,
messages=[
{"role": "user", "content": "次の問い合わせを分類して: ログイン画面でエラーが出て入れない"}
],
output_format=Ticket,
)
ticket = response.parsed_output
print(ticket.title, ticket.tags, ticket.priority)パース済みの値はresponse.parsed_outputから取り出せます。
messages.parseはスキーマへの変換とバリデーションをSDK側で行ってくれるため、JSON Schemaを手書きする必要がありません。



既存コードでPydanticを使っているなら、parseのほうが自然に組み込めます。
ツールの引数をスキーマ通りにする
ツール使用でも、引数の形が崩れて困ることがあります。
ツール定義にstrictをtrueで追加すると、Claudeが渡す引数がinput_schemaに必ず一致します。
tools = [
{
"name": "create_ticket",
"strict": True,
"description": "サポートチケットを登録する",
"input_schema": {
"type": "object",
"properties": {
"title": {"type": "string"},
"priority": {"type": "integer"},
},
"required": ["title", "priority"],
"additionalProperties": False,
},
}
]
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
tools=tools,
messages=[
{"role": "user", "content": "緊急でログイン不具合のチケットを作って"}
],
)エージェント的な処理で、ツール呼び出しの引数を検証するコードを減らせます。
対応していないスキーマ機能
Structured Outputsで使えないJSON Schemaの機能があります。
- 再帰的なスキーマ
- minimum / maximum / multipleOf などの数値制約
- minLength / maxLength などの文字列長制約
- 外部参照($refでURLを指す形)
- false以外のadditionalProperties
対応していない機能を使うと、詳細付きの400エラーが返ります。
数値の範囲などをどうしても縛りたい場合は、スキーマ側ではなくレスポンス受け取り後のバリデーションで対応します。



messages.parseを使うと、元のPydanticモデルに書いた範囲制約は受け取り後のチェックで効きます。
| 【当サイト】おすすめフリーランスエージェント3選 | |||
|---|---|---|---|
| エージェント | 評価 | ポイント | 公式サイト |
レバテックフリーランス | 5.0 | 業界最大級のエージェント。 高単価案件が豊富。 | 公式 |
Midworks | 4.8 | 満足度調査で 3年連続3冠を達成。 | 公式 |
ITプロパートナーズ | 4.6 | 週2〜3向けの案件が豊富。 | 公式 |
【厳選】フリーランスエンジニアにおすすめなエージェント3選


フリーランスエンジニアになるにはエージェントから案件をもらう必要があります。
僕が実際に利用しているおすすめエージェントを紹介しますね。



エージェントは必ず複数登録してください。
担当者によっては「全然案件紹介してくれない…」みたいなこともあるので…
僕は実際に5つのエージェントを使い回していますよ。
フリーランスを始めるなら「レバテックフリーランス


」
- 業界最大級の案件数。
- 業界トップクラスの高単価報酬、低マージン(平均年収862万円)。
- 案件参画中のフォローの充実。
※詳細は「【業界最大手】レバテックフリーランスとは?メリットや利用手順を解説!」を参照。
レバテックフリーランス
![]()
![]()
とにかく案件数が多いので、とりあえず登録しておけば間違いないエージェントです!



僕もはじめてフリーランスの案件を貰ったのはレバテックフリーランス
![]()
![]()
保有している案件数が多いので、業務経験がなくても何かしらの案件は紹介してもらえますよ(僕はJavaの経験3年でも案件を貰えました)。
手厚い保障を重視したいなら「Midworks


」
- 手厚い保障で正社員並みの安心感。
- 還元率60%超え&単価公開でクリアな契約。
- 給与保障制度(審査あり)。
Midworks
![]()
![]()
フリーランスを目指しているけど不安な方や保障を重視したい方におすすめです。



僕も何度か案件を紹介してもらいました。
自分のスキルに合った案件を紹介してもらえましたし、電話のやり取りも非常に丁寧でした。
週2〜3日の案件探しなら「ITプロパートナーズ


」
- IT案件に特化したフリーランスエージェント。
- 週2〜3日の案件が豊富。
- リモート案件が多く、直エンドなので単価も高い。
※詳細は「【週2・3案件】ITプロパートナーズとは?メリットや利用手順を解説!」を参照。
ITプロパートナーズ
![]()
![]()
週2〜3日から参画できる案件が豊富なので、起業したい人にもおすすめです。



週2〜3日の案件はある程度スキルがないと紹介してもらえない印象です。
とはいえ、週5の案件ももちろんありますし、僕が利用した時は迅速・丁寧に対応していただきました!
よくある質問
Structured Outputsを使うのにベータ設定は必要ですか?
特別なベータヘッダーは不要です。
messages.createのoutput_config、またはmessages.parseのoutput_formatを指定するだけで使えます。
どのモデルで使えますか?
Claude Sonnet 5やOpus 5、Haiku 4.5などで利用できます。
コード生成や複雑な分類を任せるならSonnet 5、軽い抽出タスクならHaiku 4.5が向いています。
通常のツール使用と厳密なツール使用は何が違いますか?
通常のツール使用は引数の形がずれることがありますが、strictをtrueにするとinput_schemaに必ず一致します。
ツール名のタイプミスのような不一致も防げます。
必ずスキーマ通りの内容になりますか?
トークン生成をスキーマから作った文法で制限しているため、形式は一致します。
ただし値の中身が業務的に正しいかは別問題なので、重要な値は受け取り後にチェックすることをおすすめします。
まとめ
今回は、Claude APIのStructured Outputsで出力をJSONに固定する方法について解説しました。
以下が本記事のまとめになります。



最後までお読みいただき、ありがとうございました!
| 【当サイト】おすすめフリーランスエージェント3選 | |||
|---|---|---|---|
| エージェント | 評価 | ポイント | 公式サイト |
レバテックフリーランス | 5.0 | 業界最大級のエージェント。 高単価案件が豊富。 | 公式 |
Midworks | 4.8 | 満足度調査で 3年連続3冠を達成。 | 公式 |
ITプロパートナーズ | 4.6 | 週2〜3向けの案件が豊富。 | 公式 |
- クソおすすめ本



海外のエンジニアがどういった思考で働いているかが理解できます。
海外に行く気はないけど海外エンジニアの動向が気になる雑魚エンジニアにおすすめです(本当におすすめな本しか紹介しないのでご安心を)。








