Microsoft「Semantic Kernel」を実装してみた

Microsoft「Semantic Kernel」を実装してみた

ジョシュエル ラノーラ

ジョシュエル ラノーラ

Technology部のJoshです。

この記事ではMicrosoftが提供する、大規模言語モデル(LLM)をデータに接続できるフレームワーク「Semantic Kernel」の説明と、そのサンプルアプリを紹介します。

「Semantic KernelとLangchainの違いを理解したい」
「Semantic Kernelで実現できること・できないことを知りたい」

というみなさんにオススメです。ぜひご覧ください。

Semantic Kernelとは

「Semantic Kernel(セマンティック カーネル)」とは、大規模言語モデル(LLM)をアプリにすばやく簡単に統合できるSDK(Software Development Kit)です。Microsoftが提供しており、ソースコードは一般公開されています。

Semantic KernelとLangchainの比較

共通点

どちらも「インメモリ機能」が搭載されており、過去に入力したプロンプトや読み込んだファイルの情報を保存できます。これにより、事前にインプットされた内容にもとづいた回答をLLMから得られます。また、プロンプトのテンプレート化を作成する機能もあります。

Semantic Kernelの特徴

Microsoftから提供されたオープンソースということもあり、AzureやMicrosoft365などのMicrosoftの各種サービスとの親和性が高いと言えるでしょう。サポートされる言語には、Python、JavaScriptのほかに、LangchainにはないC#も含まれます。

Semantic Kernelは、ユーザーが入力したプロンプトに対してさまざまな処理を独自に定義し、これらのスキルを組み合わせて目標を達成します。たとえば、「Semantic Kernelとはなにか調べてほしい」というプロンプトに対して、次のような処理を順次実行させることができます。

1.検索スキルを使用して、入力されたプロンプトに関する情報をインターネットから検索する
2.要約スキルを使用して、検索結果を要約する
3.最後に、要約された情報をLLMに渡して、適切な回答を生成させる

Langchainの特徴

gpt_indexやllama_index、pdfやcsvなどのファイルローダーが組み込まれていること、BigQueryやNotion、facebook(Meta)、Figma、GitBook、Googleドライブなどの他のサービスと連携することが可能であることから、人気のあるフレームワークです。

さまざまなサービスで幅広く利用されており、リファレンスやドキュメント、開発実装例が豊富かつ共有されています。

Langchainは、ユーザーが入力したプロンプトを解析し、適切なエージェントやLLM、ツールを使用して回答を生成します。なお、プロンプトの解析ロジックはブラックボックス化されています。

関連記事:

サンプルチャットボット機能を構築

“semantic_kernel” ライブラリとOpenAI GPT-3.5 Turboモデルを活用した、自然言語理解と生成をおこなうチャットボットを作成してみましょう。

今回は「ケロちゃん」という名前の、関西弁でメッセージに応答するフレンドリーなAIチャットボットを開発します。

アプリケーション仕様

今回開発するアプリケーション仕様は以下のとおりです。

Host ローカルホスト(MacOS Ventura 13.4.1)
プログラミング言語 Python(ver3.10)
仕様 役割や態度を設定し、ユーザーを記憶することもできるAIを構築

ライブラリ

このライブラリは、Semantic Kernel関数を使用するために必要です。

Terminal
pip install semantic-kernel

実装したコードは私のGitHubから確認できますが、一つひとつのコードについて説明します。

※解説するコードの詳細はこちら

1.ライブラリのインポート

“semantic_kernel” ライブラリは、Semantic関数を作成および管理するために使用され、OpenAI のコネクタは、OpenAI GPT-3.5 Turboモデルをチャット補完とテキスト埋め込みに統合するためにインポートします。

Python
# coding: shift_jis
import os
import asyncio
import uuid
import semantic_kernel as sk
from semantic_kernel.connectors.ai.open_ai import OpenAITextEmbedding, OpenAIChatCompletion

 
インポートするパッケージの詳細は以下のとおりです。

# coding: shift_jis:Pythonのソースコードファイルでエンコーディングを宣言するために使用される特別なコメントです。これは、ファイルがShift JISエンコーディングでエンコードされていることを示します。Shift JISエンコーディングは、日本語のテキストを表すために使用される文字コードです。

os:オペレーティングシステムと対話する方法を提供します。ファイルやディレクトリにアクセスしたり、パスを操作したり、システムコマンドを実行したりといったタスクを実行できます。

