GCPでGeminiを使用するチャットエンドポイントを作成する

GCPではGeminiを使用するためのAPIが提供されており、それをカスタムしてチャットエンドポイントとして提供することができます。

本記事では、Pythonでコーディングを行い、ユーザーからのチャットに対してあらかじめ定義したシステムプロンプトを基に回答生成するエンドポイントの作成手順を示します。

前準備

Google Cloud CLIのインストール

以下の手順に従って、Google Cloud CLIのインストールを実施します。

cloud.google.com

インストール後、コマンドプロンプトなどから以下のコマンドを実行します。

gcloud init

コマンド実行後、サインインを求められます。GCPを使用しているアカウントでサインインします。

You must sign in to continue. Would you like to sign in (Y/n)? 

サインイン後、対象プロジェクトの一覧が表示されます。ここではチャットエンドポイントを作成するプロジェクト番号を指定します。

You are signed in as: [XXXXXXXXX].

Pick cloud project to use:
 [1] XXX-sample-project-XXXXXX
 [2] phrasal-vent-XXXXXX-XX
 [3] Enter a project ID
 [4] Create a new project
Please enter numeric choice or text value (must exactly match list item):  

デフォルトリージョンの設定について聞かれますが、ここはnを選択します。

Do you want to configure a default Compute Region and Zone? (Y/n)?  n

以上で、CLIの前準備は完了です。

Python環境の準備

venvやanacondaなどを使用して、ローカルでPythonの実行環境を準備しておきます。このときバージョンは3.8以上である必要があります。

今回の記事では3.11の仮想環境で作業を実施します。

シークレットの格納

APIキーの取得

GCPのコンソールを開きます。

console.cloud.google.com

自身のプロジェクトにアクセスし、左側のメニューから[APIとサービス]-[認証情報]を選択します。

「+認証情報を作成」からAPIキーを選択すると、その時点でAPIキーが作成されます。この文字列をコピーしておきます。

Secret Managerへの格納

今回は、APIキーを使用してGeminiへのアクセスを行います。まずはGCPのコンソールからSecret ManagerのAPIを検索して、有効化します。

「+シークレットの作成」を選択します。

任意の名前でシークレットを管理します。今回はGCP_API_KEYと設定し、APIキーには取得した文字列を代入。その他の項目は任意に設定して、「シークレットを作成」を選択します。

作成に成功すると、以下の通りステータスが「有効」となったバージョン1のキーが表示されます。

ここでprojects/{PROJECT_ID}/secrets/{SECRET_ID}/versions/latestという形式で表示されている文字列は後に使うため、ここでコピーしておきます。

トークンの発行

サービスアカウントの作成

ローカル環境からデプロイしたAPIにアクセスするために、トークンを発行する必要があります。トークンを発行するためのサービスアカウントを作成します。

[IAMと管理]-[サービスアカウント]を選択し、「サービスアカウントを作成」ボタンをクリックして、任意の名前を入力します。

APIを呼び出す権限のみ設定する場合は「Cloud Functions 起動元」「Cloud Run 起動元」の2種を選択します。今回はAPIのデプロイ等の操作も含むため、オーナー権限を設定し、「完了」をクリックしてサービスアカウントを作成します。

作成したサービスアカウントの詳細で「鍵を管理」を選択します。「鍵を追加」ボタンをクリックして「新しい鍵を作成」を選択し、JSON形式でダウンロードします。

Google OAuth 2.0トークンの取得

ローカル環境のCloud SDKから、Google OAuth 2.0トークンを発行します。

gcloud auth activate-service-account --key-file=[ダウンロードしたjsonファイルパス]
gcloud auth print-identity-token

ここで表示されるトークンをコピーしておきます。このトークンは通常1時間で期限切れとなるため、必要に応じてコマンドを実行して再発行します。

作業手順

コーディング

以下のソースコードを用意します。PROJECT_IDの項目には、[IAMと管理]-[IAM]のDefault compute service accountの項目を参照し、プリンシパルの数字を入力します。

例えば123456789012-compute@developer.gserviceaccount.comであった場合は、「123456789012」を指定します。

import json
import os
import PIL.Image
import google.generativeai as genai
from google.cloud import secretmanager


PROJECT_ID = ""

def access_secret(secret_id):
    # Secret Managerクライアントを作成
    client = secretmanager.SecretManagerServiceClient()
    
    # シークレットのリソース名を指定
    name = f"projects/{PROJECT_ID}/secrets/{secret_id}/versions/latest"

    # シークレットを取得
    response = client.access_secret_version(name=name)
    return response.payload.data.decode('UTF-8')  # バイトデータを文字列にデコード  


    
