Microsoft が LLM をアプリ開発に統合するための OSS「Semantic Kernel」を発表


Semantic Kernel (SK) は Microsoft が OSS として発表した、大規模言語モデル (LLM) をアプリにすばやく簡単に統合できる SDK です。SK は従来のプログラミング言語と最新のLLM AI "プロンプト" を簡単に組み合わせることができ、テンプレート化、チェーン化、埋め込みベースのメモリー、およびプランニング機能を備えています。

https://devblogs.microsoft.com/semantic-kernel/hello-world/

機能的には、LangChain や LlamaIndex に似たような機能を持っているライブラリです。現状は [C# 向けにリリース](https://github.com/microsoft/semantic-kernel)されています。4/17 に [Python 版](https://github.com/microsoft/semantic-kernel/tree/main/python) もリリースとなりました。ただし機能は部分的な実装である点にご注意ください。([FEATURE MATRIX](https://github.com/microsoft/semantic-kernel/blob/main/FEATURE_MATRIX.md))

## 6/23 Semantic Kernel が Copilot stack との連携を明確化しプラグインエコシステムと統合
https://qiita.com/nohanaga/items/3c9446375491f46e4aae

# Semantic Kernel
GPT-3 や ChatGPT でアプリ開発していると、プロンプトという 1 つの入力インターフェースで様々なタスクができてしまうという自由度の高さを感じると思います。最初は問題ないかもしれませんが次第にやることが増えてくると、解決したいタスクごとに関数として分離して、それぞれを既存の関数と同様に扱いたいというニーズが自然と出てきます。このようなニーズに応えるために開発されたのが SK です。

![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/88846d18-4e41-ba5f-aac8-7c8fce41eaa4.png)

Semantic Kernel (SK) は、次の概念に基づいて構築されています。

|コンセプト|簡単な説明|
|:-----------|:-----------|
|カーネル|システムのコアで全体の処理をオーケストレーションします|
|プランナー|利用可能なスキルに基づいてステップに分割します|
|スキル|LLM AI プロンプトとネイティブ コードから構築されたカスタマイズ可能なリソースです|
|メモリー|コンテキスト情報を保持するカスタマイズ可能なリソースです|
|コネクター|外部データへのアクセスを可能にするカスタマイズ可能なリソースです|


# カーネル
[カーネル](https://learn.microsoft.com/semantic-kernel/concepts-sk/kernel)は全体の処理をオーケストレーションします。そして利用可能なスキル、メモリ、およびコネクタを使用して、ユーザーの質問や目的を達成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/2554d07e-748b-8d18-9943-b03e54b52716.png)

[カーネル](https://github.com/microsoft/semantic-kernel/blob/python-preview/docs/GLOSSARY.md)は Function composition（関数合成）を促進するように設計されており、ユーザーは複数の関数 (ネイティブおよびセマンティック) を 1 つのパイプラインに結合できます。あぁ…やはりパイプライン…　パイプラインがすべてを解決するんや…　Azure Cognitive Search も Azure Machine Learning も Azure Synapse も行きつくところはパイプラインなんや… しかもそのパイプラインを LLM AI が自動的に作ってくれたとしたら・・・？

# プランナー
[プランナー](https://learn.microsoft.com/semantic-kernel/concepts-sk/planner)はカーネルに登録されたスキルのコレクションを利用し、AI を用いて、与えられた依頼を実行するための計画を策定します。複数のスキルを実行していくというのは[前回の記事](https://qiita.com/nohanaga/items/803c09b5a3a4e2d1776f#3-%E8%B3%AA%E5%95%8F%E5%BF%9C%E7%AD%94-ui)で紹介した、LangChain による Read-Retrive-Read や Read-Decompose-Ask のような仕組みに似ているのではと推測していますが、現状サンプルコードなどがまともに動かないため、もう少し調査が必要です。。。

## プランナーに使用するスキルを指示
サンプルのスキルセットは、`/samples/skills` に用意されています。
```C#
var skillsDirectory = Path.Combine(System.IO.Directory.GetCurrentDirectory(), "..", "..", "skills");
kernel.ImportSemanticSkillFromDirectory(skillsDirectory, "QASkill");
```

## 質問を投げてスキルの実行計画を生成

```C#
var ask = "I want to go to Microsoft HQ from Tokyo.";
var originalPlan = await kernel.RunAsync(ask, planner["CreatePlan"]);
```

## 実行計画が XML 形式で生成される
AI がどの関数を呼び出すかを決定しています。（要調査）実行計画の各ステップの出力は `setContextVariable` として設定され、次のスキルの `input` として利用できるようになります。

```xml
Original plan:

<goal>
I want to go to Microsoft HQ from Tokyo.
</goal>
<plan>
  <function.QASkill.Question input="Where is Microsoft HQ?" setContextVariable="QUESTION_RESULT"/>
  <function.QASkill.QNA input="$QUESTION_RESULT" setContextVariable="QNA_RESULT"/>
  <function.QASkill.AssistantResults api="Microsoft" results="$QNA_RESULT" resultsContext="Microsoft HQ" setContextVariable="ASSISTANT_RESULT"/>
  <function.QASkill.ContextQuery firstname="John" lastname="Doe" city="Tokyo" state="Tokyo" country="Japan" input="$ASSISTANT_RESULT" setContextVariable="CONTEXT_QUERY_RESULT"/>
  <function.QASkill.Form promptName="Microsoft HQ" input="$CONTEXT_QUERY_RESULT" setContextVariable="FORM_RESULT"/>
  <function._GLOBAL_FUNCTIONS_.BucketOutputs input="$FORM_RESULT" bucketCount="3" bucketLabelPrefix="Result" />
</plan>
```

`QASkill` に含まれている複数のセマンティック関数の実行順と引数が自動的にセットされていることが分かります。これを上から滝のように実行して結果を引き継ぎながら最終的に回答を求めます。

# スキル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/256f4202-7562-05c0-84dd-66d04a15f74d.png)

[スキル](https://learn.microsoft.com/semantic-kernel/concepts-sk/skills)は細かく分けるとセマンティック関数とネイティブ関数の2種類で構成されており、これらを組み合わせてスキルを構成することができます。
 - セマンティック関数
実体はプロンプトを記載したテキストファイル(skprompt.txt)と Completition API のパラメータを記載した設定ファイル(config.json)です。以下は要約を行うシンプルなセマンティック関数の例で、プロンプト内のコンテキスト変数 `{{$input}}` へデータを渡すことができます。コンテキスト変数はカスタムできます。

    ```python
    sk_prompt = """
    {{$input}}
    
    上記の内容を3つのポイントに要約してください。
    """
    ```

 - ネイティブ関数
既存の開発言語で記述されたコード。セマンティック関数と組み合わせてハイブリッド開発ができる。

関数はチェーンのように[連鎖](https://learn.microsoft.com/semantic-kernel/howto/chainingfunctions)させることができ、より高度なプロンプトパイプラインを内包するスキルを構築することが可能です。要約スキルや分類スキル、質問応答スキルなどのタスクに分割して定義して管理することで、開発者はスキルの再利用が可能になり、可読性、再現性など MLOps 的なベネフィットも得られることでしょう。

# メモリー
Azure OpenAI Service の Completion API はステートレスであり、基本的に情報が保持されません。ChatGPT のようにコンテキストにチャット履歴を残していくタイプの開発では、トークン制限以内になるように過去の情報を忘却する必要があります。この課題に対処するには "記憶" をどこかに持つ必要があります。SK はこれを[メモリー](https://learn.microsoft.com/semantic-kernel/concepts-sk/memories)という機能を使って 3 種類の方法で保持することが可能です。

- Key-Value ペアによる Lookup
- ローカル ストレージへ保存しファイル名でアクセス
- セマンティック メモリ検索：テキストを Embeddings というベクトルに変換し、セマンティック検索を行います。

例えばあるユーザーの過去の会話履歴を一時的なインメモリストレージである`VolatileMemoryStore`（短期記憶）にセットすると、以下のようにコンテキストに過去の対話履歴やユーザーの属性を挿入することが簡単にできるようになります。もちろん外部のデータソースを用意し、長期記憶として履歴を永続化することも可能になります。

```python
sk_prompt = """
このチャットボットは、どんな話題でもあなたと会話することができます。

以前の会話から得られた、私に関する情報:
- {{$fact1}} {{recall $fact1}}
- {{$fact2}} {{recall $fact2}}

Chat:
{{$chat_history}}
User: {{$human_input}}
ChatBot: """
```
`TextMemorySkill` がユーザーからの質問をメモリー内からセマンティック検索し、類似度の高い回答をコンテキスト変数に代入します。その後、LLM が情報を統合して回答します。

# コネクター
[コネクター](https://learn.microsoft.com/semantic-kernel/concepts-sk/connectors)を使用すると、スキルの外にある外部 API など、あらゆるものにアクセスできます。これによって無限の可能性を持った LLM AI アプリケーションが開発できます。例えば MS Graph コネクタ キットを使うとメールを送ったり、OneDrive にファイルを追加したり、カレンダーにイベントを追加したりできます。

現在ビルトインされているコネクターは以下のようなものがあります。
- Skills.Document: OpenXML ストリームの読み取り
- Skills.Memory.Sqlite: SQLite をメモリーとして利用
- Skills.MsGraph: 
    - MicrosoftToDoConnector
    - OneDriveConnector
    - OrganizationHierarchyConnector
    - OutlookCalendarConnector
    - OutlookMailConnector
- Skills.Web
    - BingConnector: Bing 検索クエリを発行

今後ベクトルデータベースとの接続を行うようなコネクターも出てくることが予想されます。

![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/c2bffba6-0d22-5402-7593-999e268e69a7.png)

GPT-3 によるドキュメント解析結果を [MS Graph](https://learn.microsoft.com/graph/overview) を使って各サービスと連携する例。

https://qiita.com/nohanaga/items/2691f64bd1fb418295b8


# Semantic Kernel について学ぶ
 - [Semantic Kernel とは？](https://learn.microsoft.com/semantic-kernel/whatissk)
 - [無料の LinkedIn 学習コース](https://www.linkedin.com/learning/introducing-semantic-kernel-building-ai-based-apps/introducing-semantic-kernel)
 - [microsoft/semantic-kernel](https://github.com/microsoft/semantic-kernel)

# Semantic Kernel 日本語解説
https://www.youtube.com/watch?v=tFgqdHKsOME&t=4687s

# おわりに
先日 [ChatGPT × Azure Cognitive Search](https://qiita.com/nohanaga/items/803c09b5a3a4e2d1776f) を使ったエンタープライズサーチの記事を書きましたが、こちらのコードも SK を使って高度化できるような気がしました。。。が全然時間が無く、技術の進化に追いついてない状況です。