Techsy
お問い合わせ
始める
ブログ一覧へ戻る
ai-machine-learning

あらゆるLLMから信頼性の高いJSONを取得:2026年版 Pydantic + Zod パターン

著者: Mert Batur Gürbüz
更新日 May 12, 2026
3 分
目次
あらゆるLLMから信頼性の高いJSONを取得:2026年版 Pydantic + Zod パターン

**LLM構造化出力(Structured Output)**は、言語モデルの応答が事前定義されたスキーマに準拠することを保証する仕組みです。単に有効なJSONであるだけでなく、指定した正確なフィールド、型、制約を持つスキーマ準拠のJSONであることを意味します。主要なプロバイダーはすべてこれをネイティブでサポートしており、本番環境向けのLLMアプリケーションの構築方法を一変させました。

クイックサマリー:構造化出力の概要

時間がない方のために、2026年の現状をまとめます。

側面詳細
何なのかLLMからのスキーマ強制応答。「ベストエフォート」ではなく、構造が保証される
サポートしているプロバイダーOpenAI、Anthropic、Gemini、Cohere、xAI (Grok)、さらにOllama/vLLM経由のローカル実行
主要な仕組み制約付きデコーディング。サンプリング前に不正なトークンをマスクする
JSON Mode vs Strict ModeJSON Mode = 構文的に有効なJSONのみ。Strict Mode = スキーマ完全準拠
Pythonライブラリスキーマ定義には Pydantic (BaseModel + Field)
TypeScriptライブラリスキーマ定義には Zod (z.object + .describe)
最適な入門アプローチネイティブSDK経由で Pydantic または Zod を使用する OpenAI
最適な本番用ライブラリInstructor (Python) または ネイティブSDK (TypeScript)
最大の落とし穴回答フィールドの後に推論フィールドを配置すること。モデルが思考前に決定を下してしまう
レイテンシオーバーヘッド初回呼び出しで50-200ms(スキーマコンパイル)、以降はキャッシュされる

では、各要素を詳しく見ていきましょう。

LLM構造化出力とは?

構造化出力は、LLMが有効なJSONを返すことを願うことと、それを保証することの違いです。構造化出力を有効にすると、モデルは物理的にスキーマに違反するトークンを生成できなくなります。JSON Schema(またはPydanticモデル、Zodスキーマ)を定義し、APIに渡すと、毎回それに一致する応答が返ってきます。

なぜこれが重要なのでしょうか?構造化出力以前、開発者は脆弱な正規表現パーサーを書き、すべてのLLM呼び出しを try/catch JSON.parse ブロックで囲み、それでも「ほぼ正解」の応答(有効なJSONだがフィールドが欠けていたり型が間違っていたりするもの)に対処していました。そのようなバグのクラスは完全に消滅しました。

構造強制には3つのレベルがあり、明確な進化を表しています。

  1. プロンプトエンジニアリング、「これらのフィールドを含むJSONを返してください」。信頼性は低く、モデルは80〜90%の確率でしか従いません。
  2. JSON Mode、構文的に有効なJSONであることを保証しますが、スキーマは強制しません。{"name": string, "age": number} を期待しているときに {"foo": "bar"} が返ってくる可能性があります。
  3. Strict Mode / 制約付きデコーディング、100%のスキーマ準拠を保証します。モデルは文字通り不正なトークンを出力できません。これが2026年における「構造化出力」の意味です。

2026年初頭現在、OpenAI、Anthropic、および Google Gemini はすべてネイティブな構造化出力をサポートしています。エコシステムは収束しました。

結論:本番環境で正規表現や JSON.parse を使ってLLM応答を解析しているなら、難しいやり方をしています。 ネイティブな構造化出力はその失敗モード全体を排除します。

JSON Mode vs Strict Mode:実際は何が変わったのか?

名前が似ているため、多くの開発者がこの区別で混乱します。しかし、これらは別物です。

機能JSON ModeStrict Mode (構造化出力)
APIパラメータtype: "json_object"strict: true を伴う type: "json_schema"
有効なJSONを保証はいはい
スキーマ準拠を保証いいえはい
仕組み事後のトークンバイアス制約付きデコーディング (FSM)
予期しないフィールドを返す可能性ありなし
必須フィールドを省略する可能性ありなし
型強制なし完全 (string, number, array など)
使用すべき場面事前にスキーマを持っていない場合本番環境でのすべて

タイムライン: OpenAIは2023年後半にJSON Modeを導入しました。これは前進でしたが、開発者はすぐに「有効なJSON」だけでは不十分であり、スキーマ準拠のJSONが必要だと気づきました。2024年8月、OpenAIはStrict Modeを搭載した構造化出力をリリースし、制約付きデコーディングを使用してスキーマ準拠を保証しました。2025年から2026年にかけて、主要なプロバイダーはすべて同じアプローチを採用しました。

