はじめに
GoogleからGoogle.GenAI(dotnet-genai)というGemini Developer APIやVertex AI APIを利用するための.NET SDKがリリースされました。
以前Google.Cloud.AIPlatform.V1を紹介した記事を書きましたが、より高レベルで使いやすいSDKになっています。
www.hanachiru-blog.com
概要
冒頭でも記述したように、Google.GenAIはGemini Developer API/Vertex AI API向けの.NET SDKです。テキスト生成, 画像生成, リアルタイムの音声対話などを比較的簡単にできます。
Google Gen AI .Net SDK provides an interface for developers to integrate Google's generative models into their .Net applications. It supports the Gemini Developer API and Vertex AI APIs.
// DeepL翻訳
Google Gen AI .Net SDKは、開発者がGoogleの生成モデルを.Netアプリケーションに統合するためのインターフェースを提供します。Gemini Developer APIおよびVertex AI APIをサポートしています。
dotnet-genai/README.md at main · googleapis/dotnet-genai · GitHub
下準備
プロジェクトの作成とセットアップ方法を紹介します。あくまで一例なので、それぞれの目的に応じて実施してください。
コンソールアプリケーションの作成
dotnet-cliからコンソールアプリケーションを作成するには以下のコマンドを実行します。
dotnet new <TEMPLATE> - .NET CLI | Microsoft Learn
# .NET8以上でないとダメなので注意 $ dotnet new console -n Sandbox -f net9.0
dotnet-genaiをインストール
早速SDKをインストールします。以下のコマンドを実行してください。
www.nuget.org
$ dotnet add package Google.GenAI
また.NET8以上にしか対応していないので注意です。
Gemini Developer APIを利用するためにAPIキーを取得する
個人で試すのでGemini Developer APIを活用した例を紹介します。(企業であれば大体Vertex AI APIを利用されているかと)
取得方法は簡単で、Google AI Studioの[APIキー]からAPIキーを作成を選択すればOKです。
ai.google.dev

Gemini Developer APIを利用する
まずは簡単なテキスト生成をしてみましょう。Gemini Developer APIを利用する場合とVertex AI APIを活用する場合で微妙に違うので注意です。
using Google.GenAI; // Gemini Developer APIの場合 // コンストラクタで設定しない場合は GEMINI_API_KEY から読み取る。例. new Client() var client = new Client(apiKey: "..."); // Vertex AI APIの場合 // コンストラクタで設定しない場合は GOOGLE_GENAI_USE_VERTEXAI, GOOGLE_CLOUD_PROJECT and GOOGLE_CLOUD_LOCATION から読み取る // var client = new Client(project: "...", location: "...", vertexAI: true); try { var response = await client.Models.GenerateContentAsync( model: "gemini-2.0-flash", contents: "Unityの将来性についてどう思いますか?"); Console.WriteLine("Gemini API Response:"); // 例: Unityの将来性については、様々な意見がありますが、全体的に見て**非常に有望**だと考えられます。その理由は... Console.WriteLine(response.Candidates[0].Content.Parts[0].Text); } catch (HttpRequestException ex) { Console.WriteLine($"An error occurred with Gemini API: {ex.Message}"); }
ストリームとして受け取る
上記のGenerateContentAsyncはAPIからの完全なレスポンスが返ってきてから、まとめて一つのオブジェクトとして返します。対してGenerateContentStreamAsyncを利用することで、部分的な結果を都度都度受け取ることができます。一括で受け取るか、逐次で受け取るかです。
var client = new Client(); try { // ## Unityの未来:創造性の民主化とメタバースの架け橋 // 2035年、Unityは単なるゲームエンジンではなく、クリエイターエコシステムの中心として、その地位を確立していた。 // ... await foreach (var chunk in client.Models.GenerateContentStreamAsync( model: "gemini-2.0-flash", contents: "Unityが今後将来的にどうなるかを予測したストーリーを教えてください。")) { var text = chunk.Candidates?[0]?.Content?.Parts?[0]?.Text; if (!string.IsNullOrEmpty(text)) { Console.Write(text); } } } catch (ClientError ex) { Console.WriteLine($"Client error occurred with Gemini API: {ex.Message}"); Console.WriteLine($"Status Code: {ex.StatusCode}, Status: {ex.Status}"); } catch (ServerError ex) { Console.WriteLine($"Server error occurred with Gemini API: {ex.Message}"); Console.WriteLine($"Status Code: {ex.StatusCode}, Status: {ex.Status}"); } catch (HttpRequestException ex) { Console.WriteLine($"HTTP error occurred with Gemini API: {ex.Message}"); }
GenerateContentConfigを活用する
GenerateContentConfigを設定すると、TemperatureやMaxOutputTokensやResponseSchemaなど細かい設定をすることができます。
github.com
ResponseSchema
全部紹介するのも難しいので、ResponseSchema(ResponseJsonSchema)あたりを紹介しようと思います。
これを設定することで、モデルの出力を特定のJSON形式に強制することができます。例えば入力で与えたテキストを10段階評価したい場合は、ResponseSchemaで指定することで実現できます。
var client = new Client(); try { Schema countryInfo = new() { Properties = new Dictionary<string, Schema> { { "score", new Schema { Type = Type.INTEGER, Title = "A score represented by an integer value from 0 to 10" } }, { "reason", new Schema { Type = Type.STRING, Title = "Reason for the score" } } }, Required = ["score"], Title = "GameResult", Type = Type.OBJECT }; var response = await client.Models.GenerateContentAsync( model: "gemini-2.0-flash", contents: "We crushed the opposing team in baseball. Please rate the score on a scale of 1 to 10.", config: new GenerateContentConfig { ResponseMimeType = "application/json", ResponseSchema = countryInfo } ); // { // "score": 10, // "reason": "Crushing the opposing team in baseball indicates a very high score." // } string text = response.Candidates[0].Content.Parts[0].Text; Console.WriteLine(text); } catch (HttpRequestException ex) { Console.WriteLine($"An error occurred with Gemini API: {ex.Message}"); }
画像生成
画像生成も簡単にできます。
var client = new Client(); try { var generateImagesConfig = new GenerateImagesConfig { NumberOfImages = 1, AspectRatio = "1:1", SafetyFilterLevel = SafetyFilterLevel.BLOCK_LOW_AND_ABOVE, PersonGeneration = PersonGeneration.DONT_ALLOW, IncludeSafetyAttributes = true, IncludeRaiReason = true, OutputMimeType = "image/jpeg", }; var response = await client.Models.GenerateImagesAsync( model: "imagen-3.0-generate-002", prompt: "古いゲーム機", config: generateImagesConfig ); var image = response.GeneratedImages.First().Image; Console.WriteLine(image.ImageBytes.Length); } catch (HttpRequestException ex) { Console.WriteLine($"An error occurred with Gemini API: {ex.Message}"); }