asyncio:Pythonに組み込まれているモジュールで、非同期コードを書くためのフレームワークを提供します。複数のタスクを処理できる並行コードを書くことができ、他のタスクの実行をブロックしません。

uuid:universally unique identifiers (UUID) を生成するために使用されます。UUIDは、すべてのデバイスと時間にわたって一意な128ビット数です。分散システムでオブジェクトを識別するために一般的に使用されています。

semantic_kernel:Microsoftによって開発されたライブラリで、AIアプリケーションを構築するためのフレームワークを提供します。自然言語処理、意図認識、タスクオーケストレーションなどの機能を備えています。

OpenAITextEmbedding:OpenAITextEmbeddingコネクタは、semantic_kernelライブラリの一部です。OpenAI APIへのアクセスを提供し、テキスト埋め込みを生成します。テキスト埋め込みは、テキストの意味的意味を捕捉する数値表現です。テキストの類似性やクラスタリングなどのさまざまなタスクに使用できます。

OpenAIChatCompletion:OpenAIChatCompletionコネクタは、semantic_kernelライブラリのもう1つの部分です。OpenAI APIと対話し、チャットベースの補完を生成できます。これは、会話型AIアプリケーションを構築するのに役立ちます。

2.初期化

“DBA” という辞書が作成され、シンプルなインメモリデータベースをシミュレートします。”sk.Kernel()” クラスのインスタンスが作成され、Semantic Kernelを初期化します。

Python
DBA = {}  # シンプルなインメモリデータベース
kernel = sk.Kernel()  # セマンティックカーネルの初期化

3.APIキーとサービスのセットアップ

OpenAI API キーが環境変数に設定されます。その後、Semantic Kernelにチャットとテキスト埋め込みのサービスが追加されます。チャット補完には GPT-3.5 Turbo モデルが使用され、テキスト埋め込みには Ada モデルが使用されます。

Python
os.environ['OPENAI_API_KEY'] = "APIキーを入力してください"  # ご自身の OpenAI API キーに置き換えてください
api_key = os.getenv("OPENAI_API_KEY")

# カーネルにチャットとテキスト埋め込みのサービスを追加
kernel.add_chat_service("chat-gpt", OpenAIChatCompletion("gpt-3.5-turbo", api_key))
kernel.add_text_embedding_generation_service("ada", OpenAITextEmbedding("text-embedding-ada-002", api_key))

4.メモリストアの設定

“VolatileMemoryStore” を使用してメモリ関連の操作を処理するためのメモリストアが登録されます。

Python
kernel.register_memory_store(memory_store=sk.memory.VolatileMemoryStore())

5.プロンプトテンプレートと関数の設定

チャット対話用のプロンプトテンプレートが作成され、システムメッセージが追加され、チャットボットのキャラクターやコミュニケーションスタイルが紹介されます。プロンプトテンプレートを使用してSemantic関数が設定されます。今回はチャットボットを関西人風で親しみやすいものにしたいので、その設定もおこないます。

Python
//Promptの設定を作成
prompt_config = sk.PromptTemplateConfig.from_completion_parameters(
    max_tokens=2000, temperature=0.7, top_p=0.8
)
# チャット対話用のプロンプトテンプレートを作成
prompt_template = sk.ChatPromptTemplate("""Chat:
        {{$chat_history}}
        User: {{$user_input}}
        ChatBot:""", kernel.prompt_template_engine, prompt_config)

# プロンプトテンプレートにシステムメッセージを追加
prompt_template.add_system_message("""
        あなたはケロちゃんです。あなたはフレンドリーな AI チャットボットで、ユーザーと積極的に話します。
        ユーザーの質問にフレンドリーに関西弁で答えてください。短く答えてください。
        """)

# プロンプトテンプレートを使用して関数を設定
function_config = sk.SemanticFunctionConfig(prompt_config, prompt_template) 
chat_function = kernel.register_semantic_function("KeroChan", "Chat", function_config)

6.チャットの対話

この非同期関数は、ユーザーがチャットボットと対話するのをシミュレートします。コンテキスト変数を更新し、チャット関数を実行して応答を生成、チャット履歴を更新し、会話履歴を返します。kernel.memory.save_information_async は、モデルにチャットメモリを保存できる LangchainのConversationBufferMemory().save context() に似ています。

