Semantic Kernel：Plugins

プラグインは、セマンティックカーネルのコアコンポーネントです。プラグインを通じて、既存のAPIを一つのコレクションとしてラップし、AIが呼び出せるようにすることで、AIに本来実行できない操作能力を与えます。

セマンティックカーネルは、最新の大規模言語モデル（LLM）におけるネイティブ機能である「関数呼び出し（Function Calling）」を利用して、LLMがAPIをプランニングし呼び出すのを支援します。関数呼び出しを介し、LLMは特定の関数の実行を要求できます。セマンティックカーネルはこのリクエストをコード中の対応する関数に伝え、結果をLLMに返して最終応答を生成させます。

すべてのAI SDKがプラグインの概念を持っているわけではありません（ほとんどは関数やツールを提供するだけです）。しかし、エンタープライズアプリケーションシナリオにおいてプラグインは非常に有用です。なぜなら、プラグインは一連の機能をラップし、エンタープライズ開発者が一般的に使用するサービスやAPI開発方法に合致するからです。プラグインは依存性注入もサポートしています。プラグインのコンストラクタ内で、タスクの実行に必要なサービス（例えばデータベース接続やHTTPクライアントなど）を注入することができます。プラグイン機能がないSDKでは、これを実現するのは難しいです。

### 一、メソッドグループを用いたプラグインの導入

```csharp
# pragma warning disable SKEXP0001
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using System;
using System.ComponentModel;
using System.Globalization;

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

var builder = Kernel.CreateBuilder();
builder.AddOpenAIChatCompletion(chatModelId, key);
var kernel = builder.Build();

kernel.ImportPluginFromFunctions("dataPlugin",
[
    kernel.CreateFunctionFromMethod(GetJapaneseDate, "GetJapaneseDate", "按日本历法，获取当前日期")
]);

[KernelFunction]
string GetJapaneseDate()
{
    var japaneseFormat = new CultureInfo("ja-JP", false).DateTimeFormat;
    japaneseFormat.Calendar = new JapaneseCalendar();
    return DateTime.Now.ToString("gg yy年MM月dd日", japaneseFormat);
}

var settings = new OpenAIPromptExecutionSettings()
{
    ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
};

var result = await kernel.InvokePromptAsync("今日は何日ですか？", new KernelArguments(settings));
Console.WriteLine(result);
```

結果：

![画像](https://mmbiz.qpic.cn/sz_mmbiz_png/4CAA63nvHRD4iaPeNnkpAptpOCIKp9EjsBDjU6ibaVxY4qJaumoldUB1tMBKqvlt1sGgyqniad6M3SRO4aMvjbnfg/640?wx_fmt=png&from=appmsg)

### 二、Typeを用いたプラグインの導入

```javascript
……
kernel.ImportPluginFromType<CurrentDateTime>();
var settings = new OpenAIPromptExecutionSettings()
{
    ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
};
var result = await kernel.InvokePromptAsync("今日は何日ですか？", new KernelArguments(settings));
Console.WriteLine(result);

// 定義された型
public class CurrentDateTime
{
    [KernelFunction, Description("現在の日本暦の日付を取得")]
    public string GetJapaneseDate()
    {
        var japaneseFormat = new CultureInfo("ja-JP", false).DateTimeFormat;
        japaneseFormat.Calendar = new JapaneseCalendar();
        return DateTime.Now.ToString("gg yy年MM月dd日", japaneseFormat);
    }
}
```

結果は前面と同じです。

### 三、オブジェクトをプラグインとして導入

```javascript
……
kernel.ImportPluginFromObject(new CurrentDateTime());

var settings = new OpenAIPromptExecutionSettings()
{
    ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
};
var result = await kernel.InvokePromptAsync("今日は何日ですか？", new KernelArguments(settings));
Console.WriteLine(result);
……
```

結果は前面と同じです。

### 四、セマンティック関数からなるプラグイン

前面のいくつかはローカル関数ですが、セマンティック関数がプラグインとして導入される場合について見ましょう。セマンティック関数は、フォルダとファイルのセットを定義することで定義でき、構造は以下の通りです。

![画像](https://mmbiz.qpic.cn/sz_mmbiz_png/4CAA63nvHRD4iaPeNnkpAptpOCIKp9EjsIj2MI0ic4PO7e63VLIf2EOftrKvibiaic1jTxN9zFzx4w8CY3lTVBTxvGQ/640?wx_fmt=png&from=appmsg)

config.json

```json
{
  "schema": 1,
  "description": "与えられたコンテンツを日本語に翻訳する",
  "execution_settings": {
    "default": {
      "max_tokens": 512,
      "temperature": 0.0,
      "top_p": 0.0,
      "presence_penalty": 0.0,
      "frequency_penalty": 0.0
    }
  },
  "input_variables": [
    {
      "name": "input",
      "description": "翻訳コンテンツ",
      "default": "",
      "is_required": true
    }
  ]
}
```

skprompt.txt

```
{{input}}を日本語に翻訳する
```

セマンティック関数プラグインの導入：

```javascript
var translateDirectory = Path.Combine(
    System.IO.Directory.GetCurrentDirectory(),
    "plugins",
    "TranslatePlugin");
kernel.ImportPluginFromPromptDirectory(translateDirectory);

// method 04
var result = await kernel.InvokeAsync("TranslatePlugin", "translate", new() {
            { "input", "今日は月曜日です" }
          });
Console.WriteLine(result);
```

結果：

![画像](https://mmbiz.qpic.cn/sz_mmbiz_png/4CAA63nvHRD4iaPeNnkpAptpOCIKp9EjsHqdryic3Mjz0RkLMW38J7UmTXYeTnISJTerJcyianibAPfIVXLHnySItA/640?wx_fmt=png&from=appmsg)

(Translated by GPT)