【AI】Claude APIのStructured Outputsを使う方法

当ページのリンクには広告が含まれています。
いずみ

こんな悩みを解決できる記事を書きました!

僕は現役フリーランスエンジニア(歴年)で、資格は個保有しています。

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向けの案件が豊富。公式
執筆者/監修者
  • フリーランスエンジニア(保有資格個、企業と直接契約
  • ブログ・アフィリエイト歴7年(2018年〜)
  • ブランドせどりで月利50万円⇨脱サラ
  • 投資(仮想通貨・FX)歴7年(2018年〜)
  • X(旧Twitter)フォロワー約1,900人
  • 運営者情報はこちら
いずみです
目次

【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 anthropic

APIキーを環境変数に設定します。

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つのエージェントを使い回していますよ。

フリーランスを始めるなら「

案件数マージン率単価
約88,000件非公開
初心者福利厚生申し込み
無料
Good Point
  • 業界最大級の案件数。
  • 業界トップクラスの高単価報酬、低マージン(平均年収862万円)。
  • 案件参画中のフォローの充実。

※詳細は「【業界最大手】レバテックフリーランスとは?メリットや利用手順を解説!」を参照。

は業界最大手のフリーランスエージェントです。

とにかく案件数が多いので、とりあえず登録しておけば間違いないエージェントです!

いずみ

僕もはじめてフリーランスの案件を貰ったのはです。

保有している案件数が多いので、業務経験がなくても何かしらの案件は紹介してもらえますよ(僕はJavaの経験3年でも案件を貰えました)。

手厚い保障を重視したいなら「

案件数マージン率単価
約10,000件非公開
初心者福利厚生申し込み
無料
Good Point
  • 手厚い保障で正社員並みの安心感。
  • 還元率60%超え&単価公開でクリアな契約。
  • 給与保障制度(審査あり)。

は手厚い保障が特徴のフリーランスエージェントです。

フリーランスを目指しているけど不安な方や保障を重視したい方におすすめです。

いずみ

僕も何度か案件を紹介してもらいました。

自分のスキルに合った案件を紹介してもらえましたし、電話のやり取りも非常に丁寧でした。

週2〜3日の案件探しなら「

案件数マージン率単価
約5,000件非公開
初心者福利厚生申し込み
経験者向け無料
Good Point
  • 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に固定する方法について解説しました。

以下が本記事のまとめになります。

まとめ
  • Structured OutputsはClaudeの出力を指定したJSONスキーマに強制的に一致させる機能。
  • messages.createのoutput_configにjson_schemaを渡すと、json.loads()でそのまま扱えるJSONが返る。
  • Pythonではmessages.parseとPydanticモデルで型付きオブジェクトとして受け取れる。
  • ツール定義にstrictを付けると、ツール引数もスキーマ通りに固定できる。
  • 数値や文字列長の制約など一部のJSON Schema機能は非対応なので、受け取り後のバリデーションで補う。
まとめ
いずみ

最後までお読みいただき、ありがとうございました!

スクロールできます
【当サイト】おすすめフリーランスエージェント3選
エージェント評価ポイント公式サイト
レバテックフリーランス

5.0
業界最大級のエージェント。
高単価案件が豊富。
公式
Midworks

4.8
満足度調査で
3年連続3冠を達成。
公式
ITプロパートナーズ

4.6
週2〜3向けの案件が豊富。公式
  • クソおすすめ本
¥4,480 (2024/06/01 23:28時点 | Amazon調べ)
\楽天ポイント4倍セール!/
楽天市場
いずみ

海外のエンジニアがどういった思考で働いているかが理解できます。

海外に行く気はないけど海外エンジニアの動向が気になる雑魚エンジニアにおすすめです(本当におすすめな本しか紹介しないのでご安心を)。

この記事が気に入ったら
フォローしてね!

シェアしてね!
  • URLをコピーしました!
目次