Sdílet prostřednictvím


Strukturované výstupy

Strukturované výstupy tvoří model podle definice schématu JSON, kterou zadáte jako součást volání rozhraní API pro odvozování. To je na rozdíl od starší funkce režimu JSON, která zaručuje, že se vygeneruje platný JSON, ale nepodařilo se zajistit striktní dodržování zadaného schématu. Strukturované výstupy se doporučují pro volání funkcí, extrakci strukturovaných dat a vytváření složitých pracovních postupů s více kroky.

Poznámka:

Aktuálně strukturované výstupy nejsou podporovány s:

Podporované modely

  • o3-mini verze 2025-01-31
  • o1 verze: 2024-12-17
  • gpt-4o-mini verze: 2024-07-18
  • gpt-4o verze: 2024-08-06

Podpora rozhraní API

Podpora strukturovaných výstupů byla poprvé přidána ve verzi 2024-08-01-previewrozhraní API . Je k dispozici v nejnovějších rozhraních API verze Preview a také v nejnovějším rozhraní GA API: 2024-10-21.

Začínáme

Můžete použít Pydantic k definování schémat objektů v Pythonu. V závislosti na verzi OpenAI a Pydantic knihoven , které používáte, možná budete muset upgradovat na novější verzi. Tyto příklady byly testovány proti openai 1.42.0 a pydantic 2.8.2.

pip install openai pydantic --upgrade

Pokud s ověřováním začínáte používat Microsoft Entra ID, přečtěte si téma Konfigurace služby Azure OpenAI s ověřováním Microsoft Entra ID.

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))

Výstup

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
  }
}

Volání funkcí se strukturovanými výstupy

Strukturované výstupy pro volání funkce lze povolit jedním parametrem zadáním strict: true.

Poznámka:

Strukturované výstupy nejsou podporovány při paralelních voláních funkcí. Při použití strukturovaných výstupů nastavených parallel_tool_calls na falsehodnotu .

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))

Podporovaná schémata a omezení

Strukturované výstupy Azure OpenAI podporují stejnou podmnožinu schématu JSON jako OpenAI.

Podporované typy

  • String
  • Číslo
  • Logická hodnota
  • Celé číslo
  • Objekt
  • Pole
  • Výčet
  • anyOf

Poznámka:

Kořenovými objekty nemůže být anyOf typ.

Všechna pole musí být povinná.

Všechna pole nebo parametry funkce musí být zahrnuta podle potřeby. V následujícím locationpříkladu a unit jsou uvedeny v části "required": ["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"]
    }

V případě potřeby je možné emulovat volitelný parametr pomocí sjednocovacího typu s nullpříponou . V tomto příkladu toho dosáhnete pomocí čáry "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"
        ]
    }
}

Hloubka vnoření

Schéma může mít celkem až 100 vlastností objektu s až pěti úrovněmi vnoření.

additionalProperties: False musí být vždy nastaven v objektech.

Tato vlastnost určuje, jestli objekt může mít další páry klíč-hodnota, které nebyly definovány ve schématu JSON. Chcete-li použít strukturované výstupy, musíte tuto hodnotu nastavit na false.

Řazení klíčů

Strukturované výstupy jsou seřazené stejně jako zadané schéma. Pokud chcete změnit pořadí výstupu, upravte pořadí schématu, které odešlete jako součást požadavku na odvozování.

Nepodporovaná klíčová slova specifická pro typ

Typ Nepodporované klíčové slovo
String minlength
maxLength
vzor
format
Počet minimální
maximum
multipleOf
Objekty patternProperties
unevaluatedProperties
propertyNames
minProperties
maxProperties
Pole unevaluatedItems
obsahuje
minContains
maxContains
minItems
maxItems
uniqueItems

Vnořené schémata používající anyOf musí dodržovat celkovou podmnožinu schématu JSON.

Příklad podporovaného anyOf schématu:

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

Podporují se definice.

Podporovaný příklad:

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

Podporují se rekurzivní schémata.

Příklad použití # pro kořenovou rekurzi:

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

Příklad explicitní rekurze:

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