構造化出力
構造化出力を使用すると、推論 API 呼び出しの一部として指定した JSON スキーマ定義にモデルが従うようになります。 これは、有効な JSON が生成されることは保証されていたものの指定されたスキーマに厳密に準拠させることはできなかった以前の JSON モード機能とは対照的です。 構造化出力は、関数の呼び出し、構造化データの抽出、複雑な複数ステップ ワークフローの構築に推奨されます。
Note
- 現在、構造化された出力は、独自のデータを使用する (bring your own data) シナリオではサポートされていません。
サポートされているモデル
o1
のバージョン:2024-12-17
gpt-4o-mini
のバージョン:2024-07-18
gpt-4o
のバージョン:2024-08-06
API のサポート
構造化出力のサポートは、API バージョン 2024-08-01-preview
で最初に追加されました。 最新のプレビュー API と最新の GA API で使用できます: 2024-10-21
。
作業の開始
Python では、Pydantic
を使用してオブジェクト スキーマを定義できます。 実行中の OpenAI ライブラリと Pydantic
ライブラリ のバージョンによっては、新しいバージョンにアップグレードする必要があります。 これらの例は、openai 1.42.0
と pydantic 2.8.2
に対してテストされています。
pip install openai pydantic --upgrade
認証に Microsoft Entra ID を使うのが初めての場合は、「Microsoft Entra ID 認証を使用して Azure OpenAI Service を構成する方法」をご覧ください。
from pydantic import BaseModel
from openai import AzureOpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
token_provider = get_bearer_token_provider(
DefaultAzureCredential(), "https://cognitiveservices.azure.com/.default"
)
client = AzureOpenAI(
azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"),
azure_ad_token_provider=token_provider,
api_version="2024-10-21"
)
class CalendarEvent(BaseModel):
name: str
date: str
participants: list[str]
completion = client.beta.chat.completions.parse(
model="MODEL_DEPLOYMENT_NAME", # replace with the model deployment name of your gpt-4o 2024-08-06 deployment
messages=[
{"role": "system", "content": "Extract the event information."},
{"role": "user", "content": "Alice and Bob are going to a science fair on Friday."},
],
response_format=CalendarEvent,
)
event = completion.choices[0].message.parsed
print(event)
print(completion.model_dump_json(indent=2))
出力
name='Science Fair' date='Friday' participants=['Alice', 'Bob']
{
"id": "chatcmpl-A1EUP2fAmL4SeB1lVMinwM7I2vcqG",
"choices": [
{
"finish_reason": "stop",
"index": 0,
"logprobs": null,
"message": {
"content": "{\n \"name\": \"Science Fair\",\n \"date\": \"Friday\",\n \"participants\": [\"Alice\", \"Bob\"]\n}",
"refusal": null,
"role": "assistant",
"function_call": null,
"tool_calls": [],
"parsed": {
"name": "Science Fair",
"date": "Friday",
"participants": [
"Alice",
"Bob"
]
}
}
}
],
"created": 1724857389,
"model": "gpt-4o-2024-08-06",
"object": "chat.completion",
"service_tier": null,
"system_fingerprint": "fp_1c2eaec9fe",
"usage": {
"completion_tokens": 27,
"prompt_tokens": 32,
"total_tokens": 59
}
}
構造化出力を使用した関数呼び出し
関数呼び出しでは、1 つのパラメーター strict: true
を指定するだけで構造化出力を有効にできます。
Note
構造化出力は、並列関数呼び出しではサポートされていません。 構造化出力を使用する場合は、parallel_tool_calls
を false
に設定します。
from enum import Enum
from typing import Union
from pydantic import BaseModel
import openai
from openai import AzureOpenAI
client = AzureOpenAI(
azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"),
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
api_version="2024-10-21"
)
class GetDeliveryDate(BaseModel):
order_id: str
tools = [openai.pydantic_function_tool(GetDeliveryDate)]
messages = []
messages.append({"role": "system", "content": "You are a helpful customer support assistant. Use the supplied tools to assist the user."})
messages.append({"role": "user", "content": "Hi, can you tell me the delivery date for my order #12345?"})
response = client.chat.completions.create(
model="MODEL_DEPLOYMENT_NAME", # replace with the model deployment name of your gpt-4o 2024-08-06 deployment
messages=messages,
tools=tools
)
print(response.choices[0].message.tool_calls[0].function)
print(response.model_dump_json(indent=2))
サポートされているスキーマと制限事項
Azure OpenAI の構造化出力では、OpenAI と同じ JSON スキーマのサブセットがサポートされます。
サポートされている型
- String
- 番号
- Boolean
- Integer
- Object
- Array
- 列挙型
- anyOf
Note
ルート オブジェクトを anyOf
型にすることはできません。
すべてのフィールドが必須
すべてのフィールドまたは関数パラメーターを必須として含める必要があります。 次の例では、"required": ["location", "unit"]
で location
と unit
の両方が指定されています。
{
"name": "get_weather",
"description": "Fetches the weather in the given location",
"strict": true,
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The location to get the weather for"
},
"unit": {
"type": "string",
"description": "The unit to return the temperature in",
"enum": ["F", "C"]
}
},
"additionalProperties": false,
"required": ["location", "unit"]
}
必要に応じて、共用体型を null
と使用することで省略可能なパラメーターをエミュレートできます。 この例では、これを行 "type": ["string", "null"],
で達成しています。
{
"name": "get_weather",
"description": "Fetches the weather in the given location",
"strict": true,
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The location to get the weather for"
},
"unit": {
"type": ["string", "null"],
"description": "The unit to return the temperature in",
"enum": ["F", "C"]
}
},
"additionalProperties": false,
"required": [
"location", "unit"
]
}
}
入れ子の深さ
スキーマには、合計で最大 100 個のオブジェクト プロパティを含めることができ、5 レベルまでの入れ子が可能です
オブジェクトで常に additionalProperties: false を設定する必要あり
このプロパティは、JSON スキーマで定義されていない追加のキーと値のペアをオブジェクトに含めることができるかどうかを制御します。 構造化出力を使用するには、この値を false に設定する必要があります。
キーの順序
構造化出力は、指定されたスキーマと同じ順序になります。 出力の順序を変更するには、推論要求の一部として送信するスキーマの順序を変更します。
サポートされていない型固有のキーワード
Type | サポートされていないキーワード |
---|---|
String | minlength maxLength pattern format |
番号 | minimum maximum multipleOf |
Objects | patternProperties unevaluatedProperties propertyNames minProperties maxProperties |
配列 | unevaluatedItems contains minContains maxContains minItems maxItems uniqueItems |
anyOf を使用する入れ子になったスキーマは JSON スキーマのサブセット全体に準拠する必要あり
サポートされている anyOf
スキーマの例:
{
"type": "object",
"properties": {
"item": {
"anyOf": [
{
"type": "object",
"description": "The user object to insert into the database",
"properties": {
"name": {
"type": "string",
"description": "The name of the user"
},
"age": {
"type": "number",
"description": "The age of the user"
}
},
"additionalProperties": false,
"required": [
"name",
"age"
]
},
{
"type": "object",
"description": "The address object to insert into the database",
"properties": {
"number": {
"type": "string",
"description": "The number of the address. Eg. for 123 main st, this would be 123"
},
"street": {
"type": "string",
"description": "The street name. Eg. for 123 main st, this would be main st"
},
"city": {
"type": "string",
"description": "The city of the address"
}
},
"additionalProperties": false,
"required": [
"number",
"street",
"city"
]
}
]
}
},
"additionalProperties": false,
"required": [
"item"
]
}
定義をサポート
サポートされている例:
{
"type": "object",
"properties": {
"steps": {
"type": "array",
"items": {
"$ref": "#/$defs/step"
}
},
"final_answer": {
"type": "string"
}
},
"$defs": {
"step": {
"type": "object",
"properties": {
"explanation": {
"type": "string"
},
"output": {
"type": "string"
}
},
"required": [
"explanation",
"output"
],
"additionalProperties": false
}
},
"required": [
"steps",
"final_answer"
],
"additionalProperties": false
}
再帰スキーマをサポート
ルート再帰に # を使用する例:
{
"name": "ui",
"description": "Dynamically generated UI",
"strict": true,
"schema": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "The type of the UI component",
"enum": ["div", "button", "header", "section", "field", "form"]
},
"label": {
"type": "string",
"description": "The label of the UI component, used for buttons or form fields"
},
"children": {
"type": "array",
"description": "Nested UI components",
"items": {
"$ref": "#"
}
},
"attributes": {
"type": "array",
"description": "Arbitrary attributes for the UI component, suitable for any element",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The name of the attribute, for example onClick or className"
},
"value": {
"type": "string",
"description": "The value of the attribute"
}
},
"additionalProperties": false,
"required": ["name", "value"]
}
}
},
"required": ["type", "label", "children", "attributes"],
"additionalProperties": false
}
}
明示的な再帰の例:
{
"type": "object",
"properties": {
"linked_list": {
"$ref": "#/$defs/linked_list_node"
}
},
"$defs": {
"linked_list_node": {
"type": "object",
"properties": {
"value": {
"type": "number"
},
"next": {
"anyOf": [
{
"$ref": "#/$defs/linked_list_node"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false,
"required": [
"next",
"value"
]
}
},
"additionalProperties": false,
"required": [
"linked_list"
]
}