2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

C#でAzureOpenAIから構造化出力で応答させる

Last updated at Posted at 2025-10-27

すべてJSONで書いてAPIにリクエストボディで渡すこともできるが、
せっかくC#でやっているなら型(モデル)からスキーマを生成したい!
と思い備忘のため投稿します。

コードの可読性・メンテナンス性も上がっている……はず😎


💡 使用パッケージ

パッケージ名 バージョン
Azure.AI.OpenAI 2.1.0
OpenAI 2.1.0
NJsonSchema 11.4.0
NJsonSchema.NewtonsoftJson 11.4.0

🧩 実装コード

class AiFoundryHelper//任意のクラス名
{
    private Azure.AI.OpenAI.AzureOpenAIClient OpenAIClient { get; set; }

    public AiFoundryHelper()
    {
        // クライアントの初期化
        string apiKey = ConfigurationManager.AppSettings["AiFoudryApiKey"];
        string endPoint = ConfigurationManager.AppSettings["AiFoundryUrl"];
        this.OpenAIClient = new Azure.AI.OpenAI.AzureOpenAIClient(
            new Uri(endPoint),
            new System.ClientModel.ApiKeyCredential(apiKey)
        );
    }

    // ジェネリックなラッパークラス
    private class ResultWrapper<U>
    {
        public U Result { get; set; }
    }

    /// <summary>
    /// 型をスキーマ化。
    /// 複数クラスを指定して、いずれかの型で返してほしい場合は oneOf を使用する必要があります。
    /// </summary>
    private static JsonSchema ConvertToSchema(Type type)
    {
        var settings = new NewtonsoftJsonSchemaGeneratorSettings
        {
            FlattenInheritanceHierarchy = true,
            DefaultReferenceTypeNullHandling = ReferenceTypeNullHandling.NotNull,
            SchemaType = SchemaType.OpenApi3
        };
        var generator = new JsonSchemaGenerator(settings);

        var schemaType = typeof(ResultWrapper<>).MakeGenericType(type);

        return generator.Generate(schemaType);
    }

    public async Task<YourModel> ChatWithAzureOpenAi(string query)
    {
        var messages = new List<OpenAI.Chat.ChatMessage>();
        messages.Add(new OpenAI.Chat.SystemChatMessage(query));

        var completionOptions = new OpenAI.Chat.ChatCompletionOptions();
        completionOptions.Temperature = (float?)0.1;
        completionOptions.ResponseFormat = OpenAI.Chat.ChatResponseFormat.CreateJsonSchemaFormat(
            "YourModelName",
            BinaryData.FromString(ConvertToSchema(typeof(YourModel)).ToJson())
        ); //YourModelを別途定義すればその型で応答をもらえる設定


        try
        {
            var completionJson = await OpenAIClient
                .GetChatClient("AzureOpenAIにデプロイしたモデル名")
                .CompleteChatAsync(messages.ToArray(), completionOptions);

            return JsonConvert
                .DeserializeObject<ResultWrapper<VisionOcrResultModel>>(
                    completionJson.Value.Content.First().Text
                ).Result;
        }
        catch (Exception e)
        {
            //任意のエラー処理
        }
    }
}
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?