発売時期的に Azure OpenAI Service の API を直接使っている「Azure OpenAI Service入門」ではありますが、同じことは Semantic Kernelを使って書き換えることが可能です。
もともと、Semantic Kernel は Python の LangChain の .NET版(主にC#ではありますが)なところがあって、生成AIのモデルを問わない形になっています。出版時には、OpenAI社の GPTシリーズが主流であったためのこれに揃えて Azure OpenAI Serviceを活用しているのですが、現在では Google の Gemini など他の生成AIのモデルもあり、同じプログラムでもモデルを切り替えられるのは便利…とは思うんですがどうなんでしょう?
ひとまず、APIとしてはどのAIモデルもAPIをJSON形式で呼び出すようになっているので、そのフォーマットを切り替えるだけで概ねいけそうです。違いとしては、Calling Functionのように他システムと組み合わせたいときのプレ処理・ポスト処理に係る部分でしょう。属にいうRAG(検索拡張生成)と呼ばれる部分です。「RAG」というとちょっと難しい感じもしますが、要するの画像処理のプレ処理やポスト処理にあたります。画像処理を行うときに、プレ処理として2値化やグレー処理、エンボス処理などを行いますが、それと似たような形でテキスト解釈をGPTのAPIに任せて関数をコールバックさせることができます。私の場合、GPTシリーズでしかやったことがないのですが、Gemini などの他の生成AIでも同じことができるでしょう(未確認)。
まずは簡単なところから
簡単なところで、第7章のコードを書き直してみましょう。
Microsoft.SemanticKernel パッケージを追加する
Semantic Kernel はパッケージ「Microsoft.SemanticKernel」を使うので、*.csproj を以下に書き換えます。
<ItemGroup>
<PackageReference Include="Microsoft.SemanticKernel" Version="1.14.1" />
</ItemGroup>
現在のところ最新版は ver.1.14.1 になります。
実は、Microsoft.SemanticKernelパッケージは、Azure.AI.OpenAI パッケージに依存しています。なので書籍で書いたAzure.AI.OpenAIパッケージのもそのままで動くし、Semantic Kernel で書き直したものも動きます。ちなみに、Azure.AI.OpenAI パッケージは beta 版のまま ver.2 に移行しているので、ver.1 はリリース版はない…と見るんでしょうね。やっぱり(苦笑)

従来の Completion(入力候補)を呼び出す
おそらく従来型のCompletion(プロンプトから1回だけ呼び出すもの)の方法を先に示します。
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
var builder = Kernel.CreateBuilder();
builder.AddAzureOpenAIChatCompletion(
"test-x",
"https://sample-moonmile-openai.openai.azure.com/",
Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY") ?? "");
var kernel = builder.Build();
最初の Kernel 部分(従来の OpenAIClientに当たるところ)を Builder パターンで作成します。
- CreateBuilder でビルダーを作成
- AddAzureOpenAIChatCompletion でチャット/入力候補用の設定を追加
- Build メソッドで Kernel を作成
という手順です。ここでの「test-x」は、Azure OpenAI Studio で作成したデプロイ名です。
var kernel_args = new KernelArguments(
new OpenAIPromptExecutionSettings()
{
Temperature = (float)0.5,
MaxTokens = 800,
TopP = (float)0.95,
FrequencyPenalty = 0,
PresencePenalty = 0,
});
温度や最大トークンなどは、OpenAIPromptExecutionSettings で作成します。先に作成した Kernel に渡すために、KernelArguments でくるんでおきます。このあたり、KernelArguments 内で色々と切り替える(プロンプトテンプレートとか)のですが、ひとまず OpenAI のチャットか入力候補を試したいときはこれで十分です。
Console.WriteLine("通常のプロンプト") ;
var result = await kernel.InvokePromptAsync(
"""
Azure OpenAIについて詳しく説明してください。
""",
kernel_args
);
Console.WriteLine(result.GetValue<string>());
InvokePromptAsync でプロンプトを呼び出します。
各種パラメータがデフォルト値のままでいい場合は、kernel_args は追加しなくて構いません。応答は、GetValue で string 型にキャストしています。
結果
stream で出しているわけではないので応答が長いのですが、こんな感じで AI から応答が返ってきます。

文章が途中で途切れてしまっているのは、トークン数を800に制限したためで、チャット型式にして「続き」のように要求するか、最大トークン数をもう少し大きめにしておきます。
このあたりの詳しいところは書籍の第7章に書いてあります。
サンプルコードはこちら。ブランチを SemanticKernel にして取得してください。
https://github.com/moonmile/openai-samples/tree/SemanticKernel