JSON Modeには依然として狭いユースケースがあります。応答の形状を事前に全く知らず、非構造的な探索のために何らかの有効なJSONが欲しい場合です。しかし、本番環境では稀です。

結論:本番環境でのすべてにStrict Modeを使用してください。 スキーマ縛りのユースケースにおいて、JSON Modeは事実上廃止されています。スキーマがある場合(そしてあるべきです)、strict: true で type: "json_schema" を使用してください。

制約付きデコーディングは実際にどのように機能するのか?

99.9%ではなく、文字通り100%のスキーマ準拠を可能にする仕組み here です。

Strict Modeを有効にしてプロバイダーにJSON Schemaを送信すると、そのスキーマは**有限状態機械(FSM)**にコンパイルされます。このFSMは、スキーマを通るすべての有効なパスを表します。各トークン生成ステップで、推論エンジンはどのトークンが出力を有効なパス上に留め、どれが留めないかをチェックします。不正なトークンのロジットはサンプリング前に負の無限大に設定されるため、選択される確率はゼロになります。

<!-- IMAGE: constrained-decoding diagram showing FSM token masking during structured output generation -->

これは強化版のオートコンプリートのようなものだと考えてください。モデルが {"rating": を出力し、スキーマで rating が整数であると指定されている場合、次に許可されるトークンは数字トークンだけです。引用符、文字、括弧などはすべてマスクされます。モデルが「そうしたい」と思っても、"five" を出力することはできません。

これは、XGrammar(vLLM、SGLang、およびほとんどのローカル推論サーバーの背後にあるエンジン)や Outlines(制約付き生成用のオープンソースPythonライブラリ)で使用されているのと同じコアメカニズムです。APIプロバイダーはこれを推論インフラストラクチャに組み込んだだけです。

知っておくべきトレードオフが1つあります。新しいスキーマでの最初のリクエストでは、FSMが構築される間にコンパレーションレイテンシの影響(通常50-200ms)を受けます。同じスキーマでの subsequent リクエストはキャッシュされたFSMを使用し、オーバーヘッドはほぼゼロです。また、微妙な品質に関する考慮事項もあります。トークン語彙を制限すると、創造的または自由形式のフィールドで出力品質が低下することがあるため、スキーマは真に構造化されたデータに焦点を当ててください。

結論:制約付きデコーディングこそが、「通常は機能する」と「常に機能する」を分けるものです。 これが構造化出力を生産準備完了にするエンジニアリングです。

マルチプロバイダー実装:OpenAI、Anthropic、Gemini

他のガイドでは示されていないことがあります。3つの主要プロバイダーすべてで実装された同じ抽出タスクです。非構造化テキストから構造化された製品レビューを抽出します。

すべてのプロバイダーで共有されるPydanticスキーマ:

python
from pydantic import BaseModel, Field
from typing import Literal

class ProductReview(BaseModel):
    reasoning: str = Field(description="Think through the review before scoring")
    rating: int = Field(description="Rating from 1-5", ge=1, le=5)
    sentiment: Literal["positive", "negative", "neutral"]
    pros: list[str] = Field(description="Key positive points")
    cons: list[str] = Field(description="Key negative points")
    summary: str = Field(description="One-sentence summary")

OpenAIの実装

python
from openai import OpenAI

client = OpenAI()

response = client.beta.chat.completions.parse(
    model="gpt-4o-2024-08-06",
    messages=[
        {"role": "system", "content": "Extract a structured review from the text."},
        {"role": "user", "content": review_text}
    ],
    response_format=ProductReview,  # Pydantic model directly
)

review = response.choices[0].message.parsed  # Typed ProductReview object

OpenAIの実装は最も成熟しています。parse() メソッドはPydanticモデルを直接受け取り、型付けされたオブジェクトを返します。1つの制約:OpenAIの Strict ModeはJSON Schemaのサブセットをサポートしています。$ref はなく、anyOf は制限されており、すべてのフィールドは additionalProperties: false で必須である必要があります。

Anthropicの実装

python
from anthropic import Anthropic

client = Anthropic()

response = client.messages.create(
    model="claude-sonnet-4-5-20250514",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": f"Extract a structured review:\n\n{review_text}"}
    ],
    output_config={
        "format": {
            "type": "json_schema",
            "json_schema": ProductReview.model_json_schema()
        }
    }
)

import json
review_data = json.loads(response.content[0].text)
review = ProductReview(**review_data)

Anthropicのネイティブ構造化出力は、JSON Schemaとともに output_config.format を使用します。これは2026年初頭にGA(一般提供)になりました。Anthropicはまた、「フェイク」ツールを定義し tool_use 経由で抽出する古いパターンもサポートしていますが、純粋な抽出にはネイティブ構造化出力の方がクリーンです。

