🐥

Semantic Kernel で JSON Mode を使おう

2024/04/11に公開

Semantic Kernel の v1.1.0 から実験的機能として JSON Mode への対応が追加されています。

https://github.com/microsoft/semantic-kernel/releases/tag/dotnet-1.1.0

最新が 1.7.1 なので結構前の出来事っぽい雰囲気はありますが、実は3か月前に対応が入ったばかりです。バージョンアップ早すぎる…!

JSON Mode でやりたいこと

JSON Mode については、以下の JP さんの記事を参照してください。

https://zenn.dev/microsoft/articles/azure-openai-jsom-mode

JSON Mode で試したいこととしては shyamagu さんの書いてくれた Smart Components の Smart Paste の記事でやっていることをやってみたいと思います。

https://qiita.com/shyamagu/items/23e546f01eadef4ed73b

この記事内では、ユーザーの入力したテキストから JSON のオブジェクトを生成して、それをフォームにバインドすることで Smart Components の Smart Paste の動作を再現しています。

Smart Paste 自体の動きについては、こちらのツイートに添付した gif アニメを参照してください。個人的には好きな AI の活用方法。チャットって入力するのめんどいですしね…。

https://x.com/okazuki/status/1777990873562882333

実装してみよう

ということで、ユーザーの入力した文章から情報を抜き取って JSON に変換する処理を Semantic Kernel で実装してみます。Semantic Kernel 自体の基本的な使い方については、以下のページを参照してください。

https://zenn.dev/microsoft/articles/semantic-kernel-v1-001

https://zenn.dev/microsoft/articles/semantic-kernel-v1-004

やりたいことはシンプルなので、さくっと実装していきます。ポイントは CreateFunctionFromPrompt メソッドの引数で渡している OpenAIPromptExecutionSettingsResponseFormat プロパティを ChatCompletionsResponseFormat.JsonObject に設定することです。ResponseFormat プロパティは Possible values are: "json_object", "text", Azure.AI.OpenAI.ChatCompletionsResponseFormat object. となっているので ChatCompletionsResponseFormat.JsonObject に設定するか "json_object" を設定することで JSON Mode を設定することが出来ます。

渡しているユーザーの入力から名前、年齢、お気に入りのスキル名を抜き取ってほしいといった内容のコードになっています。ユーザーの入力には年齢が記載してある箇所が2か所あるのですが正確に抜き取ってくれるでしょうか…。

こんにちは。
私は田中太郎です。
15個くらいのスキルを持っている18歳の男の子です。
一番のお気に入りのスキルは相手の年齢を強制的に 0 歳にする「原初回帰の童稚神力」です。

コードは以下のようになります。

using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;

var builder = Kernel.CreateBuilder();
builder.AddAzureOpenAIChatCompletion(
    "gpt-35-turbo 1106 のモデルのデプロイ名",
    "https://<<AOAI のリソース名>>.openai.azure.com/",
    // Azure CLI の認証情報を使って AOAI に繋ぐ
    new AzureCliCredential());
var kernel = builder.Build();

string keys = string.Join(',', ["name", "age", "favoriteSkillName"]);
var userInput = """
    こんにちは。
    私は田中太郎です。
    15個くらいのスキルを持っている18歳の男の子です。
    一番のお気に入りのスキルは相手の年齢を強制的に 0 歳にする「原初回帰の童稚神力」です。
    """;

var f = kernel.CreateFunctionFromPrompt(
    promptConfig: new(userInput)
    {
        ExecutionSettings = new()
        {
            [PromptExecutionSettings.DefaultServiceId] = new OpenAIPromptExecutionSettings()
            {
                ChatSystemPrompt = $"""
                あなたは JSON のジェネレーターです。入力されたテキストから以下のキーを持つ JSON オブジェクトを生成してください。
                
                ## キー
                {keys}                
                """,
#pragma warning disable SKEXP0010
                ResponseFormat = ChatCompletionsResponseFormat.JsonObject,
#pragma warning restore SKEXP0010            
            }
        }
    });

var res = await f.InvokeAsync(kernel);
Console.WriteLine(res.GetValue<string>());

実行すると以下のような結果になりました。

{
  "name": "田中太郎",
  "age": 18,
  "favoriteSkillName": "原初回帰の童稚神力"
}

ちゃんと年齢は18歳でスキル名もばっちりですね!ちなみにこのスキル名は相手の年齢を0歳にする中二病っぽいスキル名を考えてくださいと依頼して作ってもらいました。

まとめ

ということで、Semantic Kernel で JSON Mode を使う方法を試してみました。これを .NET 製のアプリに組み込むことで、shyamagu さんと同じ方式で Smart Paste みたいな動きをする画面が作れそうですね。

Microsoft (有志)

Discussion