すべて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)
{
//任意のエラー処理
}
}
}