Geminiの実装

python
from google import genai

client = genai.Client()

response = client.models.generate_content(
    model="gemini-2.0-flash",
    contents=f"Extract a structured review:\n\n{review_text}",
    config={
        "response_mime_type": "application/json",
        "response_schema": ProductReview,  # Pydantic model directly
    }
)

import json
review = ProductReview(**json.loads(response.text))

GeminiはPython SDKで response_schema 経由でPydanticモデルを直接サポートしています。独自の機能:Geminiはスキーマ内の propertyOrdering を尊重するため、フィールドの出力順序を制御できます(推論優先パターンに有用)。

プロバイダー比較

機能OpenAIAnthropicGemini
APIパラメータresponse_formatoutput_config.formatresponse_schema
スキーマ入力Pydantic または JSON SchemaJSON SchemaPydantic または JSON Schema
Strict modestrict: truejson_schema で暗黙的暗黙的
ストリーミングはい(部分的なJSON)はいはい
拒否処理message.refusal フィールドエラーレスポンスエラーレスポンス
ツール使用の代替はいはい(元の手法)はい
スキーマコンパイルキャッシュはい(サーバーサイド)はいはい
プロパティ順序付けネイティブサポートなしなしはい (propertyOrdering)

結論:OpenAIは parse() メソッドにより最も洗練されたDXを提供します。Anthropicは最も有能な基盤モデルを提供します。Geminiのプロパティ順序付けは uniquely 有用です。 3つとも仕事はこなしますので、既存のプロバイダーとの関係に基づいて選択してください。

Python開発者向けPydanticパターン

Pydantic は、Pythonで構造化出力スキーマを定義するための事実上の標準です。重要なパターンは以下の通りです。

説明付きの基本スキーマ

python
from pydantic import BaseModel, Field
from typing import Literal, Optional

class ExtractedEntity(BaseModel):
    reasoning: str = Field(description="Think step by step about the entity")
    name: str = Field(description="Full name of the entity")
    entity_type: Literal["person", "company", "location"]
    confidence: float = Field(description="Confidence score 0.0-1.0", ge=0.0, le=1.0)
    context: Optional[str] = Field(description="Surrounding context, if relevant")

これらの description 文字列は単なるドキュメントではありません。これらはモデルに送信されるJSON Schemaの一部となり、モデルが生成する内容に直接影響を与えます。これらをスキーマ 内 の プロンプトエンジニアリング と考えてください。

ネストされたモデル

python
class Address(BaseModel):
    street: str
    city: str
    country: str
    postal_code: Optional[str] = None

class Company(BaseModel):
    reasoning: str = Field(description="Analysis of the company details")
    name: str
    industry: Literal["tech", "finance", "healthcare", "retail", "other"]
    headquarters: Address  # Nested model
    key_products: list[str] = Field(description="Top 3 products or services")

ネストは最大2〜3レベルに抑えてください。深くネストされたスキーマはエラー率を増加させ、スキーマコンパイルを遅くします。

推論優先パターン

これは最も影響力のあるスキーマ設計パターンです。回答フィールドの 前 に reasoning フィールドを配置します。

python
# Reliable JSON from Any LLM: Pydantic + Zod Patterns for 2026
class ClassificationBad(BaseModel):
    category: Literal["spam", "ham"]
    confidence: float

# Good -- model reasons through the problem first
class ClassificationGood(BaseModel):
    reasoning: str = Field(description="Analyze the text before classifying")
    category: Literal["spam", "ham"]
    confidence: float = Field(ge=0.0, le=1.0)

LLMはトークンを左から右へ生成します。category が最初に来ると、モデルはカテゴリを選び、その後でそれを合理化します。reasoning が最初に来ると、モデルは問題を解決し、その後 でカテゴリを確定します。これはスキーマに組み込まれたChain-of-Thoughtです。

JSON Schemaエクスポート

python
# Generate the JSON Schema for any Pydantic model
schema = ProductReview.model_json_schema()
# Pass this to any provider that accepts raw JSON Schema

結論:Pydantic + 記述的なフィールド + 推論優先の順序付けは、Python構造化出力の三拍子です。 これら3つのパターンをマスターすれば、90%のユースケースに対応できます。

TypeScript開発者向けZodパターン

Zod はTypeScript版のPydanticであり、構造化出力ワークフローにおいて同样に中心的な存在です。

説明付きの基本スキーマ

typescript
import { z } from "zod";

const ProductReview = z.object({
  reasoning: z.string().describe("Think through the review before scoring"),
  rating: z.number().int().min(1).max(5),
  sentiment: z.enum(["positive", "negative", "neutral"]),
  pros: z.array(z.string()).describe("Key positive points"),
  cons: z.array(z.string()).describe("Key negative points"),
  summary: z.string().describe("One-sentence summary"),
});

