次の方法で共有


構造化出力

構造化出力を使用すると、推論 API 呼び出しの一部として指定した JSON スキーマ定義にモデルが従うようになります。 これは、有効な JSON が生成されることは保証されていたものの指定されたスキーマに厳密に準拠させることはできなかった以前の JSON モード機能とは対照的です。 構造化出力は、関数の呼び出し、構造化データの抽出、複雑な複数ステップ ワークフローの構築に推奨されます。

Note

サポートされているモデル

  • 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.0pydantic 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_callsfalse に設定します。

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"]locationunit の両方が指定されています。

{
    "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"
	]
}