def hello_world(request):
    return "Hello, World!"

def gemini_request(request):
    try:
        api_key = access_secret("GCP_API_KEY")
        genai.configure(api_key=api_key)

        # リクエストボディを文字列として取得
        user_input = request.get_data(as_text=True)  # ボディを文字列として取得

        # モデルを初期化
        model = genai.GenerativeModel(model_name="gemini-1.5-flash")

        # コンテンツを生成
        print("user_input:",user_input)
        response = model.generate_content([user_input])  # 文字列をリクエストに渡す
        return response.text
    except Exception as e:
        print(e)
        return f"Error: {str(e)}", 500  # エラーメッセージを返す

パッケージの準備

Google Cloud Functionsで必要なパッケージを、requirements.txtに定義します。

Flask==3.0.3
google-generativeai==0.8.3
google-cloud-secret-manager==2.21.0
pillow==11.0.0

関数のデプロイ

以下の通り、関数をコマンドでデプロイします。関数1つにつき一度コマンドを実行します。

cd [ファイルの存在するディレクトリ]
gcloud functions deploy hello_world --runtime python311 --trigger-http --entry-point hello_world
gcloud functions deploy gemini_request --runtime python311 --trigger-http --entry-point gemini_request

認証について質問されます。「y」の場合は認証無しで関数が使えるようになりますが、今回は「N」を入力します。

Allow unauthenticated invocations of new function [gemini_request]? (y/N)?

デプロイ完了後、コマンドプロンプトに次のように表示されます。末尾のURLを使用してデプロイした関数を使用します。

state: ACTIVE
updateTime: [デプロイ日時]
url: https://[リージョン]-[プロジェクトID].cloudfunctions.net/[関数名]

Cloud ConsoleのCloud Run関数のページに「Hello World」「gemini_request」関数が表示されていることが分かります。

IAMの設定

使用する関数がシークレットを使用する場合、アクセス権限(IAM)を設定する必要があります。

関数を開いて[詳細]タブを選択して、「サービスアカウント」の項目をチェックします。

左のメニューから「IAMと管理」-「IAM」をクリックします。そしてCloud Functionsが使用しているサービスアカウントを見つけます。通常、[ID]-compute@developer.gserviceaccount.comという形式です。

サービスアカウントを編集して、「+別のロールを追加」を選択します。

secretmanagerのsecretAccessorロールをサービスアカウントに付与します。このロールは、シークレットにアクセスするための権限を持っています。

Bearer Tokenの設定

関数にアクセスするために認証が必要になります。OAuthトークンがない場合、以下のように401リクエストが返ってきます。

以下のようにヘッダーを設定することで、認証を行うことができます。Bearer Tokenの期限は1時間ですので、もし期限が切れていた場合は上記手順に従って再発行してください。

Key Value
Authorization Bearer [コピーしたGoogle OAuth 2.0トークン]

リクエストの送信

Hello World関数

次のURLに対して、GETリクエストを送ります。

https://[リージョン]-[プロジェクトID].cloudfunctions.net/hello_world

指定した通り「Hello, World!」のレスポンスを取得できます。

gemini_request関数

次のURLに対して、任意の文章をbodyに入れつつPOSTリクエストを送ります。

https://[リージョン]-[プロジェクトID].cloudfunctions.net/gemini_request

Cloud Run関数がシークレットに格納したAPIキーを使用して、Geminiにリクエストを送信します。

おわりに

本記事では、GCP上でGeminiを利用するためのチャットエンドポイントをPythonで構築する方法を詳しく説明しました。

Google Cloud CLIやSecret Manager、サービスアカウントの設定を経て、関数をデプロイし、実際にリクエストを送信する手順を示しました。特に、APIキーやOAuthトークンを適切に管理することで、セキュリティリスクを軽減しつつ、効果的なアプリケーション運用が可能となります。

今後は、実装したチャットエンドポイントにさらなる機能を追加したり、性能の最適化を行ったりすることで、より洗練されたサービスを提供できるでしょう。

GCPとGeminiを活用したプロジェクトが、皆さまの新たなプロジェクトの実現に寄与できることを願っています。

執筆担当者プロフィール
西野 佑基

西野 佑基(日本ビジネスシステムズ株式会社)

機械学習系ソリューション開発、業務Webアプリ開発、開発環境自動化などを担当。

担当記事一覧