共用方式為


結構化輸出

結構化輸出會讓模型遵循您在推斷 API 呼叫中提供的 JSON 結構描述定義。 這與較舊的 JSON 模式功能相反,該功能保證會產生有效的 JSON,但無法確保嚴格遵循提供的結構描述。 建議使用結構化輸出來呼叫函式、擷取結構化資料,以及組建複雜的多步驟工作流程。

注意

支援的模型

  • 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

開始使用

您可以使用 Pydantic 以 Python 定義物件結構描述。 根據您執行的 OpenAIPydantic 程式庫版本而定,您可能需要升級至較新版本。 這些範例是針對 openai 1.42.0pydantic 2.8.2 進行測試。

pip install openai pydantic --upgrade

如果您不熟悉使用 Microsoft Entra ID 進行驗證,請參閱 如何使用 Microsoft Entra ID 驗證來設定 Azure OpenAI 服務。

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

透過結構化輸出呼叫函式

可以透過提供 strict: true,使用單一參數來允許結構化輸出用於函式呼叫。

注意

平行函式呼叫不支援結構化輸出。 當使用結構化輸出時,將 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
  • 數值
  • 布林值
  • 整數
  • Object
  • 陣列
  • 列舉
  • anyOf

注意

根物件不能是 anyOf 類型。

所有欄位都必須是必要項目

所有欄位或函式參數都必須納入必要項目。 在下列範例中,locationunit 都是在 "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"]
    }

如有需要,可以使用具有 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 個物件屬性,最多五個巢狀項目層級

一律必須在物件中設定 additionalProperties: false

此屬性控制物件是否可以擁有在 JSON 結構描述中未定義的額外索引鍵/值組。 若要使用結構化輸出,您必須將此值設定為 false。

索引鍵排序

結構化輸出的排序方式與提供的結構描述相同。 若要變更輸出順序,請修改您在推斷要求中傳送的結構描述順序。

不支援的類型專屬關鍵字

類型 不支援的關鍵字
String minlength
maxLength
pattern
format
數字 minimum
maximum
multipleOf
物件 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"
	]
}