構造化出力
構造化出力により、モデルの応答は自由形式のテキストではなく、指定したJSON形式に厳格に準拠したものになります。RouteAPIは2つの構造化出力モードをサポートしています:JSON mode(有効なJSONの出力を要求)とJSON Schema(特定のschemaへの準拠を保証)です。
1. 構造化出力の概要
Section titled “1. 構造化出力の概要”構造化出力とは
Section titled “構造化出力とは”構造化出力は、モデルの応答形式を制御する仕組みです。通常の対話でモデルが自由にテキストを生成するのとは異なり、構造化出力はモデルに定義した形式でJSONデータを生成させます。これは、モデル出力をプログラム的に処理する必要があるシナリオ(データ抽出、フォーム生成、APIレスポンス解析)において非常に重要です。
JSON mode vs JSON Schema
Section titled “JSON mode vs JSON Schema”RouteAPIは2つの構造化出力モードを提供します:
| 比較項目 | JSON mode | JSON Schema |
|---|---|---|
| 保証内容 | 出力が有効なJSON | 出力が指定されたschemaに準拠 |
| パラメータ | response_format: { type: "json_object" } | response_format: { type: "json_schema", json_schema: {...} } |
| schema定義 | 不要、ただしpromptで形式を説明する必要あり | 完全なJSON Schemaの提供が必須 |
| 厳密度 | パース可能であることのみ保証、構造は保証しない | フィールド、型、必須項目が完全に準拠することを保証 |
| 適用シナリオ | 形式がシンプルで、モデルがpromptから構造を理解できる場合 | 複雑なネスト構造、厳密な型検証が必要な場合 |
簡単な理解:JSON modeは「JSON.parseで正常に解析できる」ことのみを保証し、内部のフィールドは問いません。JSON Schemaは有効性だけでなく、構造、フィールド名、型、必須項目がすべて定義に準拠することを保証します。
適用シナリオ
Section titled “適用シナリオ”| シナリオ | 説明 | 推奨モード |
|---|---|---|
| データ抽出 | 非構造化テキストから構造化情報を抽出(氏名、住所、日付) | JSON Schema |
| フォーム生成 | モデルにフォームの初期値や設定オブジェクトを生成させる | JSON Schema |
| APIレスポンス解析 | モデル出力を下流システムのAPIに連携する必要がある | JSON Schema |
| シンプルなキー値ペア | 数個のフィールドのみで、構造が明確 | JSON mode |
| 分類タスク | 固定の列挙値を出力(例:感情分類 positive/negative/neutral) | JSON Schema + enum |
2. JSON Mode
Section titled “2. JSON Mode”JSON modeは最もシンプルな構造化出力方法です:リクエストでresponse_format.typeを"json_object"に設定すると、モデルは通常のテキストではなく有効なJSONを出力します。
リクエスト形式
Section titled “リクエスト形式”{ "model": "gpt-5.5", "messages": [ { "role": "system", "content": "你是一个数据提取助手。请从用户输入中提取姓名、年龄、城市三个字段,以 JSON 格式返回。" }, { "role": "user", "content": "我叫李明,今年 28 岁,住在上海。" } ], "response_format": { "type": "json_object" }}重要なポイント
Section titled “重要なポイント”-
promptでJSON形式を説明する必要があります:モデルはどのフィールドが必要かを知らないため、system messageまたはuser messageで出力するフィールドと型を明確に指示する必要があります。上記の例では、
"请从用户输入中提取姓名、年龄、城市三个字段,以 JSON 格式返回"が形式の説明です。 -
schemaへの準拠は保証されません:モデルは
{"name": "李明", "age": 28, "city": "上海"}を出力するかもしれませんし、{"姓名": "李明", "年龄": 28}、さらには{"person": {"name": "李明"}}を出力する可能性もあります。有効なJSONであれば要件を満たします。 -
使用方法:形式がシンプルで、フィールドが少なく、モデルが自然言語から構造を理解できるシナリオに適しています。フィールド名や型の厳密な検証が必要な場合はJSON Schemaを使用してください。
リクエスト(curl):
curl https://api.routeapi.ai/v1/chat/completions \ -H "Authorization: Bearer $ROUTEAPI_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-5.5", "messages": [ { "role": "system", "content": "你是一个数据提取助手。从用户输入中提取 name(姓名)、age(年龄)、city(城市)三个字段,以 JSON 格式返回。" }, { "role": "user", "content": "我叫李明,今年 28 岁,住在上海。" } ], "response_format": { "type": "json_object" } }'レスポンス:
{ "id": "chatcmpl_xxx", "object": "chat.completion", "created": 1730000000, "model": "gpt-5.5", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "{\"name\": \"李明\", \"age\": 28, \"city\": \"上海\"}" }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 58, "completion_tokens": 18, "total_tokens": 76 }}message.contentはJSON文字列であることに注意してください。自分でJSON.parse / json.loadsを使用して解析する必要があります。
3. JSON Schema(Structured Outputs)
Section titled “3. JSON Schema(Structured Outputs)”JSON Schemaモードでは、出力の構造を正確に定義でき、モデルはschema定義に完全に準拠したJSONを生成することを保証します。
リクエスト形式
Section titled “リクエスト形式”{ "model": "gpt-5.5", "messages": [ { "role": "user", "content": "我叫李明,今年 28 岁,住在上海。" } ], "response_format": { "type": "json_schema", "json_schema": { "name": "person_extraction", "strict": true, "schema": { "type": "object", "properties": { "name": { "type": "string", "description": "姓名" }, "age": { "type": "integer", "description": "年龄" }, "city": { "type": "string", "description": "城市" } }, "required": ["name", "age", "city"], "additionalProperties": false } } }}response_format構造
Section titled “response_format構造”| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
type | string | はい | "json_schema"に固定 |
json_schema.name | string | はい | schemaの名前、識別用、英数字、アンダースコア、ハイフン |
json_schema.strict | boolean | いいえ | 厳密モードを有効にするか、デフォルトはfalse |
json_schema.schema | object | はい | 標準JSON Schema定義 |
厳密モード vs 非厳密モード
Section titled “厳密モード vs 非厳密モード”| モード | strict | 動作 |
|---|---|---|
| 厳密モード | true | モデルは必ずschemaに完全に従って生成、フィールド名、型、必須項目、additionalPropertiesすべてを厳密に遵守 |
| 非厳密モード | false | モデルはできる限りschemaに準拠、ただし完全一致は保証せず、フィールドの欠落や追加の可能性あり |
推奨:本番環境ではstrict: trueを使用してください。これがJSON Schemaモードの核心的価値です。非厳密モードの動作はJSON mode + prompt説明に近く、あまり意義がありません。
schema定義の規範
Section titled “schema定義の規範”schemaフィールドは標準JSON Schema規範(Draft 2020-12)に従い、よく使用されるフィールド:
| フィールド | 説明 |
|---|---|
type | データ型:"object", "array", "string", "number", "integer", "boolean", "null" |
properties | オブジェクトのフィールド定義(typeが"object"の場合に使用) |
required | 必須フィールド名の配列 |
additionalProperties | 未定義の追加フィールドを許可するか(厳密モードではfalseを推奨) |
items | 配列要素のschema(typeが"array"の場合に使用) |
enum | 列挙値リスト、取りうる値を制限 |
description | フィールドの説明、モデルが意味を理解するのに役立つ |
4. Schema定義ガイド
Section titled “4. Schema定義ガイド”{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "score": { "type": "number" }, "is_active": { "type": "boolean" }, "notes": { "type": ["string", "null"] } }}型の説明:
"string": 文字列"integer": 整数"number": 数値(整数と小数を含む)"boolean": ブール値"null": null値["string", "null"]: 文字列またはnullを許可(オプショナルフィールド)
オブジェクトと配列
Section titled “オブジェクトと配列”{ "type": "object", "properties": { "user": { "type": "object", "properties": { "name": { "type": "string" }, "email": { "type": "string" } }, "required": ["name"] }, "tags": { "type": "array", "items": { "type": "string" } }, "scores": { "type": "array", "items": { "type": "number" } } }}必須フィールド
Section titled “必須フィールド”{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "city": { "type": "string" } }, "required": ["name", "age"]}required配列には必ず存在する必要があるフィールドを列挙します。上記の例ではnameとageは必須、cityはオプショナルです。
{ "type": "object", "properties": { "sentiment": { "type": "string", "enum": ["positive", "negative", "neutral"], "description": "情感分类结果" }, "priority": { "type": "integer", "enum": [1, 2, 3], "description": "优先级:1-低,2-中,3-高" } }, "required": ["sentiment"]}enumはフィールドがリスト内の値のみを取れるよう制限し、モデルは他の値を生成しません。
{ "type": "object", "properties": { "user": { "type": "object", "properties": { "name": { "type": "string" }, "address": { "type": "object", "properties": { "city": { "type": "string" }, "street": { "type": "string" } }, "required": ["city"] } }, "required": ["name", "address"] } }, "required": ["user"]}オブジェクトは無限にネストできますが、深すぎるネストはモデルの生成品質とパフォーマンスに影響する可能性があります。
説明フィールド
Section titled “説明フィールド”{ "type": "object", "properties": { "date": { "type": "string", "description": "日期,格式 YYYY-MM-DD" }, "amount": { "type": "number", "description": "金额,单位:元" } }}descriptionは必須ではありませんが、強く推奨します。これはモデルがフィールドの意味、取りうる値の範囲、形式の規約を理解するのに役立ち、生成精度を大幅に向上させます。
5. Schemaの例
Section titled “5. Schemaの例”ユーザー情報抽出
Section titled “ユーザー情報抽出”非構造化テキストからユーザー情報を抽出:
{ "name": "user_info_extraction", "strict": true, "schema": { "type": "object", "properties": { "name": { "type": "string", "description": "用户姓名" }, "age": { "type": "integer", "description": "年龄" }, "email": { "type": ["string", "null"], "description": "电子邮箱,如果文本中没有则为 null" }, "phone": { "type": ["string", "null"], "description": "手机号,如果文本中没有则为 null" }, "city": { "type": "string", "description": "所在城市" } }, "required": ["name", "age", "city"], "additionalProperties": false }}商品リスト生成
Section titled “商品リスト生成”モデルに商品配列を生成させる:
{ "name": "product_list", "strict": true, "schema": { "type": "object", "properties": { "products": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string", "description": "商品名称" }, "price": { "type": "number", "description": "价格,单位:元" }, "category": { "type": "string", "enum": ["electronics", "clothing", "food", "other"], "description": "商品分类" }, "in_stock": { "type": "boolean", "description": "是否有货" } }, "required": ["name", "price", "category", "in_stock"], "additionalProperties": false } }, "total_count": { "type": "integer", "description": "商品总数" } }, "required": ["products", "total_count"], "additionalProperties": false }}複雑なネストオブジェクト
Section titled “複雑なネストオブジェクト”注文情報の抽出、複数階層のネスト:
{ "name": "order_extraction", "strict": true, "schema": { "type": "object", "properties": { "order_id": { "type": "string", "description": "订单号" }, "customer": { "type": "object", "properties": { "name": { "type": "string" }, "phone": { "type": "string" }, "address": { "type": "object", "properties": { "province": { "type": "string" }, "city": { "type": "string" }, "street": { "type": "string" } }, "required": ["province", "city", "street"], "additionalProperties": false } }, "required": ["name", "phone", "address"], "additionalProperties": false }, "items": { "type": "array", "items": { "type": "object", "properties": { "product_name": { "type": "string" }, "quantity": { "type": "integer" }, "unit_price": { "type": "number" } }, "required": ["product_name", "quantity", "unit_price"], "additionalProperties": false } }, "total_amount": { "type": "number", "description": "订单总金额" } }, "required": ["order_id", "customer", "items", "total_amount"], "additionalProperties": false }}6. 各モデルのサポート状況
Section titled “6. 各モデルのサポート状況”JSON modeをサポートするモデル
Section titled “JSON modeをサポートするモデル”RouteAPIが統合している主流モデルのほとんどがJSON mode(response_format: { type: "json_object" })をサポートしています:
- OpenAI GPTシリーズ(gpt-4o, gpt-4-turbo, gpt-3.5-turbo等)
- Claudeシリーズ(claude-3.5-sonnet, claude-3-opus, claude-3-haiku等)
- Geminiシリーズ(gemini-2.0-flash, gemini-1.5-pro等)
- その他OpenAI形式をサポートするモデル
JSON Schemaをサポートするモデル
Section titled “JSON Schemaをサポートするモデル”JSON Schema(response_format: { type: "json_schema" })はモデルの能力により高い要求があり、現在サポートしているモデル:
- OpenAI: gpt-4oシリーズ、gpt-4-turboシリーズ(2024-08-06以降のバージョン)
- Claude: claude-3.5-sonnetシリーズ、claude-3-opusシリーズ
- Gemini: gemini-2.0-flash-exp、gemini-1.5-proシリーズ
- その他:一部の新世代モデル
確認方法:呼び出し前にModels APIでモデルの能力を照会し、supports_response_formatフィールドを確認してください。
モデル能力比較表
Section titled “モデル能力比較表”| 能力 | JSON mode | JSON Schema | 説明 |
|---|---|---|---|
| サポートモデル範囲 | 広範囲(ほぼすべての主流モデル) | 限定的(新世代モデル) | JSON modeのサポートがより高い |
| schemaの複雑度 | 該当なし | 3階層以内のネストを推奨 | 深すぎると生成品質に影響 |
| 最大フィールド数 | 該当なし | トップレベルフィールド50個以内を推奨 | フィールドが多すぎるとパフォーマンスに影響 |
| 厳密な保証 | 有効なJSONのみ保証 | schemaへの準拠を保証 | 厳密モードで100%準拠 |
| パフォーマンス | 速い | 相対的に遅い | schema検証に追加オーバーヘッドあり |
| Token消費 | 低い | やや高い | schema定義がprompt tokensを占有 |
制限と注意事項
Section titled “制限と注意事項”-
schemaサイズ制限:単一schema定義は10KB以下を推奨します。大きすぎるschemaは切り捨てられるか拒否される可能性があります。
-
ネスト深度制限:ネスト階層は3-4階層以内を推奨します。深すぎるネストはモデルの生成品質と速度を低下させます。
-
パフォーマンスへの影響:JSON Schemaモードの応答時間は通常のリクエストより10%-30%遅くなります。モデルが生成過程で構造をリアルタイムで検証する必要があるためです。
-
サポートされないschema機能:一部の高度なJSON Schema機能(
$ref、allOf、anyOf、oneOf、正規表現)は、すべてのモデルでサポートされない可能性があります。 -
ストリーミング出力:JSON Schemaモードはストリーミング出力(
stream: true)をサポートしますが、contentは断片的に返されるため、完全なJSONは連結後に解析する必要があります。
7. 完全なアプリケーション例
Section titled “7. 完全なアプリケーション例”例1:非構造化テキストから構造化情報を抽出
Section titled “例1:非構造化テキストから構造化情報を抽出”シナリオ:カスタマーサポート会話から顧客情報と問題分類を抽出。
curl:
curl https://api.routeapi.ai/v1/chat/completions \ -H "Authorization: Bearer $ROUTEAPI_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-4o", "messages": [ { "role": "user", "content": "客户李明(手机 13800138000)反馈在北京市朝阳区的订单 ORD-2024-001 一直没发货,比较着急。" } ], "response_format": { "type": "json_schema", "json_schema": { "name": "customer_inquiry", "strict": true, "schema": { "type": "object", "properties": { "customer_name": { "type": "string", "description": "客户姓名" }, "phone": { "type": ["string", "null"], "description": "客户手机号" }, "location": { "type": ["string", "null"], "description": "客户所在地" }, "order_id": { "type": ["string", "null"], "description": "订单号" }, "issue_category": { "type": "string", "enum": ["delivery", "quality", "refund", "other"], "description": "问题分类:delivery-物流,quality-质量,refund-退款,other-其他" }, "urgency": { "type": "string", "enum": ["low", "medium", "high"], "description": "紧急程度" } }, "required": ["customer_name", "issue_category", "urgency"], "additionalProperties": false } } } }'レスポンス:
{ "choices": [ { "message": { "role": "assistant", "content": "{\"customer_name\":\"李明\",\"phone\":\"13800138000\",\"location\":\"北京市朝阳区\",\"order_id\":\"ORD-2024-001\",\"issue_category\":\"delivery\",\"urgency\":\"high\"}" }, "finish_reason": "stop" } ]}Python:
import osimport jsonfrom openai import OpenAI
client = OpenAI( api_key=os.environ["ROUTEAPI_KEY"], base_url="https://api.routeapi.ai/v1",)
response = client.chat.completions.create( model="gpt-4o", messages=[ { "role": "user", "content": "客户李明(手机 13800138000)反馈在北京市朝阳区的订单 ORD-2024-001 一直没发货,比较着急。", } ], response_format={ "type": "json_schema", "json_schema": { "name": "customer_inquiry", "strict": True, "schema": { "type": "object", "properties": { "customer_name": {"type": "string", "description": "客户姓名"}, "phone": {"type": ["string", "null"], "description": "客户手机号"}, "location": {"type": ["string", "null"], "description": "客户所在地"}, "order_id": {"type": ["string", "null"], "description": "订单号"}, "issue_category": { "type": "string", "enum": ["delivery", "quality", "refund", "other"], "description": "问题分类", }, "urgency": { "type": "string", "enum": ["low", "medium", "high"], "description": "紧急程度", }, }, "required": ["customer_name", "issue_category", "urgency"], "additionalProperties": False, }, }, },)
data = json.loads(response.choices[0].message.content)print(f"客户: {data['customer_name']}")print(f"问题类型: {data['issue_category']}")print(f"紧急程度: {data['urgency']}")Node.js:
import OpenAI from 'openai';
const client = new OpenAI({ apiKey: process.env.ROUTEAPI_KEY, baseURL: 'https://api.routeapi.ai/v1',});
const response = await client.chat.completions.create({ model: 'gpt-4o', messages: [ { role: 'user', content: '客户李明(手机 13800138000)反馈在北京市朝阳区的订单 ORD-2024-001 一直没发货,比较着急。', }, ], response_format: { type: 'json_schema', json_schema: { name: 'customer_inquiry', strict: true, schema: { type: 'object', properties: { customer_name: { type: 'string', description: '客户姓名' }, phone: { type: ['string', 'null'], description: '客户手机号' }, location: { type: ['string', 'null'], description: '客户所在地' }, order_id: { type: ['string', 'null'], description: '订单号' }, issue_category: { type: 'string', enum: ['delivery', 'quality', 'refund', 'other'], description: '问题分类', }, urgency: { type: 'string', enum: ['low', 'medium', 'high'], description: '紧急程度', }, }, required: ['customer_name', 'issue_category', 'urgency'], additionalProperties: false, }, }, },});
const data = JSON.parse(response.choices[0].message.content);console.log(`客户: ${data.customer_name}`);console.log(`问题类型: ${data.issue_category}`);console.log(`紧急程度: ${data.urgency}`);例2:フォームデータの生成
Section titled “例2:フォームデータの生成”シナリオ:自然言語の記述に基づいてモデルにフォームの初期値を生成させる。
Python:
response = client.chat.completions.create( model="gpt-4o", messages=[ { "role": "system", "content": "你是一个表单填充助手。根据用户描述生成表单数据。", }, { "role": "user", "content": "创建一个新员工入职表单:张伟,男,1995 年出生,本科学历,软件工程师职位,月薪 15000。", }, ], response_format={ "type": "json_schema", "json_schema": { "name": "employee_form", "strict": True, "schema": { "type": "object", "properties": { "name": {"type": "string"}, "gender": {"type": "string", "enum": ["male", "female"]}, "birth_year": {"type": "integer"}, "education": { "type": "string", "enum": ["high_school", "bachelor", "master", "phd"], }, "position": {"type": "string"}, "salary": {"type": "number", "description": "月薪,单位:元"}, }, "required": ["name", "gender", "birth_year", "education", "position", "salary"], "additionalProperties": False, }, }, },)
form_data = json.loads(response.choices[0].message.content)print(json.dumps(form_data, ensure_ascii=False, indent=2))出力:
{ "name": "张伟", "gender": "male", "birth_year": 1995, "education": "bachelor", "position": "软件工程师", "salary": 15000}例3:APIレスポンス解析
Section titled “例3:APIレスポンス解析”シナリオ:サードパーティAPIの非構造化レスポンスからモデルに重要情報を抽出させる。
Node.js:
const apiResponse = `订单状态:已发货物流公司:顺丰速运运单号:SF1234567890预计送达:2024 年 1 月 20 日当前位置:北京市分拨中心`;
const response = await client.chat.completions.create({ model: 'gpt-4o', messages: [ { role: 'user', content: `从以下物流信息中提取结构化数据:\n${apiResponse}`, }, ], response_format: { type: 'json_schema', json_schema: { name: 'logistics_info', strict: true, schema: { type: 'object', properties: { status: { type: 'string', enum: ['pending', 'shipped', 'in_transit', 'delivered'], }, carrier: { type: 'string', description: '物流公司' }, tracking_number: { type: 'string', description: '运单号' }, estimated_delivery: { type: ['string', 'null'], description: '预计送达日期,格式 YYYY-MM-DD', }, current_location: { type: ['string', 'null'], description: '当前位置' }, }, required: ['status', 'carrier', 'tracking_number'], additionalProperties: false, }, }, },});
const data = JSON.parse(response.choices[0].message.content);console.log(data);// 出力: { status: 'shipped', carrier: '顺丰速运', tracking_number: 'SF1234567890', estimated_delivery: '2024-01-20', current_location: '北京市分拨中心' }8. エラー処理
Section titled “8. エラー処理”Schema検証失敗
Section titled “Schema検証失敗”schema定義自体に問題がある場合(構文エラー、サポートされていない機能)、リクエストは直接400エラーを返します:
{ "error": { "message": "Invalid JSON schema: ...", "type": "invalid_request_error", "param": "response_format.json_schema.schema", "code": "invalid_json_schema" }}解決方法:
- schemaの構文がJSON Schema規範に準拠しているか確認
- サポートされていない高度な機能(
$ref、allOfなど)を削除 - 深すぎるネスト構造を簡素化
モデルがschemaに準拠した出力を生成できない
Section titled “モデルがschemaに準拠した出力を生成できない”ごく稀に、モデルがschemaに準拠したコンテンツを生成できない場合があります(ユーザー入力とschema要件が完全に矛盾する場合など)。この場合、エラーが返されるか通常のテキスト出力にフォールバックされます。エラー例:
{ "error": { "message": "Failed to generate valid output matching the provided schema after maximum retries.", "type": "model_error", "code": "schema_generation_failed" }}解決方法:
- promptがschema要件と一致しているか確認
- schemaを簡素化し、厳しすぎる制約を削除
- promptで出力要件を明確に説明
- オプショナルフィールドには
"string"だけでなく["string", "null"]型を使用
リトライ戦略
Section titled “リトライ戦略”偶発的な生成失敗に対して、自動リトライを実装できます:
import time
def call_with_retry(client, **kwargs): max_retries = 3 for attempt in range(max_retries): try: response = client.chat.completions.create(**kwargs) content = response.choices[0].message.content data = json.loads(content) # 解析可能か検証 return data except (json.JSONDecodeError, Exception) as e: if attempt == max_retries - 1: raise time.sleep(2 ** attempt) # 指数バックオフ9. ベストプラクティス
Section titled “9. ベストプラクティス”Schema設計原則
Section titled “Schema設計原則”-
シンプルから始める:まずJSON modeで実行可能性を検証し、厳密な検証が必要であることを確認してからJSON Schemaにアップグレードします。
-
必須とオプショナルを明確に:必須フィールドは
required配列に、オプショナルフィールドは["type", "null"]を使用するかrequiredに入れません。 -
enumで列挙を制限:取りうる値が限られているフィールド(状態、分類、優先度)には、
enumで明示的にリストアップすることでエラー率を大幅に下げられます。 -
descriptionを追加:各フィールドに
descriptionを追加し、意味、形式、取りうる値の範囲を説明すると、モデルはそれに基づいてより正確に生成します。 -
additionalProperties: falseを設定:厳密モードでは、これを追加するとモデルが未定義の追加フィールドを出力するのを防げます。
過度に複雑なschemaを避ける
Section titled “過度に複雑なschemaを避ける”| 問題 | 説明 | 推奨 |
|---|---|---|
| ネストが深すぎる | 4階層を超えるネストは生成品質を低下させる | 複数のフラットなオブジェクトに分割、または複数ラウンドの対話で段階的に抽出 |
| フィールドが多すぎる | 単一オブジェクトで50フィールドを超える | ビジネスロジックでグループ化し、複数のサブオブジェクトに分割 |
| 過度な制約 | すべてのフィールドが必須で柔軟性がない | コアフィールドのみを必須とし、他のフィールドはnullを許可 |
| descriptionがない | モデルがフィールドの意味を理解できない | 各フィールドにdescriptionを追加し、明確に説明 |
パフォーマンス最適化
Section titled “パフォーマンス最適化”-
schemaサイズを削減:schema定義はprompt tokensを占有するため、大きすぎるschemaは遅延とコストを増加させます。
-
schema定義をキャッシュ:同じschemaを繰り返し使用する場合、コード内で定数として定義し、リクエストごとに再構築するのを避けます。
-
適切なモデルを選択:すべてのタスクに最強のモデルが必要なわけではありません。シンプルな構造化抽出にはgpt-3.5-turbo + JSON modeを使用できます。
-
バッチ処理:類似したタスクが複数ある場合、配列schemaを設計し、モデルに一度に複数のデータを処理させることができます。
コストの考慮
Section titled “コストの考慮”| 要因 | 影響 | 最適化推奨 |
|---|---|---|
| schemaサイズ | schema定義がprompt tokensを占有 | descriptionを簡素化し、冗長なフィールドを削除 |
| モデル選択 | JSON Schemaには通常より強力なモデルが必要 | シンプルなタスクにはJSON mode + 弱いモデルを使用 |
| レスポンス長 | JSON出力は通常テキストより長い(キー名、引用符、括弧) | フィールド名を短縮し、長い文字列の代わりに列挙を使用 |
| リトライ回数 | 生成失敗のリトライは課金が倍増 | schemaとpromptを最適化して失敗率を下げる |
実用的なヒント:高頻度で呼び出すシナリオでは、まずJSON modeでテストし、モデルが安定して正しい形式を出力できることを確認してからJSON Schemaにアップグレードします。JSON modeのtoken消費とコストは通常JSON Schemaより10%-20%低くなります。
互換性に関する注意
Section titled “互換性に関する注意”- JSON modeとJSON Schemaのサポートは選択したモデルに依存します。Models APIで
supports_response_formatフィールドを照会して確認してください。 response_formatとtools(ツール呼び出し)は相互排他的です:同一リクエストで構造化出力とツール呼び出しを同時に使用することはできません。- ストリーミング出力(
stream: true)では、contentは断片的に返されるため、完全に連結してからJSON.parseする必要があります。 - 明示的に
0またはfalseが渡されたオプショナルパラメータは、ユーザーが明示的に設定したものとみなされ、デフォルトとして破棄されません。 - 各リクエストのrequest ID、model ID、ステータスコード、token使用量を記録し、トラブルシューティングを容易にします。エラー構造の詳細はエラーとデバッグを参照してください。