👻

Semantic Kernel のサンプル概要

2023/04/30に公開

Semantic Kernel とは?

  • Microsoft が発表した SDK
  • 大規模言語モデル (LLM) AI と連携したアプリを簡単に構築することができるようになる
  • C# で実装できる(Python も可)

機能としては、LangChain や LlamaIndex、また今後利用可能となる ChatGPT Plugins に近いものではないかと思います。

本記事では、具体的にどのようなことができるのか を GitHub リポジトリにあるサンプルに沿って見ていきます。Semantic Kernel の詳細について知りたい方は以下の参考サイト等を参照ください。

参考サイト

環境構築

基本的には OpenAI / Azure OpenAI API key のどちらかがあれば利用できます(Webサーチなど外部との連携をおこなう場合、外部サービスの API key が必要になる場合もあります)。

サンプルには Python 環境で実行するもの、Visual Studio で実行するもの、ブラウザで実行するもの(Webアプリ)、Jupyter Notebook で実行するものなどいくつかのパターンがあります。また現時点では C# と Python で機能に差分があるため事前に Kernel Feature Matrix by Language を確認しておくと良いと思います。

上記のパターンの中で Jupyter Notebook の dotnet サンプルを見ていきます(Jupyter Notebook上で C# を動かせるのが面白かったため)

その際に必要となるものは以下になります。

サンプル説明

Jupyter Notebook の dotnet サンプルは、リポジトリの
semantic-kernel\samples\notebooks\dotnet
配下にあるファイル群になります。
環境構築が済んでいれば、あとはこれらのファイルを VSCode で開いてマウスでクリックしていくだけで動くので、サンプルの動作確認をするだけであればコードを自分で打ち込む必要はないのでお手軽です。

以降、各サンプルの説明です。

0-AI-settings.ipynb

初期設定、設定リセットの説明をしたファイルです。
次の 00-getting-started.ipynb でも同様の初期設定を行うので飛ばして大丈夫です。

00-getting-started.ipynb

OpenAI または Azure OpenAI の API key が必要になります。
Step 2を実行するとエディター上部に key の入力欄が表示されるので入力して Enter を押します。ここで設定した API key は config/settings.json に保存されているため初期設定手順は一度だけ行えば他のサンプルも動作します。

あとは Step の順番にそって実行ボタンを押していきます。

Step 4 で
semantic-kernel\samples\skills\FunSkill\Joke
という 入力をもとにジョークを出力してくれるスキル を読み込み実行しています。

https://twitter.com/hi_rom_/status/1652362573873049601?s=20

01-basic-loading-the-kernel.ipynb

カーネルの基本的なロード方法を説明したサンプルです。
こんなものかと眺める程度で大丈夫だと思います。

02-running-prompts-from-file.ipynb

セマンティックスキルをファイルから読み込む方法を説明したサンプルです(やっていること自体は、00-getting-started.ipynb で説明済みのジョークスキルを読み込んでいるだけです)。
セマンティックスキルとは、セマンティックファンクションのコレクションで、セマンティックファンクションとは簡単に言えば LLM に入力するためのプロンプトのことです。

FunSkill     :セマンティックスキル
  ├ Excuses  :セマンティックファンクション
  ├ Joke     :セマンティックファンクション
  └ Limerick :セマンティックファンクション

他にもコアスキルやネイティブスキルがありますが詳細は What are Skills? を参照ください。

03-semantic-function-inline.ipynb

インラインに実装したセマンティックファンクションを読み込むサンプルです。

以下のようなシナリオで役に立つと説明されています:

  • 実行時に複雑なルールを使用してプロンプトを動的に生成する
  • TXTファイルの代わりにC#コードを編集してプロンプトを書く
  • このドキュメントのようなデモを簡単に作成することができる

サンプルにおいては、入力内容を要約する例が紹介されています。

example
長い文章が5単語に要約されています。

04-context-variables-chat.ipynb

コンテキスト変数を使った基本的なチャット体験のサンプルです。
ユーザがボットとやり取りをするときに、コンテキストに会話の履歴を入力することがポイントとなります。
いわゆる ChatGPT みたいなものを作りたい場合に参考になります。

06-memory-and-embeddings.ipynb でメモリを利用した改善案が提示されています。

05-using-the-planner.ipynb

プランナーを利用したサンプル です。
プランナーに利用可能なスキルを登録しておくと、ユーザーの質問に対して適切なスキルを選択し、解決するためのプランを立ててくれます。

サンプルでは以下のようなユーザーの入力(日本語へ翻訳しています)

明日はバレンタインデーです。 デートのアイデアをいくつか考え出す必要があります。 彼女はシェイクスピアが好きなので、彼のスタイルで書きます。 これらのアイデアを大切な人に電子メールで送信します。

に対して、

  • WriterSkill.Brainstorm
  • ShakespeareSkill.shakespeare
  • WriterSkill.EmailTo

の3つのスキルを利用するプランを立てて、実行することで以下のような出力(日本語へ翻訳しています)が得られています。

親愛なる大切な人へ

一緒にロマンティックで楽しい時間を過ごすためのアイデアがいくつかあります。 ロマンティックなレストランに行ったり、一緒に料理教室に参加したり、公園でピクニックをしたり、地元のワイナリーを訪れたり、一緒にダンスのクラスに参加したり、お笑い番組に行ったり、温泉に行ったり、美術館に行ったり、温泉に行ったりしましょう。 気球に乗ったり、星空を見たり。

これらのアイデアを気に入っていただければ幸いです。また、ご一緒できることを楽しみにしています。

ありがとう

06-memory-and-embeddings.ipynb

埋め込みを利用したメモリのサンプルです。

これまでのサンプルで利用してきた text-davinci-003 モデルだけでなく、埋め込み用の text-embedding-ada-002 モデルも利用しています。

サンプルではあらかじめ自分についての情報を保存しておき(埋め込んでおき)、その情報も利用してユーザーの質問に答える例が紹介されています。

また、外部のドキュメント(.md, .ipynb, .csなど)を埋め込んでおく例も紹介されています。

RAMに入りきらないほどのデータがある場合、エンベッディングを保存・検索するために作られた、外部のベクターデータベースを利用することになります。そのあたりはご期待ください!

とのことです。期待しておきましょう。

07-DALL-E-2.ipynb

DALL-E 2 を利用して画像を生成するサンプルです。
単に画像を生成するだけであれば画像生成APIをたたくだけで済みますが、このサンプルでは画像を生成するテキストをまずAIで生成し、生成されたテキストをもとに画像を生成、生成された画像のもととなったテキストを当てるゲームとして埋め込み機能を利用しています。

// ランダムな画像説明文を生成するセマンティック関数を作成する
var genImgDescription = kernel.CreateSemanticFunction(
    "Think about an artificial object correlated to number {{$input}}. " +
    "Describe the image with one detailed sentence. The description cannot contain numbers.", 
    maxTokens: 256, temperature: 1);

var random = new Random().Next(0, 200);
Console.WriteLine(random); // 追記
var imageDescription = await genImgDescription.InvokeAsync($"{random}");
Console.WriteLine(imageDescription.Result); // 追記

// DALL-E 2 を使用して画像を生成する
// OpenAI は URL を返す (ただし、base64 イメージを返すように要求することは可能)。
var imageUrl = await dallE.GenerateImageAsync(imageDescription.Result.Trim(), 512, 512);
Console.WriteLine(imageUrl); // 追記

await SkiaUtils.ShowImage(imageUrl, 512, 512);

まず、

数字の xx に関連付けられた人工物について考えてみましょう。
イメージを 1 つの詳細な文で説明します。 説明に数字を含めることはできません。

といったプロンプトを入力しています。実行してみた結果が以下になります。

ランダムに 45 という数字が選ばれ、

A bright blue, 45-degree angled triangle with a glossy finish.

という説明文が得れています。この説明文をもとに画像を生成しています。

output

ゲームの部分は

A bright blue, 45-degree angled triangle with a glossy finish.

の部分を上の例ではデバッグ表示しましたが、本来は表示されていないものなので、この文章を推測して入力し、類似度を表示するといったものです。

output2

08-chatGPT-with-DALL-E-2.ipynb

これまでの TextCompletion API を利用したサンプルと異なり、ChatCompletion API を利用し、DALL-E 2 で画像を生成するサンプルです。

Semantic Kernel で ChatGPT をセットアップする方法チャット履歴オブジェクトを管理する方法、そして面白くするために ChatGPT に画像の説明で返信するように依頼し、DALL-E 2 を活用して画像を使って対話する方法が例として示されています。

なお、ChatGPT モデル(gpt-3.5-turbo) の利用においては、以下の3種類のメッセージを把握しておく必要があります。

  • system: チャットモデルに指示を与えるために使用され、例えば、あなたのアプリが提供するコンテキストや会話の種類を設定します

  • user: アプリのユーザーから受け取ったデータを保存します

  • assistant: LLM モデルによって生成された返信を保存します

messages=[
    { "role": "system",    "content": "You are a helpful assistant."},
    { "role": "user",      "content": "Who won the world series in 2020?"},
    { "role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."},
    { "role": "user",      "content": "Where was it played?"}
]

以下は実行してみた例です。

output

まとめ

サンプルから Semantic Kernel を利用して様々なことができることがわかります。
具体的な作業を行うための(セマンティック)スキルについては、適切なプロンプトを考えることが重要であり、プログラミングの知識はマストではありません。紹介したもの以外にもリポジトリ内に様々なスキルがあるので興味が沸いた方はぜひ参考にしてみてください。
自分用の秘伝のスキルをたくさんストックしておき、それらをうまく組み合わせることで生産性が爆上がりするかもしれませんね。

Discussion