go-gemini-client

module
v1.13.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 22, 2026 License: MIT

README

✨ Go Gemini Client

CI Language Go Version GitHub tag (latest by date) Go Reference Status

🎯 概要: Net Armor 統合型ハイブリッド Gemini クライアント

Go Gemini Client は、shouni/netarmor をリトライ基盤に採用した、Google Gemini API / Vertex AI 向けの Go ライブラリです。

ひとつのクライアントで、API Key 方式の Gemini API (Google AI Studio) と、Google Cloud 認証を使う Vertex AI を切り替えて利用できます。テキスト生成だけでなく、GCS URI や File API を使ったマルチモーダル入力、画像・音声レスポンス、Lyria による音楽生成ワークフローも扱えるように設計されています。


💎 特徴と設計思想

🤖 ハイブリッド・バックエンド・サポート
  • Dual Backend: APIKey 方式と ProjectID / LocationID 方式の両方に対応。
  • Vertex AI 連携: Cloud Run などの環境ではサービスアカウントや Application Default Credentials を利用できます。
  • GCS 直接参照: Vertex AI では gs:// URI を genai.Part として直接プロンプトに含められます。
🛡️ 堅牢な AI クライアント (gemini)
  • 高度なリトライ戦略: netarmor の retry を利用し、一時的なネットワーク障害や API 側の一過性エラーを指数バックオフで再試行します。
  • リトライ不要エラーの判定: セーフティフィルタによるブロックや空レスポンスなど、再試行しても解決しにくい API レスポンスエラーを識別します。
  • 決定論的な制御: Seed により、生成結果の再現性を必要とするワークフローをサポートします。
  • 型安全なエラー判定: 設定不備や入力不備はセンチネルエラーとして公開しており、errors.Is で判定できます。
  • ストリーミング生成: GenerateContentStream / GenerateWithPartsStreamiter.Seq2 によるチャンク単位のレスポンスを受け取れます。
  • トークン数の事前計測: CountTokens / CountTokensWithParts で、実際に生成せずにプロンプトのトークン数を見積もれます。
📁 高度なリソース管理
  • File API サポート: ファイルアップロード後、利用可能な Active 状態になるまで自動でポーリングします。
  • 自動クリーンアップ: Active 化に失敗した File API オブジェクトはバックグラウンドで削除を試みます。
  • レスポンス抽出: テキスト、生成画像、生成音声、トークン使用量 (Usage) を gemini.Response にまとめて返します。
🎼 Lyria ワークフロー (lyria)
  • 作詞から音声生成までの統合: 歌詞生成、作曲レシピ生成、Lyria 音声生成を Workflow で一括実行できます。
  • 構造化出力: 歌詞・レシピ生成は ResponseSchema による constrained decoding を使い、JSON 以外のノイズ混入を防ぎます。
  • 重複呼び出し抑制: singleflight により、同一条件の音声生成リクエストをまとめます。

🚀 クイックスタート

インストール
go get github.com/shouni/go-gemini-client
1. Gemini API モード (API Key 方式)
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/shouni/go-gemini-client/gemini"
)

func main() {
	ctx := context.Background()

	client, err := gemini.NewClient(ctx, gemini.Config{
		APIKey: "YOUR_GEMINI_API_KEY",
	})
	if err != nil {
		log.Fatal(err)
	}

	resp, err := client.GenerateContent(ctx, "gemini-2.5-flash", "Goで短い俳句を書いて")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(resp.Text)
}
2. Vertex AI モード (Cloud Run / GCS 連携)
client, err := gemini.NewClient(ctx, gemini.Config{
	ProjectID:  "your-google-cloud-project-id",
	LocationID: "asia-northeast1",
})
if err != nil {
	return err
}

Vertex AI モードでは、Google Cloud 側の認証情報を利用します。Cloud Run などの環境では API Key をアプリケーションに持たせずに運用できます。


🧩 マルチモーダル生成

GenerateWithParts は公式 SDK の genai.Part をそのまま受け取ります。テキスト、画像、GCS URI、File API の URI などを組み合わせた入力に対応できます。

