🤖
Semantic KernelでGeminiを使用してみた
はじめに
こんにちは!
ネクスタで開発エンジニアをしている日野岡です。
近年、生成AIは急速に進化しており、弊社システムにおいてもLLM(大規模言語モデル)を活用した機能開発が求められています。弊社の主要開発言語はC#であり、この環境に適したLLM開発フレームワークの選定が課題となっています。
一般的にLLM開発ではPythonのLangChainが広く用いられますが、C#へのネイティブ対応はありません。このため、以下の選択肢を検討しました。
- Dify APIの利用: Difyで構築した機能をAPI経由で呼び出す方法。
- Semantic Kernel: Microsoft公式のLLMフレームワーク。(GitHub)
- LangChain .NET: LangChainの非公式C#移植版。(GitHub)
これらの中で、公式サポートのあるSemantic Kernelは有力な候補です。
しかし、調査を進めると、以下の点が確認されました。
- 日本語情報の不足: 現時点で、日本語による詳細な技術情報や事例が少ない状況です。
- Gemini APIに関する情報不足: 弊社ではGoogleのGemini APIの利用も検討していますが、Semantic Kernelに関する情報の多くはOpenAIまたはAzure OpenAIを対象としており、Gemini連携に関する具体的な情報は限定的です。
これらの状況を踏まえ、Semantic KernelがC#環境でのLLM開発において実用的か、特に弊社が利用を想定しているGemini APIとの連携が可能かを具体的に検証する必要があると判断し、試してみました。
やってみた
-
ステップ1: Gemini APIキーを取得する
-
ステップ2: Visual Studioでプロジェクトを作成する
- VSCodeではなく、Visual Studioで開発できるかどうかも弊社では大事なポイントです。
-
ステップ3: 必要なパッケージをインストール
- Microsoft.SemanticKernel
- Microsoft.SemanticKernel.Connectors.Google
- 現状は、プレリリース版の様子
- プレリリースチェックなし
OpenAIとAzureOpenAI系しかない・・・
- プレリリースにチェックを入れると色々出てきた
- プレリリースチェックなし
-
ステップ4: コードを作成する
-
不穏な警告が出るが・・・
警告メッセージSKEXP0070: 'Microsoft.SemanticKernel .GoogleAIKernelBuilderExtensions. .AddGoogleAIGeminiChatCompletion( Microsoft.SemanticKernel.IKernelBuilder, string, string, Microsoft.SemanticKernel.Connectors.Google.GoogleAIVersion, string?, System.Net.Http.HttpClient?)' は、評価の目的でのみ提供されています。 将来の更新で変更または削除されることがあります。 続行するには、この診断を非表示にします。
-
将来に期待し、いったん警告を無視して進める
string modelId = "gemini-2.0-flash"; string apiKey = "GEMINI_API_KEY"; // 1. Kernel Builderの作成 var builder = Kernel.CreateBuilder(); // 2. Gemini Chat Completionサービスの追加 #pragma warning disable SKEXP0070 builder.AddGoogleAIGeminiChatCompletion(modelId, apiKey); #pragma warning restore SKEXP0070 // 3. Kernelのビルド var kernel = builder.Build(); // 4. プロンプトの準備 var prompt = "Semantic Kernelについて簡単に説明してください。"; Console.WriteLine($"プロンプト: {prompt}"); Console.WriteLine("\nGeminiからの応答:"); Console.WriteLine("--------------------"); // 5. Gemini APIの呼び出し (プロンプトの実行) var result = await kernel.InvokePromptAsync(prompt); // 6. 結果の表示 Console.WriteLine(result.GetValue<string>()); Console.WriteLine("--------------------"); Console.WriteLine("\n処理が完了しました。何かキーを押すと終了します..."); Console.ReadKey();
-
-
成功
プロンプト: Semantic Kernelについて簡単に説明してください。 Geminiからの応答: -------------------- Semantic Kernel(セマンティックカーネル)は、Microsoftが開発したオープンソースのソフトウェア開発キット(SDK)です。AIモデル(特に大規模言語モデル:LLM)をアプリケーションに簡単に統合できるように設計されています。 **Semantic Kernelの主な特徴:** * **プラグインベースのアーキテクチャ:** LLMの機能を、再利用可能な「プラグイン」として扱います。これにより、特定のタスクを実行するための様々なLLMスキルを簡単に組み合わせることができます。 * **セマンティック機能:** LLMの理解能力を活用して、ユーザーの意図を理解し、適切なアクションを実行します。例えば、「〇〇について調べて、メールのドラフトを作成して」といった要求に対して、自動的に必要な情報収集とメール作成を実行できます。 * **プランニング機能:** 複雑なタスクを複数のステップに分解し、LLMを使って最適な実行プランを自動的に生成できます。これにより、複雑なワークフローを自動化できます。 * **言語に依存しない設計:** C#, Python, Javaなど、複数のプログラミング言語をサポートしています。 * **オープンソース:** GitHub上で公開されており、誰でも自由に利用、貢献できます。 **Semantic -------------------- 処理が完了しました。何かキーを押すと終了します...
画像からの文字列抽出も試してみる
-
ステップ1: 画像を用意(パワポの名刺のテンプレート)
-
ステップ2: コードを作成する
// 4. プロンプトの準備 var prompt = "この画像から全てのテキストを抽出してください。"; Console.WriteLine($"プロンプト: {prompt}"); Console.WriteLine("\nGeminiからの応答:"); Console.WriteLine("--------------------"); // 画像ファイルのパスを指定 string imagePath = @"card.jpg"; // 画像ファイルをバイト配列として読み込み byte[] imageData = File.ReadAllBytes(imagePath); // 画像データをBase64エンコード string base64Image = Convert.ToBase64String(imageData); // マルチモーダル入力を作成 var arguments = new KernelArguments { ["imageBase64"] = base64Image, ["imageFormat"] = Path.GetExtension(imagePath).TrimStart('.').ToLower() }; // 5. Gemini APIの呼び出し (プロンプトの実行) var result = await kernel.InvokePromptAsync(prompt, arguments);
-
失敗
なんじゃこりゃ・・・画像からテキストを抽出しました。以下の通りです。 **上部:** * 第1章 3Dアバターとは? **本文:** * 近年、メタバースを筆頭に3D空間での活動が広がりを見せる中、自分自身の分身となる3Dアバターの需要が高まっています。 * 3Dアバターとは、3D空間上でユーザー自身を表現するデジタルキャラクターのことです。2Dのアイコンやアバターに比べ、より立体的で表現力豊かなため、メタバースやVR/ARなどの没入感の高い体験をよりリアルに楽しむことができます。 * 本章では、3Dアバターの概要や種類、利用シーンについて解説します。 **下部:** * 1. 3Dアバターの概要 * 2. 3Dアバターの種類 * 3. 3Dアバターの利用シーン 上記のテキストが画像から認識されました。
- 別の方法で試してみる
Multi-modal chat completion - コード
// 画像ファイルのパスを指定 string imagePath = @"card.jpg"; //// 画像ファイルをバイト配列として読み込み byte[] imageData = File.ReadAllBytes(imagePath); // LLMに必要な役割を指示するシステムメッセージとともにチャット履歴を作成する var chatHistory = new ChatHistory("あなたは画像解析エンジンです。"); // 画像と画像に関する質問の両方を添えて、ユーザーメッセージを追加 chatHistory.AddUserMessage( [ new TextContent("この画像から全てのテキストを抽出してください。"), new ImageContent(imageData, "image/jpg"), ]); // チャット完了サービスの取得 var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>(); // チャット完了モデルを呼び出す var result = await chatCompletionService.GetChatMessageContentAsync(chatHistory); // 6. 結果の表示 Console.WriteLine(result.Content);
- 別の方法で試してみる
-
成功
以下は画像から抽出されたテキストです。 舞玄太郎 Taro Maikuro 株式会社 ○○○○○ 〒000-0000 ○○○○○○○○○○○○○ TEL: 00-0000-0000 FAX: 00-0000-0000 E-mail: taro@xxxxxxX Mobile: 000-0000-0000 Company name http://XXXXXX_sample.aa.jp
感想
- プレリリース版ではあるが、使用できる事はわかった
- 正式版は、OpenAIとAzureOpenAIのみ
- 次は、LangChain .NETも試したい
Discussion