// Infer the TypeScript type automatically
type ProductReview = z.infer<typeof ProductReview>;

Pydanticの Field(description=...) と同様に、Zodの .describe() はJSON Schemaの一部となり、モデルの出力を導きます。

OpenAI Node SDKとの統合

typescript
import OpenAI from "openai";
import { zodResponseFormat } from "openai/helpers/zod";

const client = new OpenAI();

const response = await client.beta.chat.completions.parse({
  model: "gpt-4o-2024-08-06",
  messages: [
    { role: "system", content: "Extract a structured review." },
    { role: "user", content: reviewText },
  ],
  response_format: zodResponseFormat(ProductReview, "product_review"),
});

const review = response.choices[0].message.parsed; // Typed!

Vercel AI SDKとの統合

typescript
import { generateObject } from "ai";
import { openai } from "@ai-sdk/openai";

const { object: review } = await generateObject({
  model: openai("gpt-4o"),
  schema: ProductReview,
  prompt: `Extract a structured review:\n\n${reviewText}`,
});
// review is fully typed as ProductReview

Vercel AI SDK は generateObject() でZodをネイティブに使用し、最もクリーンなTypeScript統合を実現しています。統一されたAPIを通じて、OpenAI、Anthropic、Gemini、および他のプロバイダーで動作します。

JSON Schema変換

typescript
import { zodToJsonSchema } from "zod-to-json-schema";

const jsonSchema = zodToJsonSchema(ProductReview);
// Use with any provider that accepts raw JSON Schema

結論:Zod + .describe() + Vercel AI SDKは、TypeScript構造化出力スタックです。 Node/Next.jsエコシステムにいる場合、これが最小抵抗の経路です。

構造化出力 vs 関数呼び出し:いつどちらを使うか?

これは最も一般的な混乱の原因の一つです。どちらもスキーマ涉及し、構造化データを返しますが、異なる問題を解決します。

構造化出力は言います:「この正確な形状でデータを私にください。」これは抽出、分類、フォーマット用です。非構造化テキストから構造化情報を引き出しています。

**関数呼び出し(ツール使用)**は言います:「ここに取れるアクションがあります。どれを実行するか決定し、引数を提供してください。」これは、モデルが複数のツールから選び、アクションをトリガーするエージェントワークフロー用です。

歴史的に混乱するのは理解できます。Anthropicの元の「構造化出力」は文字通り関数呼び出しでした。extract_review というフェイクツールを定義し、引数を取得していました。それはまだ機能しますが、純粋な抽出にはネイティブ構造化出力の方がシンプルです。

シナリオベストアプローチ理由
テキストからデータを抽出構造化出力直接的、低レイテンシ、単一スキーマ
カテゴリに分類構造化出力1回の応答、1つのスキーマ
どのツールを呼び出すか決定するエージェント関数呼び出しモデルが複数のツールから選択
マルチステップオーケストレーション関数呼び出し順次ツール呼び出し
データ抽出 AND 次のアクション決定両方抽出には構造化出力、オーケストレーションには関数呼び出し

構造化出力は、AIエージェントシステム内のツール呼び出しパイプラインを動力源としています。これらが本番ワークフローにどのように適合するかについては、ビジネス向けAIエージェントガイドをご覧ください。

結論:データの形状がわかっている場合は構造化出力を使用してください。モデルがアクションを選択する必要がある場合は関数呼び出しを使用してください。 実際には、ほとんどのアプリケーションで両方を使用します。データ抽出には構造化出力、エージェントオーケストレーションには関数呼び出しです。

本番パターン:エラー、リトライ、ストリーミング

デモで構造化出力を動作させるのは簡単です。本番環境で信頼性を維持するには、拒否、検証失敗、ストリーミングの3つを処理する必要があります。

拒否処理

場合によっては、モデルが要求された出力の生成を拒否することがあります。通常、安全性フィルターが入力をフラグ立てたためです。この場合、構造化出力APIはスキーマを返しません。拒否を返します。

python
response = client.beta.chat.completions.parse(
    model="gpt-4o-2024-08-06",
    messages=messages,
    response_format=ProductReview,
)

# ALWAYS check for refusal before accessing parsed content
if response.choices[0].message.refusal:
    print(f"Model refused: {response.choices[0].message.refusal}")
else:
    review = response.choices[0].message.parsed

拒否チェックをスキップして拒否に対して .parsed にアクセスしようとすると、None が返され、下流で混乱するエラーが発生します。必ず最初にチェックしてください。

検証フィードバック付きリトライパターン

