次の方法で共有


構造化出力

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

注記

現在、構造化出力は次ではサポートされていません:

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

  • codex-mini バージョン 2025-05-16
  • o3-pro バージョン 2025-06-10
  • gpt-4.5-preview バージョン 2025-02-27
  • o3-mini バージョン 2025-01-31
  • o1 のバージョン: 2024-12-17
  • gpt-4o-mini のバージョン: 2024-07-18
  • gpt-4o のバージョン: 2024-08-06
  • gpt-4o のバージョン: 2024-11-20
  • gpt-4.1 バージョン 2025-04-14
  • gpt-4.1-nano バージョン 2025-04-14
  • gpt-4.1-mini のバージョン: 2025-04-14
  • o4-mini のバージョン: 2025-04-16
  • o3 のバージョン: 2025-04-16

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 AI Foundry Models で Azure OpenAI を構成する方法」を参照してください。

import os
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 を指定するだけで構造化出力を有効にできます。

注記

構造化出力は、並列関数呼び出しではサポートされていません。 構造化出力を使用する場合は、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 で使用するために、次のパッケージをご利用のプロジェクトに追加します。

  • Azure.AI.OpenAI: 標準の OpenAI ライブラリの依存関係に基づいて構築される Azure 固有の機能を Azure OpenAI クライアントに提供します。
  • Azure.Identity: Azure SDK ライブラリ全体で Microsoft Entra ID トークン認証のサポートを提供します。
  • Newtonsoft.Json.Schema: JSON スキーマを操作するための便利なユーティリティを提供します。
dotnet add package Azure.AI.OpenAI --prerelease
dotnet add package Azure.Identity
dotnet add package Newtonsoft.Json.Schema

認証に Microsoft Entra ID を初めて使用する場合は、「Microsoft Entra ID 認証を使用して Azure AI Foundry Models で Azure OpenAI を構成する方法」を参照してください。

using Azure.AI.OpenAI;
using Azure.Identity;
using Newtonsoft.Json.Schema.Generation;
using OpenAI.Chat;
using System.ClientModel;

// Create the clients
string endpoint = GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT");

AzureOpenAIClient openAIClient = new(
    new Uri(endpoint),
    new DefaultAzureCredential());

var client = openAIClient.GetChatClient("gpt-4o");

// Create a chat with initial prompts
var chat = new List<ChatMessage>()
    {
         new SystemChatMessage("Extract the event information and projected weather."),
         new UserChatMessage("Alice and Bob are going to a science fair in Seattle on June 1st, 2025.")
    };

// Get the schema of the class for the structured response
JSchemaGenerator generator = new JSchemaGenerator();
var jsonSchema = generator.Generate(typeof(CalendarEvent)).ToString();

// Get a completion with structured output
var chatUpdates = client.CompleteChatStreamingAsync(
        chat,
        new ChatCompletionOptions()
        {
            ResponseFormat = ChatResponseFormat.CreateJsonSchemaFormat(
                        "calenderEvent",
                        BinaryData.FromString(jsonSchema))
        });

// Write the structured response
await foreach (var chatUpdate in chatUpdates)
{
    foreach (var contentPart in chatUpdate.ContentUpdate)
    {
        Console.Write(contentPart.Text);
    }
}

// The class for the structured response
public class CalendarEvent()
{
    public string Name { get; set; }
    public string Date { get; set; }
    public List<string> Participants { get; set; }
}

構造化出力を使用した関数呼び出し

関数呼び出しでは、1 つのパラメーター strict: true を指定するだけで構造化出力を有効にできます。

using Azure.AI.OpenAI;
using Newtonsoft.Json.Schema.Generation;
using OpenAI.Chat;
using System.ClientModel;

// Create the clients
string endpoint = GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT");

AzureOpenAIClient openAIClient = new(
    new Uri(endpoint),
    new DefaultAzureCredential());

var chatClient = openAIClient.GetChatClient("gpt-4o");

// Local function to be used by the assistant tooling
string GetTemperature(string ___location, string date)
{
    // Placeholder for Weather API
    if(___location == "Seattle" && date == "2025-06-01")
    {
        return "75";
    }

    return "50";
}

// Create a tool to get the temperature
ChatTool GetTemperatureTool = ChatTool.CreateFunctionTool(
    functionName: nameof(GetTemperature),
    functionSchemaIsStrict: true,
    functionDescription: "Get the projected temperature by date and ___location.",
    functionParameters: BinaryData.FromBytes("""
        {
            "type": "object",
            "properties": {
                "___location": {
                    "type": "string",
                    "description": "The ___location of the weather."
                },
                "date": {
                    "type": "string",
                    "description": "The date of the projected weather."
                }
            },
            "required": ["___location", "date"],
            "additionalProperties": false  
        }
        """u8.ToArray())
);

// Create a chat with prompts
var chat = new List<ChatMessage>()
    {
         new SystemChatMessage("Extract the event information and projected weather."),
         new UserChatMessage("Alice and Bob are going to a science fair in Seattle on June 1st, 2025.")
    };

// Create a JSON schema for the CalendarEvent structured response
JSchemaGenerator generator = new JSchemaGenerator();
var jsonSchema = generator.Generate(typeof(CalendarEvent)).ToString();