Python
async def main(): 
 async def chat(user_id, message):
    # ユーザーのコンテキスト変数を取得または作成
    context_vars = DBA.get(user_id, sk.ContextVariables(variables=dict(
        user_input="",
        chat_history="",
    )))
    context_vars["user_input"] = message
    
    # チャット関数を実行して応答を生成
    talk = f'{user_id}: ' + context_vars["user_input"]
    answer = await kernel.run_async(chat_function, input_vars=context_vars)
    
    # チャット履歴とコンテキスト変数を更新
    print('ケロちゃん: ' + answer.result)
    await kernel.memory.save_information_async(user_id, talk, uuid.uuid4 ())
    context_vars["chat_history"] += f"\n{talk}\nケロちゃん:> {answer.result}\n"
    DBA[user_id] = context_vars
    
    # 会話履歴を返す
    return "\n".join([talk, 'ケロちゃん: ' + answer.result])

7.メイン関数

メインの非同期関数は、ユーザーとチャットボットの間での一連のチャット対話をシミュレートします。”await chat()” 関数を使用して会話を開始しましょう。”kernel.Memory.SearchAsync” は、保存されたデータにもとづく結果を検索するために Azure Cognitive Search で使用できる関数です。AIが2人のユーザーを区別できるかどうかをテストするために、2人のユーザーを入れました。

Python
 await chat('ユーザー1', 'こんにちはあなたは誰ですか?')

    await chat('ユーザー1', '僕はジョシュです!よろしく!')
    await chat('ユーザー2', '僕はれんげといいます!よろしくにゃ!')

    await chat('ユーザー1', 'あれ僕の名前は何だっけ?')
    await chat('ユーザー2', '僕の名前は何ですか?')

    await chat('ユーザー1', '僕は今日フライドチキンを食べたよ')
    await chat('ユーザー2', '僕は今日ゲームをしました。')

    await chat('ユーザー1', '僕は何を食べたか?')
    await chat('ユーザー2', '僕は何を食べましたか?')
    memory = await kernel.memory.search_async('ユーザー1', 'ユーザーの今日の活動')
    print("メモリー: " + memory[0].text)

    memory = await kernel.memory.search_async('ユーザー2', 'ユーザーの今日の活動')
    print("メモリー: " + memory[0].text)


if __name__ == "__main__":
    asyncio.run(main())

8.結果

AIは2人のユーザーを区別することに成功しました。また、各ユーザーのプロンプトも正常に記憶されました!

まとめ

Semantic KernelとLangchainのどちらを選択するかは、特定のニーズと優先順位によって異なります。より大きなコミュニティとより多くのライブラリを重視する場合は、LangChainのほうがよい選択と言えるでしょう。ただし、カスタマイズ、最適化、Azureサービスとの統合が必要な場合は、Semantic Kernelが有力候補となる可能性があります。

プロジェクトの要件にもとづいて、コミュニティサポート、ドキュメント、パフォーマンス、使いやすさなどの要素を比較検討することをオススメします。

 

また、LIGでは生成AIコンサルティング事業をおこなっています。ぜひ気軽にご相談ください。

生成AIコンサルティング事業の詳細へ

最新情報をメルマガでお届けします!

LIGブログではAIやアプリ・システム開発など、テクノロジーに関するお役立ち記事をお届けするメルマガを配信しています。

<お届けするテーマ>
  • 開発プロジェクトを円滑に進めるためのTIPS
  • エンジニアの生産性が上がった取り組み事例
  • 現場メンバーが生成AIを使ってみた
  • 開発ツールの使い方や開発事例の解説
  • AIをテーマにしたセミナーの案内
  • 最新のAI関連ニュースまとめ など

「AIに関する最新情報を集めたい!」「開発ツールの解説や現場の取り組みを知りたい!」とお考えの方は、ぜひお気軽に無料のメルマガをご購読くださいませ。

購読する(無料)

この記事のシェア数

ジョシュエル ラノーラ
ジョシュエル ラノーラ Technical Director / ラノーラ ジョシュエル

ITプロフェッショナル/テクニカルディレクターとしてOpenAIを使用したサービスの実装に関する研究や実験に従事。JS、PHP、Python、Vue、Reactのフレームワークに関して深い知識を所有する。プログラミングへの情熱は高校時代からあり、コンピュータサイエンスの学位を取得後、エンジニアとして日本のIT系企業に就職。4年間フルスタックエンジニアに従事し、2023年LIGにジョイン。

このメンバーの記事をもっと読む
デザイン力 × グローバル体制を活かしたシステム・アプリ開発
お問い合わせ サービス詳細/実績