スキーマ準拠は制約付きデコーディングによって保証されますが、意味的 正しさは保証されません。モデルは {"rating": 1, "sentiment": "positive"} を返すかもしれません。有効なスキーマですが、矛盾した内容です。そこで検証+リトライが登場します。

python
import instructor

client = instructor.from_openai(OpenAI())

# Instructor handles retries automatically
review = client.chat.completions.create(
    model="gpt-4o",
    response_model=ProductReview,
    max_retries=3,  # Retries with validation error feedback
    messages=[
        {"role": "user", "content": review_text}
    ],
)

Instructor はリトライ時に検証エラーをモデルにフィードバックするため、自己修正が可能です。Instructorを使わない手動リトライパターンの場合:

python
from pydantic import ValidationError

for attempt in range(3):
    try:
        response = client.beta.chat.completions.parse(
            model="gpt-4o-2024-08-06",
            messages=messages,
            response_format=ProductReview,
        )
        review = response.choices[0].message.parsed
        # Run additional semantic validation here
        break
    except ValidationError as e:
        messages.append({"role": "assistant", "content": str(response)})
        messages.append({"role": "user", "content": f"Validation error: {e}. Fix it."})

構造化出力のストリーミング

大規模な構造化応答、長い配列、多数のフィールド、複雑なネストされたオブジェクトの場合、ストリーミングにより部分的な結果を段階的にレンダリングできます。

python
import instructor

client = instructor.from_openai(OpenAI())

# Stream partial results as fields populate
review_stream = client.chat.completions.create_partial(
    model="gpt-4o",
    response_model=ProductReview,
    messages=[{"role": "user", "content": review_text}],
)

for partial_review in review_stream:
    # Fields populate one by one as tokens stream in
    if partial_review.summary:
        print(f"Summary so far: {partial_review.summary}")

1つの落とし穴:個々のストリーミングチャンク自体はスキーマ準拠ではありません。rating がまだ None の間に reasoning フィールドが入力されている可能性があります。 accordingly UIを計画し、未入力フィールドにはローディング状態を表示してください。

結論:拒否チェックは必須です。検証フィードバック付きリトライは意味的エラーを検出します。数秒以上かかる応答にはストリーミングの価値があります。

構造化出力ライブラリの比較

ネイティブAPIを通じて構造化出力を使用できますが、ライブラリは検証、リトライ、ストリーミング、マルチプロバイダーサポートを追加します。現状は以下の通りです。

Instructor は11K以上のGitHubスターと月間300万を超えるダウンロード数を誇る最も人気のあるオプションです。OpenAI、Anthropic、Gemini、Cohere、Ollamaなどを統一されたPydanticベースのインターフェースでラップします。主要な機能:検証フィードバック付き自動リトライ、create_partial() によるストリーミング、そして極めてシンプルなセットアップ(instructor.from_openai(client))。Pythonチームならここから始めてください。

BAML は異なるアプローチを取ります。カスタムDSLによるスキーマファーストです。.baml ファイルでスキーマを定義し、Python、TypeScript、Rubyなどのクライアントを自動生成します。そのSAP(スキーマ整合パーシング)アルゴリズムは、 messy なモデル出力を gracefully に処理します。クロスランゲージチームや、LLM層とアプリケーション層の間の契約が必要な場合に最適です。トレードオフ:追加のビルドステップと新しい構文の学習が必要です。

LangChain は、プロバイダーに依存しない構造化出力のために .with_structured_output(schema) を提供します。すでにLangChainエコシステムにいる場合は便利です。トレードオフ:重い依存関係であり、抽象化が必要なプロバイダー固有の機能を隠してしまう可能性があります。

ネイティブAPI、response_format / output_config を直接使用する呼び出しは、プロバイダーSDK以外の依存関係を必要としません。完全な制御と可視性が得られます。シンプルなユースケースや、最小限の抽象化を好むチームに最適です。

ライブラリ言語プロバイダー自動リトライストリーミングGitHubスター学習曲線
InstructorPython, TS15+はいはい11K+低
BAMLPython, TS, Ruby, Goすべて (DSL非依存)はいはい7K+中
LangChainPython, TS20+部分的はい100K+中〜高
ネイティブAPI任意SDKごと1つなしはいN/A低

適切な構造化出力ライブラリの選択は、より広範なAIスタック決定の一部です。フルスタックの詳細は SaaS向け最佳AIスタックガイド で解説しています。

Instructor、BAML、Mirascopeなどの詳細な比較については、近日公開予定の LLM構造化出力向け最佳ライブラリ をご覧ください。

結論:PythonではInstructorから始め、TypeScriptではネイティブAPIを使用してください。 クロスランゲージスキーマ契約が必要な場合はBAMLに移行してください。構造化出力のためだけにLangChainを使用するのは避けましょう。過剰仕様です。

