0
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?

Semantic Kernel:Function Calling

Posted at

    前回のFunctionにおいて、開発者が構成した順番で、セマンティックFunctionとローカルFunctionをそれぞれ呼び出す混合方式を使用しました。

    実際には、Semantic Kernel(SK)は自動で組織化できます。以下で定義されているローカルFunction「GetChineseDay」を「ImportPluginFromFunctions」方式でSKのプラグインライブラリに追加します。「Call1」で「今月餅を食べるのまで何日ありますか?」と質問されると、GetChineseDayが自動的に呼び出されます。しかし、質問が「1=1=?」のように日付と無関係な場合、ローカルFunctionはトリガーされません。注意すべき設定は「var settings = new OpenAIPromptExecutionSettings() { ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions };」です。

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using System;
using System.Globalization;
using System.Text;
#pragma warning disable SKEXP0001

var chatModelId = "gpt-4o";
var key = File.ReadAllText(@"C:\GPT\key.txt");

var builder = Kernel.CreateBuilder();
builder.AddOpenAIChatCompletion(chatModelId, key);
Kernel kernel = builder.Build();
kernel.ImportPluginFromFunctions("HelperFunctions",
[
    kernel.CreateFunctionFromMethod(GetChineseDay, "GetChineseDay", "返回中国的农历")
]);

await Call1();

async Task Call1()
{
    Console.WriteLine("-----------------Call1 開始---------------------");
    var settings = new OpenAIPromptExecutionSettings() { ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions };
    await foreach (var content in kernel.InvokePromptStreamingAsync("现在离吃月饼还有多少天?", new(settings)))
    {
        Console.Write(content);
    }
    Console.WriteLine();
    Console.WriteLine("-----------------Call1 終了---------------------");
}

string GetChineseDay()
{
    var chineseCalendar = new ChineseLunisolarCalendar();
    var today = DateTime.Now;
    int lunarYear = chineseCalendar.GetYear(today);
    int lunarMonth = chineseCalendar.GetMonth(today);
    int lunarDay = chineseCalendar.GetDayOfMonth(today);
    bool isLeapMonth = chineseCalendar.IsLeapMonth(lunarYear, lunarMonth);
    Console.WriteLine("-------GetChineseDay--------");
    return $"农历日期: {lunarYear}{(isLeapMonth ? "闰" : "")}{lunarMonth}{lunarDay}日";
}
Console.WriteLine();

実行結果は次のとおり:

画像

チャットでFunction Callingを使用するには?

await Call2();

async Task Call2()
{
    Console.WriteLine("-----------------Call2 開始---------------------");
    var settings = new OpenAIPromptExecutionSettings() { ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions };
    var chat = kernel.GetRequiredService<IChatCompletionService>();
    var chatHistory = new ChatHistory("中国农历的表示方式是:九月初三,十二月二十三,请用这种表示方式表示农历日期。");
    chatHistory.AddUserMessage("现在离吃月饼还有多少天?");
    var contentBuilder = new StringBuilder();
    await foreach (var streamingContent in chat.GetStreamingChatMessageContentsAsync(chatHistory, settings, kernel))
    {
        if (streamingContent.Content is not null)
        {
            Console.Write(streamingContent.Content);
            contentBuilder.Append(streamingContent.Content);
        }
    }
    chatHistory.AddAssistantMessage(contentBuilder.ToString());
    Console.WriteLine();
    Console.WriteLine("-----------------Call2 終了---------------------");
}

実行結果は次のとおり:

画像

FunctionCallContentBuilderを用いて、呼び出されたローカルFunctionを確認するには?

await Call3();

async Task Call3()
{
    Console.WriteLine("-----------------Call4 開始---------------------");
    IChatCompletionService chat = kernel.GetRequiredService<IChatCompletionService>();
    OpenAIPromptExecutionSettings settings = new() { ToolCallBehavior = ToolCallBehavior.EnableKernelFunctions };
    ChatHistory chatHistory = new();
    chatHistory.AddUserMessage("中秋节吃月饼,现在离吃月饼还有多少天?");
    while (true)
    {
        AuthorRole? authorRole = null;
        var fccBuilder = new FunctionCallContentBuilder();
        await foreach (var streamingContent in chat.GetStreamingChatMessageContentsAsync(chatHistory, settings, kernel))
        {
            if (streamingContent.Content is not null)
            {
                Console.Write(streamingContent.Content);
            }
            authorRole ??= streamingContent.Role;
            fccBuilder.Append(streamingContent);
        }
        Console.WriteLine();
        var functionCalls = fccBuilder.Build();
        if (!functionCalls.Any())
        {
            break;
        }
        var fcContent = new ChatMessageContent(role: authorRole ?? default, content: null);
        chatHistory.Add(fcContent);

        foreach (var functionCall in functionCalls)
        {
            fcContent.Items.Add(functionCall);
            var functionResult = await functionCall.InvokeAsync(kernel);
            Console.WriteLine($"FunctionName:{functionResult.FunctionName},Return:{functionResult.InnerContent}");
            chatHistory.Add(functionResult.ToChatMessage());
        }
        Console.WriteLine();
    }
    Console.WriteLine();
    Console.WriteLine("-----------------Call4 終了---------------------");
}

実行結果:

画像

(Translated by GPT)

0
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
0
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?