🔥

Semantic KernelのFunctionを自動的に選択して回答を返す

2023/12/09に公開

始めに

https://zenn.dev/tomokusaba/articles/0f84acd5352d1b

昨日書いた例だとFunctionが1つだけだったのでこの書き方の優位性があまり分からなかったのではないかとおもいSementic KernelがFunctionを自動的に選んで最適な結果を返す(これも使用しているAIモデルによって選択しているわけですが)ことのデモを紹介したいと思います。

前提

Sementic Kernel 1.0.0-rc3
.NET 8

プラグインのクラス

以下のようにプラグインクラスを作成しておきました。

Plugin.cs
using Microsoft.SemanticKernel;
using System.ComponentModel;

public class Plugin
{
    private readonly HttpClient _client = new();

    [KernelFunction, Description("今日の日付を返す")]
    public static string Today()
    {
        return DateTime.Now.ToString("yyyy/MM/dd");
    }

    [KernelFunction, Description("今日の曜日を返す")]
    public static string DayOfWeek()
    {
        return DateTime.Now.ToString("dddd");
    }

    [KernelFunction, Description("今の時間を返す")]
    public static string Now()
    {
        return DateTime.Now.ToString("HH:mm:ss");
    }

    [KernelFunction, Description("東京の天気を返す")]
    public async Task<string> Weather()
    {
        return (await _client.GetAsync("https://www.jma.go.jp/bosai/forecast/data/forecast/130000.json")).Content.ReadAsStringAsync().Result;
    }
}

呼び出し側

次に呼び出し側として以下のようにしました。
好みに合わせてマネージド認証でOpenAIServiceを使用してもよいでしょう。

Program.cs
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.AI.OpenAI;

KernelBuilder builder = new();
builder.Services.AddAzureOpenAIChatCompletion(
    "デプロイ名",
    "モデル名",
    "エンドポイント", 
    "APIキー");
builder.Plugins.AddFromType<Plugin>();

Kernel kernel = builder.Build();
OpenAIPromptExecutionSettings? setting = new()
{
    FunctionCallBehavior = FunctionCallBehavior.AutoInvokeKernelFunctions
};

while (true)
{
    Console.Write("User > ");
    string input = Console.ReadLine()!;
    if (input == "exit")
    {
        break;
    }
    else
    {
        var result = await kernel.InvokePromptAsync(input, new(setting));
        Console.WriteLine($"Assistant > {result}");
    }
}

実行結果

このようにして実行したところ以下のようになりました。

ユーザーから受け取った質問文に対して適切なFunctionを選択して回答をしているということが分かるかとおもいます。
また、Pluginを使用しない場合は「今何時?」といった質問にはもちろん答えることはできません。

このようなことから、Functionに書かれた説明文をもとに適切なFunctionを選択して回答をする便利な方法と言えるでしょう。
また、これだけのコードでそれが実現できていることが素晴らしいと思います。

https://github.com/tomokusaba/SKAutoFunctions

Discussion