スキーマ設計のベストプラクティス(および一般的な間違い)

スキーマ設計は出力品質に直接影響します。重要なパターンと、精度を損なう間違いは以下の通りです。

回答の前に推論を配置する

Pydanticのセクションで触れましたが、これが最も影響の大きい設計決定であるため繰り返します。

python
# Before: model guesses the answer, then rationalizes
class Bad(BaseModel):
    answer: str
    reasoning: str

# After: model thinks first, then commits
class Good(BaseModel):
    reasoning: str = Field(description="Think step by step")
    answer: str

LLMは左から右へ生成します。フィールド順序はプロンプト順序です。推論を最初に配置することで、モデルは回答を確定する前に問題を解決しなければなりません。

アンチパターン表

間違い問題修正
回答フィールドの後の推論フィールド思考前にモデルが決定推論を回答の前に移動
深いネスト(4レベル以上)エラー率上昇、コンパイル遅延2〜3レベルに平坦化
フィールド説明なしモデルが意図を推測.describe() / Field(description=...) を追加
null処理の欠如モデルがフィールドを埋めるために値を幻覚Optional / .nullable() を使用
過度に大きなスキーマ(50+フィールド)コンパイルタイムアウト、品質低下複数の呼び出しに分割
曖昧なenumオプションモデルが間違ったカテゴリを選択具体的で重複しないオプションを使用

nullを明示的に処理する

ソーステキストにデータがない可能性があるフィールドは、オプションにしてください。データが存在しない場合に必須フィールドを強制すると、幻覚につながります。

python
class PersonInfo(BaseModel):
    name: str  # Always present
    email: Optional[str] = Field(None, description="Email if mentioned, null otherwise")
    phone: Optional[str] = Field(None, description="Phone if mentioned, null otherwise")

スキーマを集中させる

1タスクにつき1スキーマ。単一の巨大なスキーマですべてを抽出しようとしないでください。50以上のフィールドが必要な場合は、複数の抽出呼び出しに分割してください。OpenAIのStrict Modeにはスキーマの複雑さに対する実用的な限界があり、機能した場合でも、非常に大きなスキーマは出力品質を低下させます。

結論:推論優先、記述的なフィールド、明示的なnull、集中したスキーマ。 この4つを正しく行えば、構造化出力の精度は測定可能なほど向上します。

ローカルLLMでの構造化出力

構造化出力のためにAPIプロバイダーは必要ありません。ローカル推論エンジンは、独自のハードウェア上で実行される同じ根本的なメカニズムである、文法ベースの制約付きデコーディングを通じてこれをサポートします。

Ollama

ローカル構造化出力への最も簡単な道。Ollama は format パラメータ経由でJSON Schemaを受け入れます。

python
import ollama
from pydantic import BaseModel

class Country(BaseModel):
    name: str
    capital: str
    languages: list[str]

response = ollama.chat(
    model="llama3.2",
    messages=[{"role": "user", "content": "Tell me about Japan."}],
    format=Country.model_json_schema(),
)

import json
country = Country(**json.loads(response.message.content))

Ollamaは内部で制約付きデコーディングのために XGrammar を使用しています。APIプロバイダーと同じ保証:100%のスキーマ準拠。

vLLM と SGLang

本番グレードのローカル推論の場合、vLLM と SGLang はどちらも guided_json および guided_regex パラメータを通じて構造化出力をサポートしています。XGrammarはデフォルトのバックエンドであり、JSON生成におけるオーバーヘッドはほぼゼロで、代替の文法エンジンよりも最大3.5倍高速です。

Outlines

Outlines は、文法ベースの制約付き生成を開拓したオープンソースPythonライブラリです。任意のHugging Faceモデルで動作し、JSON Schema、正規表現、および完全な文脈自由文法(CFG/EBNF)制約をサポートします。また、文法バックエンドオプションとしてvLLMおよびSGLangにも統合されています。

APIプロバイダーとの主な違い:ローカル構造化出力には スキーマサブセットの制限がありません 。文法を完全に制御できます。ただし、モデル品質はより変動し、7Bパラメータのローカルモデルは複雑な抽出タスクでGPT-4oやClaudeに匹敵しません。スキーマは常に有効ですが、コンテンツ の品質はモデルに依存します。

結論:開発にはOllama、本番にはXGrammar搭載のvLLM/SGLang。 ローカル構造化出力はほとんどのユースケースに対応できるほど成熟していますが、小さいモデルはスキーマ内で低品質のコンテンツを生成するという注意点があります。

FAQ

LLMにおける構造化出力とは何ですか?

