Delen via


Gestructureerde uitvoer

Gestructureerde uitvoer maakt een model volgens een JSON-schemadefinitie die u opgeeft als onderdeel van uw deductie-API-aanroep. Dit is in tegenstelling tot de oudere JSON-modusfunctie , die gegarandeerde geldige JSON zou genereren, maar niet in staat was om strikte naleving van het opgegeven schema te garanderen. Gestructureerde uitvoer wordt aanbevolen voor het aanroepen van functies, het extraheren van gestructureerde gegevens en het bouwen van complexe werkstromen met meerdere stappen.

Notitie

Ondersteunde modellen

  • o1 Versie: 2024-12-17
  • gpt-4o-mini Versie: 2024-07-18
  • gpt-4o Versie: 2024-08-06

API-ondersteuning

Ondersteuning voor gestructureerde uitvoer is voor het eerst toegevoegd in api-versie 2024-08-01-preview. Deze is beschikbaar in de nieuwste preview-API's en de nieuwste GA-API: 2024-10-21.

Aan de slag

U kunt objectschema's Pydantic definiëren in Python. Afhankelijk van de versie van de OpenAI en Pydantic bibliotheken die u gebruikt, moet u mogelijk een upgrade uitvoeren naar een nieuwere versie. Deze voorbeelden zijn getest tegen openai 1.42.0 en pydantic 2.8.2.

pip install openai pydantic --upgrade

Als u geen toegang hebt tot Microsoft Entra ID voor verificatie, raadpleegt u Hoe u de Azure OpenAI-service configureert met Microsoft Entra ID-verificatie.

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

Uitvoer

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

Functie aanroepen met gestructureerde uitvoer

Gestructureerde uitvoer voor functieaanroepen kan worden ingeschakeld met één parameter door het opgeven strict: truevan .

Notitie

Gestructureerde uitvoer wordt niet ondersteund met parallelle functie-aanroepen. Wanneer u gestructureerde uitvoer gebruikt, ingesteld parallel_tool_calls op 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))

Ondersteunde schema's en beperkingen

Gestructureerde Uitvoer van Azure OpenAI ondersteunt dezelfde subset van het JSON-schema als OpenAI.

Ondersteunde typen

  • String
  • Aantal
  • Booleaans
  • Geheel getal
  • Object
  • Matrix
  • Enum
  • anyOf

Notitie

Hoofdobjecten kunnen niet het anyOf type zijn.

Alle velden moeten vereist zijn

Alle velden of functieparameters moeten worden opgenomen zoals vereist. In het onderstaande locationvoorbeeld worden unit beide opgegeven onder "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"]
    }

Indien nodig is het mogelijk om een optionele parameter te emuleren met behulp van een samenvoegtype met null. In dit voorbeeld wordt dit bereikt met de regel "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"
        ]
    }
}

Diepte nesten

Een schema kan maximaal 100 objecteigenschappen bevatten, met maximaal vijf geneste niveaus

additionalProperties: false moet altijd worden ingesteld in objecten

Deze eigenschap bepaalt of een object extra sleutel-waardeparen kan hebben die niet zijn gedefinieerd in het JSON-schema. Als u gestructureerde uitvoer wilt gebruiken, moet u deze waarde instellen op false.

Sleutelvolgorde

Gestructureerde uitvoer wordt op dezelfde volgorde gerangschikt als het opgegeven schema. Als u de uitvoervolgorde wilt wijzigen, wijzigt u de volgorde van het schema dat u verzendt als onderdeel van uw deductieaanvraag.

Niet-ondersteunde typespecifieke trefwoorden

Type Niet-ondersteund trefwoord
String minlength
maxLength
pattern
indeling
Aantal minimum
maximum
multipleOf
Objecten patternProperties
niet-geëvalueerdeProperties
propertyNames
minProperties
maxProperties
Matrices niet-geëvalueerdItems
Bevat
minContains
maxContains
minItems
maxItems
uniqueItems

Geneste schema's die anyOf gebruiken, moeten voldoen aan de algemene subset van het JSON-schema

Voorbeeld van een ondersteund anyOf schema:

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

Definities worden ondersteund

Ondersteund voorbeeld:

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

Recursieve schema's worden ondersteund

Voorbeeld van het gebruik van # voor hoofdrecursie:

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

Voorbeeld van expliciete recursie:

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