// Get a chat completion from the AI model
var completion = chatClient.CompleteChat(
        chat,
        new ChatCompletionOptions()
        {
            ResponseFormat = ChatResponseFormat.CreateJsonSchemaFormat(
                "calenderEvent",
                BinaryData.FromString(jsonSchema)),
            Tools = { GetTemperatureTool }
        });

Console.WriteLine(completion.Value.ToolCalls[0].FunctionName);

// Structured response class
public class CalendarEvent()
{
    public string Name { get; set; }
    public string Date { get; set; }
    public string Temperature { get; set; }
    public List<string> Participants { get; set; }
}

作業の開始

response_formatjson_schema に設定し、strict: true を設定します。

curl -X POST  https://YOUR_RESOURCE_NAME.openai.azure.com/openai/deployments/YOUR_MODEL_DEPLOYMENT_NAME/chat/completions?api-version=2024-10-21 \
  -H "api-key: $AZURE_OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
    -d '{
        "messages": [
                {"role": "system", "content": "Extract the event information."},
                {"role": "user", "content": "Alice and Bob are going to a science fair on Friday."}
            ],
            "response_format": {
                "type": "json_schema",
                "json_schema": {
                    "name": "CalendarEventResponse",
                    "strict": true,
                    "schema": {
                        "type": "object",
                        "properties": {
                            "name": {
                              "type": "string"
                            },
                            "date": {
                                "type": "string"
                            },
                            "participants": {
                                "type": "array",
                                "items": {
                                    "type": "string"
                                }
                            }
                        },
                        "required": [
                            "name",
                            "date",
                            "participants"
                        ],
                        "additionalProperties": false
                    }
                }
          }
  }'

出力:

{
  "id": "chatcmpl-A1HKsHAe2hH9MEooYslRn9UmEwsag",
  "object": "chat.completion",
  "created": 1724868330,
  "model": "gpt-4o-2024-08-06",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "{\n  \"name\": \"Science Fair\",\n  \"date\": \"Friday\",\n  \"participants\": [\"Alice\", \"Bob\"]\n}"
      },
      "logprobs": null,
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 33,
    "completion_tokens": 27,
    "total_tokens": 60
  },
  "system_fingerprint": "fp_1c2eaec9fe"
}

構造化出力を使用した関数呼び出し

curl -X POST  https://YOUR_RESOURCE_NAME.openai.azure.com/openai/deployments/YOUR_MODEL_DEPLOYMENT_NAME/chat/completions?api-version=2024-10-21 \
  -H "api-key: $AZURE_OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "messages": [
    {
      "role": "system",
      "content": "You are a helpful assistant. The current date is August 6, 2024. You help users query for the data they are looking for by calling the query function."
    },
    {
      "role": "user",
      "content": "look up all my orders in may of last year that were fulfilled but not delivered on time"
    }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "query",
        "description": "Execute a query.",
        "strict": true,
        "parameters": {
          "type": "object",
          "properties": {
            "table_name": {
              "type": "string",
              "enum": ["orders"]
            },
            "columns": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "id",
                  "status",
                  "expected_delivery_date",
                  "delivered_at",
                  "shipped_at",
                  "ordered_at",
                  "canceled_at"
                ]
              }
            },
            "conditions": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "column": {
                    "type": "string"
                  },
                  "operator": {
                    "type": "string",
                    "enum": ["=", ">", "<", ">=", "<=", "!="]
                  },
                  "value": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "number"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "column_name": {
                            "type": "string"
                          }
                        },
                        "required": ["column_name"],
                        "additionalProperties": false
                      }
                    ]
                  }
                },
                "required": ["column", "operator", "value"],
                "additionalProperties": false
              }
            },
            "order_by": {
              "type": "string",
              "enum": ["asc", "desc"]
            }
          },
          "required": ["table_name", "columns", "conditions", "order_by"],
          "additionalProperties": false
        }
      }
    }
  ]
}'

サポートされているスキーマと制限事項

Azure OpenAI 構造化出力では、OpenAI と同じ JSON スキーマ のサブセットがサポートされます。

サポートされている型

  • Number
  • ボーリアン
  • 整数
  • オブジェクト
  • Array
  • 列挙型
  • 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 個のオブジェクト プロパティを含めることができ、5 レベルまでの入れ子が可能です

オブジェクトで常に additionalProperties: false を設定する必要あり

このプロパティは、JSON スキーマで定義されていない追加のキーと値のペアをオブジェクトに含めることができるかどうかを制御します。 構造化出力を使用するには、この値を false に設定する必要があります。

キーの順序

構造化出力は、指定されたスキーマと同じ順序になります。 出力の順序を変更するには、推論要求の一部として送信するスキーマの順序を変更します。

サポートされていない型固有のキーワード

タイプ サポートされていないキーワード
minlength
最大長さ
パターン
フォーマット
Number minimum
maximum
multipleOf
オブジェクト パターンプロパティーズ
未評価のプロパティ
propertyNames
minProperties
maxProperties
配列 未評価の項目
contains
minContains
maxContains
minItems
maxItems
ユニークな項目

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