構造化出力は、LLMの応答が事前定義されたJSON Schemaに準拠することを保証するメカニズムです。プレーンテキストやJSON Modeとは異なり、構造化出力は制約付きデコーディングを使用して、スキーマ内のすべてのフィールド、型、制約が満たされることを保証します。「通常」ではなく、100%の時間です。

JSON Modeと構造化出力の違いは何ですか?

JSON Modeは構文的に有効なJSONを保証しますが、スキーマは強制しません。任意の有効なJSONオブジェクトが返される可能性があります。構造化出力(Strict Mode)は、制約付きデコーディングを通じて完全なスキーマ準拠を保証します。本番環境にはStrict Modeを使用してください。JSON Modeは、事前にスキーマを持っていない場合のみ関連します。

どのLLMプロバイダーがネイティブで構造化出力をサポートしていますか?

OpenAI(2024年8月以降)、Google Gemini(2024年、2026年に拡張)、Anthropic(2025年11月ベータ、2026年初頭GA)、Cohere、およびxAI(Grok)はすべてネイティブな構造化出力をサポートしています。ローカル側では、Ollama、vLLM、およびSGLangが文法ベースの制約付きデコーディングを通じてこれをサポートしています。

制約付きデコーディングはどのようにスキーマ準拠を保証しますか?

JSON Schemaは有限状態機械(FSM)にコンパイルされます。各トークン生成ステップで、FSMを通る有効なパス上に出力を留めるトークンだけが許可され、不正なトークンのロジットは負の無限大に設定されます。这意味着不正なトークンが生成される確率はゼロであり、統計的な保証ではなく数学的な保証が得られます。

構造化出力と関数呼び出しのどちらを使用すべきですか?

特定の形状のデータを望む場合、抽出と分類には構造化出力を使用してください。モデルが取るアクションを決定する必要がある場合、エージェントワークフローには関数呼び出しを使用してください。多くの本番アプリケーションでは両方を使用します。データ抽出には構造化出力、オーケストレーションには関数呼び出しです。

構造化出力をストリーミングできますか?

はい。OpenAIは parse() メソッドでストリーミングをサポートし、Instructorはフィールドごとに populate されるPydanticモデルのストリーミングのために create_partial() を提供します。個々のストリーミングチャンクは個別にはスキーマ準拠ではないことに注意してください。フィールドは漸進的に入力されます。

Instructorライブラリとは何ですか?

Instructorは最も人気のある構造化出力ライブラリです(11K以上のGitHubスター、月間300万を超えるダウンロード数)。プロバイダーSDKをPydanticベースの検証、検証フィードバック付き自動リトライ、およびストリーミングサポートでラップします。OpenAI、Anthropic、Gemini、Cohere、Ollama、および10以上の他のプロバイダーで動作します。

構造化出力はローカルLLMで動作しますか?

はい。OllamaはJSON Schema付きの format パラメータ経由で構造化出力をサポートしています。vLLMとSGLangは guided_json パラメータを通じてこれをサポートしています。3つすべてが制約付きデコーディングのためにXGrammarまたはOutlinesを使用しています。スキーマ準拠の保証はAPIプロバイダーと同じです。コンテンツ品質はモデルに依存します。

一般的なスキーマ設計の間違いは何ですか?

主な間違い:回答フィールドの後に推論フィールドを配置すること(モデルが思考前に決定)、深くネストされたスキーマ(4レベル以上はエラーを増加)、フィールド説明の欠如(モデルが意図を推測)、オプションデータのnull処理なし(幻覚を強制)、過度に大きなスキーマ(50以上のフィールドは品質を低下)。

構造化出力はレイテンシを追加しますか?

最初のリクエストにはスキーマコンパイルのオーバーヘッドがあり、通常FSMが構築される間に50-200msかかります。同じスキーマでの subsequent リクエストはキャッシュされたFSMを使用し、レイテンシはほぼゼロです。ほとんどのアプリケーションにとって、これは全体のモデル推論時間と比較して無視できます。

構造化出力を画像やマルチモーダル入力で使用できますか?

はい。構造化出力は 応答 形式に適用され、入力には適用されません。構造化出力スキーマ付きでGPT-4oやGeminiに画像を送信し、画像のスキーマ準拠分析を受け取ることができます。これは領収書、フォーム、または製品画像から構造化データを抽出する視覚的抽出ワークフローに強力です。

ソース

  • OpenAI構造化出力ガイド
  • Anthropicツール使用ドキュメント
  • Google Gemini構造化出力
  • Instructorライブラリドキュメント
  • BAMLドキュメント
  • Pydanticドキュメント
  • Zodドキュメント
  • Outlinesライブラリ
  • XGrammar GitHub
  • Ollama構造化出力
  • Vercel AI SDK

タグ

llm structured outputstructured outputsjson schemapydanticzodopenaianthropicgemini

記事をシェアする

関連記事

その他の記事 ai-machine-learning