parts := []*genai.Part{
	{
		FileData: &genai.FileData{
			URI:      "gs://my-bucket/sample.jpg",
			MIMEType: "image/jpeg",
		},
	},
	{Text: "この画像の内容を日本語で要約してください"},
}

resp, err := client.GenerateWithParts(ctx, "gemini-2.5-flash", parts, gemini.GenerateOptions{
	SystemPrompt: "簡潔に回答してください。",
})
if err != nil {
	return err
}

fmt.Println(resp.Text)

🖼️ 画像・音声レスポンス

ResponseMIMETypeimage/* または audio/* を指定すると、レスポンスモダリティが自動設定されます。Inline data は Response.Images または Response.Audios に格納されます。

seed := int64(1234)

resp, err := client.GenerateWithParts(ctx, "gemini-2.5-flash-image-preview", []*genai.Part{
	{Text: "青い招き猫のステッカー画像を生成して"},
}, gemini.GenerateOptions{
	ResponseMIMEType: "image/png",
	AspectRatio:      "1:1",
	ImageSize:        "1K",
	Seed:             &seed,
})
if err != nil {
	return err
}

if len(resp.Images) > 0 {
	// resp.Images[0] contains image bytes.
}

📤 File API

Gemini API の File API を使う場合は、アップロード後にファイルが Active になるまで自動で待機します。

f, err := os.Open("movie.mp4")
if err != nil {
	return err
}
defer f.Close()

uri, name, err := client.UploadFile(ctx, f, "video/mp4", "movie.mp4")
if err != nil {
	return err
}
defer client.DeleteFile(context.Background(), name)

resp, err := client.GenerateWithParts(ctx, "gemini-2.5-flash", []*genai.Part{
	{
		FileData: &genai.FileData{
			URI:      uri,
			MIMEType: "video/mp4",
		},
	},
	{Text: "この動画を要約してください"},
}, gemini.GenerateOptions{})

📶 ストリーミング生成

GenerateContentStream / GenerateWithPartsStream は、genai SDK の iter.Seq2 をそのまま gemini.Response のストリームに変換して返します。チャンク単位でエラーが発生した場合は、そのチャンクの error 戻り値として伝播します(ストリーム開始後のリトライは行いません)。

seq, err := client.GenerateContentStream(ctx, "gemini-2.5-flash", "Goについて3行で説明して")
if err != nil {
	return err
}

for resp, err := range seq {
	if err != nil {
		return err
	}
	fmt.Print(resp.Text)
}

🔢 トークン数の計測

CountTokens / CountTokensWithParts は、実際に生成を行わずにプロンプトのトークン数だけを計測します。事前のコスト見積もりやコンテキスト長の検証に使えます。

total, err := client.CountTokens(ctx, "gemini-2.5-flash", "Goについて3行で説明して")
if err != nil {
	return err
}
fmt.Println("推定トークン数:", total)

生成レスポンス自体のトークン使用量は Response.UsagePromptTokenCount / CandidatesTokenCount / TotalTokenCount)から参照できます。


🎵 Lyria Workflow

lyria パッケージは、歌詞生成・作曲レシピ生成・Lyria 音声生成を束ねるファサードです。利用側で TextPromptGeneratorAudioPromptBuilder を実装し、プロダクト固有のプロンプト設計を差し込めます。

workflow, err := lyria.New(
	client,
	promptGenerator,
	audioPromptBuilder,
	lyria.WithGeminiModel("gemini-2.5-flash"),
	lyria.WithLyriaModel("lyria-realtime-exp"),
)
if err != nil {
	return err
}

recipe, wavBytes, err := workflow.Run(ctx, lyria.AIModels{}, &lyria.CollectedContent{
	Prompt: "夜の東京を走るシンセポップ",
})

WithRateInterval は音声生成(Lyria 呼び出し)、WithTextRateInterval は歌詞・レシピ生成(Gemini 呼び出し)のレート制限間隔をそれぞれ設定します。いずれも未設定(ゼロ値)の場合はレート制限を行いません。


⚙️ 詳細設定 (gemini.Config)

設定項目 役割 デフォルト値
APIKey Gemini API キー。Google AI Studio / Gemini API で利用します。 -
ProjectID Google Cloud プロジェクト ID。Vertex AI で利用します。 -
LocationID Vertex AI のリージョン。例: asia-northeast1, us-central1 -
MaxRetries 最大リトライ回数 1
InitialDelay リトライ開始時の待機時間 30s
MaxDelay リトライ待機時間の上限 120s
FilePollingInterval File API の状態確認間隔 2s
FilePollingTimeout File API の状態確認タイムアウト 60s

APIKeyProjectID / LocationID は排他的です。Vertex AI を使う場合は ProjectIDLocationID の両方を指定してください。


🧪 生成オプション (gemini.GenerateOptions)

設定項目 役割
SystemPrompt System instruction を指定します。
AspectRatio 画像生成時のアスペクト比を指定します。
ImageSize 画像生成時のサイズを指定します。
Seed 再現性のためのシード値。int32 の範囲内である必要があります。
PersonGeneration Vertex AI 画像生成での人物生成ポリシーを指定します。
SafetySettings SDK の SafetySettings を指定します。
ResponseMIMEType image/pngaudio/wav など、期待するレスポンス MIME type を指定します。
ResponseSchema 構造化出力(constrained decoding)のスキーマ。application/json と併用すると、出力が文法レベルでスキーマに制約されます。

標準的な4つのハームカテゴリ(暴力・ヘイト・性的表現・危険行為)すべてに同一の閾値を適用したい場合は、gemini.NewSafetySettings(threshold) ヘルパーを使うと SafetySettings を簡潔に構築できます。閾値をバックエンドや用途に応じてどう選ぶかは呼び出し側の判断に委ねています。

opts := gemini.GenerateOptions{
    SafetySettings: gemini.NewSafetySettings(genai.HarmBlockThresholdBlockNone),
}

ResponseSchema + ResponseMIMEType: "application/json" による構造化出力(constrained decoding)を使っても、モデルが完結した JSON の後に余分な閉じ括弧や説明テキストを継ぎ足すことが実際にあります。json.Unmarshal の前段で gemini.CleanJSONResponse(raw) を通すと、こうした末尾ノイズを除去・補正できます。

resp, err := client.GenerateWithParts(ctx, model, parts, opts)
// ...
var out MyStruct
jsonStr := gemini.CleanJSONResponse(resp.Text)
if err := json.Unmarshal([]byte(jsonStr), &out); err != nil {
    // ...
}

📜 エラーハンドリング

本ライブラリでは、以下のセンチネルエラーをエクスポートしています。errors.Is を使って判定できます。

  • ErrConfigRequired: APIKey または ProjectID / LocationID のいずれも設定されていない場合。
  • ErrExclusiveConfig: APIKeyProjectID / LocationID が同時に設定されている場合。
  • ErrIncompleteVertexConfig: ProjectID または LocationID の片方だけが設定されている場合。
  • ErrEmptyPrompt: プロンプトが空の場合。
  • ErrEmptyModelName: モデル名が空の場合。
  • ErrEmptyParts: 生成パーツが空の場合。
  • ErrInvalidPart: 生成パーツに nil が含まれている場合。
  • ErrInvalidSeed: Seedint32 の範囲外の場合。

📂 パッケージ構成

パッケージ 役割
github.com/shouni/go-gemini-client/gemini Gemini / Vertex AI クライアント、リトライ、File API、レスポンス抽出。
github.com/shouni/go-gemini-client/lyria 歌詞生成、作曲レシピ生成、Lyria 音声生成の統合アダプタ。

🤝 依存関係 (Dependencies)


📜 ライセンス (License)

このプロジェクトは MIT License の下で公開されています。

Directories

Path Synopsis
Package gemini は、Gemini API / Vertex AI 向けの genai SDK をラップし、 リトライやFile APIアップロードを備えたクライアントを提供します。
Package gemini は、Gemini API / Vertex AI 向けの genai SDK をラップし、 リトライやFile APIアップロードを備えたクライアントを提供します。
Package lyria は、歌詞生成・楽曲設計・Lyriaによる音声生成を束ねる 音楽生成ワークフローを提供します。
Package lyria は、歌詞生成・楽曲設計・Lyriaによる音声生成を束ねる 音楽生成ワークフローを提供します。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL