📦 LLM Structured Output
AI(人工知能)から、JSON
📺 まず動画で見る(YouTube)
▶ 【Claude Code完全入門】誰でも使える/Skills活用法/経営者こそ使うべき ↗
※ jpskill.com 編集部が参考用に選んだ動画です。動画の内容と Skill の挙動は厳密には一致しないことがあります。
📜 元の英語説明(参考)
Get reliable JSON, enums, and typed objects from LLMs using response_format, tool_use, and schema-constrained decoding across OpenAI, Anthropic, and Google APIs.
🇯🇵 日本人クリエイター向け解説
AI(人工知能)から、JSON
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o llm-structured-output.zip https://jpskill.com/download/3108.zip && unzip -o llm-structured-output.zip && rm llm-structured-output.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/3108.zip -OutFile "$d\llm-structured-output.zip"; Expand-Archive "$d\llm-structured-output.zip" -DestinationPath $d -Force; ri "$d\llm-structured-output.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
llm-structured-output.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
llm-structured-outputフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-17
- 取得日時
- 2026-05-17
- 同梱ファイル
- 1
💬 こう話しかけるだけ — サンプルプロンプト
- › LLM Structured Output の使い方を教えて
- › LLM Structured Output で何ができるか具体例で見せて
- › LLM Structured Output を初めて使う人向けにステップを案内して
これをClaude Code に貼るだけで、このSkillが自動発動します。
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
[Skill 名] llm-structured-output
LLM 構造化出力
このスキルができること
LLM API レスポンスから、フリーテキストをパースする代わりに、型付けされ検証済みのデータを抽出します。このスキルは、OpenAI の response_format と JSON Schema、Anthropic の構造化抽出のための tool_use ブロック、および Google の Gemini における responseSchema という、3つの主要なアプローチをカバーしています。それぞれの方法がいつ機能し、いつ破綻するのか、そしてすべての本番システムが遭遇するスキーマ検証の失敗に対するリトライロジックをどのように構築するかを学びます。
このスキルを使用するタイミング
- ユーザーが LLM レスポンスから構造化データ(JSON オブジェクト、配列、列挙型)を抽出する必要がある場合
- ユーザーが LLM 出力が直接コード(データベース書き込み、API 呼び出し、UI レンダリング)にフィードされるパイプラインを構築している場合
- ユーザーが OpenAI の
response_format、json_mode、json_object、またはjson_schemaについて尋ねている場合 - ユーザーがデータ抽出のために Anthropic の
tool_useまたはtool_resultブロックの使用について尋ねている場合(実際のツール実行のためではない) - ユーザーが
openainpm パッケージのzodResponseFormat()と Zod スキーマについて尋ねている場合 - ユーザーが
instructor、marvin、または手動検証を使用して LLM 出力を Pydantic モデルにパースする必要がある場合 - ユーザーが LLM レスポンスから不正な形式の JSON、欠落したフィールド、または間違った型を受け取っており、修正が必要な場合
- ユーザーがローカルモデルにおける
controlled generation、constrained decoding、またはgrammar-based samplingについて尋ねている場合
このスキルを使用しないタイミング:
- ユーザーが自由形式のテキスト生成(要約、エッセイ、チャット)を求めている場合
- ユーザーがフォーム検証または API 入力検証のために Zod について尋ねている場合(代わりに
zod-validation-expertを使用してください) - ユーザーがテキスト品質(構造ではない)向上のためのプロンプトエンジニアリングを必要としている場合
- ユーザーが実際の外部ツール/API を呼び出したい場合(このスキルは、実際のツールオーケストレーションではなく、構造化出力のハックとしての tool_use の使用をカバーしています)
コアワークフロー
-
ターゲットスキーマを特定します。ユーザーに抽出する必要があるフィールドを尋ねます。すべてのフィールドをその型、必須かオプションか、および該当する場合は有効な列挙値を定義します。具体的なスキーマなしでは先に進まないでください。
-
プロバイダーに適したメソッドを選択します。
- OpenAI (gpt-4o, gpt-4o-mini):
response_format: { type: "json_schema", json_schema: { ... } }を使用します。これにより、制約付きデコーディングを介してスキーマ準拠が保証された構造化出力が可能になります。 - Anthropic (Claude): ターゲットスキーマを
input_schemaとして持つ単一のツールを定義し、tool_choice: { type: "tool", name: "extract_data" }を設定します。Claude はtool_useコンテンツブロックに構造化データを返します。 - Google (Gemini): JSON Schema オブジェクトとともに
generationConfig.responseSchemaを使用し、responseMimeType: "application/json"を設定します。 - ローカルモデル (llama.cpp, vLLM): トークンレベルでの制約付きデコーディングのために GBNF 文法または
--json-schemaフラグを使用します。
- OpenAI (gpt-4o, gpt-4o-mini):
-
ユーザーの言語でスキーマ定義を記述します。Python の場合は Pydantic
BaseModelを定義します。TypeScript の場合は Zod スキーマを定義し、zodResponseFormat()で変換します。生の API 呼び出しの場合は、JSON Schema を直接記述します。 -
スキーマにフィールドレベルの記述を含めます。すべてのフィールドには、モデルに何を入れるべきかを伝える
description文字列が必要です。モデルはこれらの記述を暗黙的なプロンプト指示として使用します。たとえば、"The user's sentiment as positive, negative, or neutral"と記述されたフィールドは、コンテキストのない単なるsentiment: strよりも良い結果を生み出します。 -
システムプロンプトを設定して構造を強化します。モデルに、会話ではなくデータ抽出がその仕事であることを伝えます。例:
"You are a data extraction system. Analyze the input and return the requested fields. Do not include explanations outside the JSON structure." -
OpenAI の
json_schemaモードを使用している場合は、スキーマ定義で"strict": trueを設定します。これにより、モデルがスキーマに準拠するトークンのみを出力できる制約付きデコーディングが有効になります。strict: trueがないと、モデルは無効な JSON を生成する可能性があります。 -
Anthropic の tool_use アプローチを使用している場合は、
response.contentから構造化データを抽出するために、type == "tool_use"のブロックを見つけてそのinputフィールドを読み取ります。テキストブロックをパースしないでください。構造化データは tool_use ブロックにのみ存在します。 -
アプリケーションコードでレスポンスをスキーマに対して検証します。制約付きデコーディングを使用している場合でも、データを下流に渡す前に Pydantic の
model_validate()または Zod の.parse()で検証してください。これにより、スキーマ準拠だけでは防げない意味論的な問題(空の文字列、範囲外の数値)が捕捉されます。 -
検証失敗のためのリトライループを構築します。検証が失敗した場合、元の入力と失敗した出力、および検証エラーをモデルに送り返し、
"Your previous output failed validation: {error}. Fix the output."のような指示を与えます。リトライは3回までに制限します。 -
すべての構造化出力呼び出しを、入力、生のレスポンス、パースされた結果、および検証エラーとともにログに記録します。本番環境で構造化出力が破綻した場合、これらのログは、失敗がスキーマ設計の問題、プロンプトの問題、またはモデルの回帰によるものかを判断するために必要です。
例
例 1: Pydantic を使用した OpenAI 構造化出力 (Python)
from pydantic import BaseModel, Field
from openai import OpenAI
from enum import Enum
class Sentiment(str, Enum):
positive = "positive"
negative = "negative"
neutral = "neutral"
class ReviewAnalysis(BaseModel):
sentiment: Sentiment = Field(description="Overall sentiment of the review")
key_topics: list[str] = Field(description="Main topics mentioned, max 5")
purchase_intent: bool = Field(description="Whether the reviewer would buy again")
confidence_score: float = Field(ge=0.0, le=1.0, description="Model confidence 0-1")
client = OpenAI()
response = client.beta.chat.completions.parse(
model="gpt-4o-2024-08-06",
messages=[
{"role": "system", "content": "Extract structured review analysis."},
{"role": "user", "content": "This laptop is amazing. The battery lasts forever and the keyboard feels great. Definitely buying the next v 📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
LLM Structured Output
What This Skill Does
Extract typed, validated data from LLM API responses instead of parsing free-text. This skill covers the three main approaches: OpenAI's response_format with JSON Schema, Anthropic's tool_use block for structured extraction, and Google's responseSchema in Gemini. You will learn when each approach works, when it breaks, and how to build retry logic around schema validation failures that every production system encounters.
When to Use This Skill
- The user needs to extract structured data (JSON objects, arrays, enums) from an LLM response
- The user is building a pipeline where LLM output feeds directly into code (database writes, API calls, UI rendering)
- The user asks about
response_format,json_mode,json_object, orjson_schemain OpenAI - The user asks about using Anthropic's
tool_useortool_resultblocks for data extraction (not for actual tool execution) - The user asks about Zod schemas with
zodResponseFormat()from theopenainpm package - The user needs to parse LLM output into Pydantic models using
instructor,marvin, or manual validation - The user is getting malformed JSON, missing fields, or wrong types from LLM responses and needs a fix
- The user asks about
controlled generation,constrained decoding, orgrammar-based samplingin local models
Do NOT use this skill when:
- The user wants free-form text generation (summaries, essays, chat)
- The user is asking about Zod for form validation or API input validation (use
zod-validation-expertinstead) - The user needs prompt engineering for better text quality (not structure)
- The user wants to call real external tools/APIs (this skill covers using tool_use as a structured output hack, not actual tool orchestration)
Core Workflow
-
Identify the target schema. Ask the user what fields they need extracted. Define every field with its type, whether it's required or optional, and valid enum values if applicable. Do not proceed without a concrete schema.
-
Choose the provider-appropriate method:
- OpenAI (gpt-4o, gpt-4o-mini): Use
response_format: { type: "json_schema", json_schema: { ... } }. This enables Structured Outputs with guaranteed schema conformance via constrained decoding. - Anthropic (Claude): Define a single tool with the target schema as
input_schemaand settool_choice: { type: "tool", name: "extract_data" }. Claude returns the structured data in thetool_usecontent block. - Google (Gemini): Use
generationConfig.responseSchemawith a JSON Schema object and setresponseMimeType: "application/json". - Local models (llama.cpp, vLLM): Use GBNF grammars or
--json-schemaflag for constrained decoding at the token level.
- OpenAI (gpt-4o, gpt-4o-mini): Use
-
Write the schema definition in the user's language. For Python, define a Pydantic
BaseModel. For TypeScript, define a Zod schema and convert it withzodResponseFormat(). For raw API calls, write JSON Schema directly. -
Include field-level descriptions in the schema. Every field should have a
descriptionstring that tells the model what to put there. Models use these descriptions as implicit prompt instructions — a field described as"The user's sentiment as positive, negative, or neutral"produces better results than a baresentiment: strwith no context. -
Set the system prompt to reinforce structure. Tell the model its job is data extraction, not conversation. Example:
"You are a data extraction system. Analyze the input and return the requested fields. Do not include explanations outside the JSON structure." -
If using OpenAI's
json_schemamode, set"strict": truein the schema definition. This activates constrained decoding where the model can only output tokens that conform to the schema. Withoutstrict: true, the model may still produce invalid JSON. -
If using Anthropic's tool_use approach, extract the structured data from
response.contentby finding the block wheretype == "tool_use"and reading itsinputfield. Do not parse the text blocks — the structured data lives exclusively in the tool_use block. -
Validate the response against the schema in your application code. Even with constrained decoding, validate with Pydantic's
model_validate()or Zod's.parse()before passing data downstream. This catches semantic issues (empty strings, out-of-range numbers) that schema conformance alone cannot prevent. -
Build a retry loop for validation failures. When validation fails, send the original input plus the failed output and the validation error back to the model with an instruction like
"Your previous output failed validation: {error}. Fix the output."Cap retries at 3 attempts. -
Log every structured output call with: the input, the raw response, the parsed result, and any validation errors. When structured output breaks in production, you need these logs to determine whether the failure was a schema design issue, a prompt issue, or a model regression.
Examples
Example 1: OpenAI Structured Outputs with Pydantic (Python)
from pydantic import BaseModel, Field
from openai import OpenAI
from enum import Enum
class Sentiment(str, Enum):
positive = "positive"
negative = "negative"
neutral = "neutral"
class ReviewAnalysis(BaseModel):
sentiment: Sentiment = Field(description="Overall sentiment of the review")
key_topics: list[str] = Field(description="Main topics mentioned, max 5")
purchase_intent: bool = Field(description="Whether the reviewer would buy again")
confidence_score: float = Field(ge=0.0, le=1.0, description="Model confidence 0-1")
client = OpenAI()
response = client.beta.chat.completions.parse(
model="gpt-4o-2024-08-06",
messages=[
{"role": "system", "content": "Extract structured review analysis."},
{"role": "user", "content": "This laptop is amazing. The battery lasts forever and the keyboard feels great. Definitely buying the next version."}
],
response_format=ReviewAnalysis,
)
result = response.choices[0].message.parsed
# result.sentiment == Sentiment.positive
# result.key_topics == ["battery life", "keyboard"]
# result.purchase_intent == True
Example 2: Anthropic tool_use for Structured Extraction (Python)
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
system="You are a data extraction system. Use the provided tool to return structured data.",
tools=[{
"name": "extract_invoice",
"description": "Extract invoice fields from text",
"input_schema": {
"type": "object",
"properties": {
"vendor_name": {"type": "string", "description": "Company that issued the invoice"},
"total_amount": {"type": "number", "description": "Total amount in USD"},
"line_items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"description": {"type": "string"},
"quantity": {"type": "integer"},
"unit_price": {"type": "number"}
},
"required": ["description", "quantity", "unit_price"]
}
}
},
"required": ["vendor_name", "total_amount", "line_items"]
}
}],
tool_choice={"type": "tool", "name": "extract_invoice"},
messages=[{"role": "user", "content": "Invoice from Acme Corp: 3x Widget A at $10 each, 1x Widget B at $25. Total: $55."}]
)
# Find the tool_use block — do NOT parse text blocks
tool_block = next(b for b in response.content if b.type == "tool_use")
invoice = tool_block.input
# invoice["vendor_name"] == "Acme Corp"
# invoice["total_amount"] == 55.0
Example 3: TypeScript with Zod + zodResponseFormat
import OpenAI from "openai";
import { z } from "zod";
import { zodResponseFormat } from "openai/helpers/zod";
const EventSchema = z.object({
event_name: z.string().describe("Name of the event"),
date: z.string().describe("ISO 8601 date string"),
location: z.string().describe("City and venue"),
attendee_count: z.number().int().describe("Expected number of attendees"),
is_virtual: z.boolean().describe("Whether the event is online-only"),
});
const client = new OpenAI();
const completion = await client.beta.chat.completions.parse({
model: "gpt-4o-2024-08-06",
messages: [
{ role: "system", content: "Extract event details from the text." },
{ role: "user", content: "Tech Summit 2025 in Austin at the Convention Center on March 15th. Expecting 2000 attendees, in-person only." },
],
response_format: zodResponseFormat(EventSchema, "event_extraction"),
});
const event = completion.choices[0].message.parsed;
// event.event_name === "Tech Summit 2025"
// event.is_virtual === false
Never Do This
-
Never use
response_format: { type: "json_object" }without a schema. This is OpenAI's legacy JSON mode — it guarantees valid JSON syntax but not schema conformance. The model can return{"result": "hello"}when you expected{"name": str, "age": int}. Always usejson_schemawith a full schema definition instead. -
Never parse Anthropic's text blocks for structured data. When using
tool_choiceto force structured output, the data is in thetool_usecontent block, not in anytextblock. Parsingresponse.content[0].textwill either return empty string or a conversational preamble — never the data you need. -
Never define schema fields without descriptions. A field named
statuswith no description can mean HTTP status, order status, or review status. Models use field descriptions as extraction instructions. Omitting them is equivalent to omitting half your prompt. -
Never use
additionalProperties: truein strict mode schemas. OpenAI's strict mode requiresadditionalProperties: falseon every object in the schema. If you set it to true or omit it, the API rejects the request with a 400 error, not at response time — you will never get a response at all. -
Never put extraction instructions only in the user message and not the system prompt. The system prompt has higher attention weight for behavioral instructions. Putting "extract the following fields" only in the user message alongside the source text forces the model to split attention between the instruction and the data. System prompt defines behavior; user message provides input data.
-
Never assume structured output means correct output. Constrained decoding guarantees the response matches the schema's types and structure. It does not guarantee the values are correct. A model can return
{"sentiment": "positive"}for a negative review if the source text is ambiguous. Always validate semantics in application code after schema validation. -
Never use recursive or deeply nested schemas without testing. Recursive types (
$refpointing to the same definition) and schemas deeper than 3 levels increase decoding latency significantly and raise the probability of the model hitting max_tokens before completing the JSON structure. Flatten nested schemas where possible.
Edge Cases
-
Long source text exceeding context window. When the input text is too long, the model may truncate its reading and return incomplete extractions. Split long documents into chunks, extract from each chunk independently, then merge results in application code. Do not rely on the model to handle 50-page documents in a single call.
-
The model returns a
refusalinstead of structured data. OpenAI's structured output can return arefusalfield when the model considers the request unsafe. Checkresponse.choices[0].message.refusalbefore accessing.parsed. Ifrefusalis not None, the parsed data will be None and accessing it throws an error. -
Array fields returning empty when data exists. Models sometimes return
[]for array fields when the source text contains the data but the field description is too vague. Fix by making the description prescriptive:"List of all product names mentioned in the text. Return at least one if any product is referenced.". -
Enum values not matching due to casing. If you define an enum as
["Active", "Inactive"]but the model returns"active", validation fails. Either lowercase all enum values in the schema or add a normalization step before validation. OpenAI's strict mode respects exact casing; Anthropic may not. -
Streaming with structured output. OpenAI supports streaming structured output where partial JSON arrives chunk by chunk. You cannot parse intermediate chunks as valid JSON. Use the
openaiSDK's built-in partial parsing or buffer chunks until the stream completes. Anthropic's tool_use blocks arrive complete in a singlecontent_block_stopevent — no partial assembly needed.
Best Practices
-
Start with the simplest schema that solves the problem. Flat objects with 3-5 fields produce higher accuracy than nested schemas with 20+ fields. If you need complex data, extract in two passes: first extract top-level entities, then make a second call to extract details for each entity.
-
Use enums instead of free-form strings for categorical data. A field
mood: strcan return anything. A fieldmood: Literal["happy", "sad", "neutral", "angry"]constrains the model to exactly those values. This reduces downstream parsing logic to zero. -
Pin the model version in production.
gpt-4ois an alias that changes when OpenAI releases new versions. Structured output behavior can change between versions. Usegpt-4o-2024-08-06explicitly so that your schema+prompt combination remains stable until you deliberately upgrade. -
Test schema changes against 20+ real inputs before deploying. Schema changes (adding a field, changing a type, modifying a description) can break extraction on inputs that previously worked. Build a test suite of real inputs with expected outputs and run it on every schema change. This is the structured output equivalent of unit testing.
-
Use
defaultvalues in Pydantic models for optional fields. When a field might not have relevant data in the source text, define it asOptional[str] = Nonein Pydantic or.optional()in Zod. Without defaults, the model is forced to hallucinate a value for fields where the source text has no answer. -
Separate extraction schemas from application schemas. Your LLM extraction schema should match what the model can reliably produce. Your application database schema may have additional computed fields, foreign keys, or constraints. Map between them in application code — do not force the LLM to understand your database schema.
Limitations
- Use this skill only when the task clearly matches the scope described above.
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.