ai-machine-learning
Jul 24, 2026

Claude Opus 5が登場:Fable 5に迫る知能を半額で

Anthropicは2026年7月24日にClaude Opus 5をリリース。Frontier-BenchでOpus 4.8を2倍以上上回り、Opus価格を維持するが、Fable 5とMythos 5にいくつかのテストで敗れる。ベンチマーク表、価格、切り替え/待機/据え置きの判断を解説。

10 min read 分
読む
ai-machine-learning
Jul 20, 2026

2026年ベストAIウェブスクレイピングAPI 8選(自社エージェントスタックで実測)

自社エージェントスタックで取得した2026年の実価格をもとに、8つのAIウェブスクレイピングAPIをテスト。Firecrawl、Bright Data、ScrapingBeeほか5社を、LLM対応出力・アンチボット突破・MCPサポートの観点でランキング。

9 min read 分
読む
ai-machine-learning
Jul 20, 2026

コーディングのためのプロンプトエンジニアリング:Claude CodeとCursorで毎日使う7つのパターン(2026年版)

多くの「AIコーディングプロンプト」記事はコピー用のテンプレートを50個並べるだけですが、この記事では私たちが16エージェントのClaude Codeパイプラインを運用するために毎日使っている7つのパターンを紹介します。各パターンの具体的な改善前後の例に加え、2026年時点でのClaude Code、Cursor、Copilotにおける各パターンの適用方法も解説します。

11 min read 分
読む
すべての記事を表示
プロジェクトを始めよう

さあ、何かを作ろう。 特別なものへ?

ビジョンを、かたちに。変化を生むソフトウェアづくりは、私たちのチームにお任せください。

30分のスコーピング通話を予約する実績を見る

注目のツール

Claude Skills

すべて表示
  • New Post

    Full SEO blog pipeline: research, brief, write, validate, image, translate, publish to Sanity. Autonomous from start to finish.

  • Content Refresh

    Audit a stale post, find decay drivers, and ship a SERP-aligned refresh without losing existing rankings.

  • SEO Audit

    Site-wide SEO audit with prioritized fix list: technical, on-page, and EEAT signals.

AI自動化

すべて表示
  • Security Auditor

    Weekly SCA + IaC scan with prioritized fix PRs.

  • Cold Email Writer

    Generates first-touch emails grounded in one specific public detail.

  • Lead Research Agent

    Enrich an email into a profile, score fit, alert in Slack.

注目のツール

Claude Skills

すべて表示
  • New Post

    Full SEO blog pipeline: research, brief, write, validate, image, translate, publish to Sanity. Autonomous from start to finish.

  • Content Refresh

    Audit a stale post, find decay drivers, and ship a SERP-aligned refresh without losing existing rankings.

  • SEO Audit

    Site-wide SEO audit with prioritized fix list: technical, on-page, and EEAT signals.

AI自動化

すべて表示
  • Security Auditor

    Weekly SCA + IaC scan with prioritized fix PRs.

  • Cold Email Writer

    Generates first-touch emails grounded in one specific public detail.

  • Lead Research Agent

    Enrich an email into a profile, score fit, alert in Slack.

サービス

  • エンタープライズソリューション
  • モバイルアプリ
  • Webアプリケーション

ソリューション

  • CRMシステム
  • AI統合
  • ERPソリューション
  • 音声エージェント
  • プロセス自動化
  • サイバーセキュリティ

ライブラリ

  • ブログ
  • ポートフォリオ

コミュニティ

  • AI自動化
  • Claude Skills

ツール

  • モバイルアプリ開発費用計算ツール
  • OpenAI / LLM API 利用料金計算ツール
  • MVP(Minimum Viable Product)開発費用計算ツール
  • 音声AIエージェント構築費用計算ツール

会社情報

  • 概要
  • パートナー
  • お問い合わせ

法的情報

  • プライバシーポリシー
  • 利用規約
  • クッキーポリシー

サービス

  • エンタープライズソリューション
  • モバイルアプリ
  • Webアプリケーション

ソリューション

  • CRMシステム
  • AI統合
  • ERPソリューション
  • 音声エージェント
  • プロセス自動化
  • サイバーセキュリティ

ライブラリ

  • ブログ
  • ポートフォリオ

コミュニティ

  • AI自動化
  • Claude Skills

ツール

  • モバイルアプリ開発費用計算ツール
  • OpenAI / LLM API 利用料金計算ツール
  • MVP(Minimum Viable Product)開発費用計算ツール
  • 音声AIエージェント構築費用計算ツール

会社情報

  • 概要
  • パートナー
  • お問い合わせ
法的情報プライバシーポリシー利用規約クッキーポリシー
TECHSY
© 2026 Techsy. 無断複写・転載を禁じます