1. はじめに
本を読むのは好きだけれど、選択肢が多すぎて困っている方へ。AI 搭載アプリが、最適な本をおすすめするだけでなく、選択したジャンルに基づいてあらすじを提供し、内容を簡単に紹介してくれるとしたらどうでしょう。この Codelab では、Gemini を搭載した BigQuery と Cloud Functions を使用して、このようなアプリをビルドする方法について説明します。
プロジェクトの概要
このユースケースは、次の 4 つの主要なコンポーネントが中心です。
- 書籍データベース: インターネット アーカイブの書籍の BigQuery 一般公開データセットを包括的な書籍カタログとして使用します。
- AI サマリー エンジン: Gemini-Pro 言語モデルを搭載した Google Cloud Functions が、ユーザーのリクエストに合わせて有益な要約を生成します。
- BigQuery の統合: BigQuery 内のリモート関数。Cloud Functions を呼び出して、オンデマンドで書籍の要約とテーマを配信します。
- ユーザー インターフェース: Cloud Run でホストされるウェブアプリ。ユーザーが結果を確認するためのウェブ アプリケーションを提供します。
実装を 3 つの Codelab に分割します。
Codelab 1: Gemini を使用して、Gemini アプリケーション用の Java Cloud Functions の関数をビルドする。
Codelab 2: Gemini を使用して、BigQuery で SQL のみの生成 AI アプリケーションをビルドする。
Codelab 3: Gemini を使用して、BigQuery とやり取りする Java Spring Boot ウェブ アプリケーションを作成する。
2. Gemini を使用して、Java Cloud Functions で生成 AI アプリをサーバーレスでビルドする
作成するアプリの概要
このチュートリアルでは、
- Gemini 1.0 Pro を実装して、特定のプロンプトを JSON 配列の形式で入力として受け取り、レスポンス(「replies」というラベルの付いた JSON 値)を返す Java Cloud Functions アプリケーション。
- Gemini のサポートを受けながらビルドとデプロイの手順を行います。
3. 要件
前提条件は次のとおりです。
プロジェクトを作成する
- Google Cloud コンソールのプロジェクト選択ページで、Google Cloud プロジェクトを選択または作成します。
- Cloud プロジェクトに対して課金が有効になっていることを確認します。詳しくは、プロジェクトで課金が有効になっているかどうかを確認する方法をご覧ください。
Cloud Shell をアクティブにする
- Cloud Shell(Google Cloud で動作するコマンドライン環境)を使用します。この環境には bq がプリロードされています。
Cloud コンソールで、右上にある [Cloud Shell をアクティブにする] をクリックします。
- Cloud Shell に接続すると、すでに認証は完了しており、プロジェクトに各自のプロジェクト ID が設定されていることがわかります。Cloud Shell で次のコマンドを実行して、認証されたことを確認します。
gcloud auth list
- Cloud Shell で次のコマンドを実行して、gcloud コマンドがプロジェクトを認識していることを確認します。
gcloud config list project
- プロジェクトが設定されていない場合は、次のコマンドを使用して設定します。
gcloud config set project <YOUR_PROJECT_ID>
gcloud コマンドとその使用方法については、ドキュメントをご覧ください。
4. Gemini for Google Cloud と必要な API を有効にする
Gemini を有効にする
- Marketplace の Gemini for Google Cloud に移動して、API を有効にします。次のコマンドも使用できます。
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID
- Gemini のページにアクセスして、[チャットを開始] をクリックします。
重要: Gemini の使用を開始し、Cloud Shell IDE で Gemini を有効にするには、この Codelab の手順 1 と 2 に沿って操作してください。
その他の必要な API を有効にする
どのように有効にするのでしょうか?Gemini に聞いてみましょう。ただし、その前に以下の点に注意してください。
LLM は非決定的です。そのため、これらのプロンプトを試しているときに受け取るレスポンスがスクリーンショット内のレスポンスとは異なる場合があります。
Google Cloud コンソールの右上の「Gemini を開く」アイコン(検索バーの横)をクリックして、Gemini チャット コンソールに移動します。

[ここにプロンプトを入力] に次の質問を入力します。
How do I enable the cloud functions api using a gcloud command?
次のようなレスポンスが返されます。
gcloud services enable cloudfunctions.googleapis.com
コピーして(コマンド スニペットの上部にあるコピーアイコンを使用できます)、Cloud Shell ターミナルで実行し、Cloud Functions を有効にします。Cloud Run についても同様に操作します。Cloud Functions のビルドとデプロイを行うには、両方が必要です。
gcloud services enable \
cloudfunctions.googleapis.com \
aiplatform.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com
5. Gemini を使用して Cloud Functions テンプレートを準備する
この時点で、Cloud Shell IDE で Gemini がすでに有効になっていることを前提としています。
Cloud Shell ターミナルの右上にある [エディタを開く] アイコンをクリックして Cloud Shell エディタを開きます。ターミナルとエディタを別々のタブで同時に開き、一方でコードを記述し、もう一方でビルドする方法がおすすめです。

エディタを開いたら、エディタ コンソールの右下にある Gemini ロゴがアクティブになっていること(およびキャンセルされていないこと)を確認します。また、左下の Google Cloud プロジェクトが、作業する現在のアクティブなプロジェクトを参照していることを確認します。アクティブになっていない場合は、クリックして承認し、参照する Google Cloud プロジェクトを選択してアクティブにします。
両方がアクティブになったら、左下のプロジェクト名をクリックし、表示された [Cloud Code] というポップアップ リストで [New Application] までスクロールします。

リストで、Cloud Functions アプリケーションを選択します。表示されたリストから [Java] を選択します。

表示されたリストで、「helloworld」ではなくプロジェクト名「duetai-gemini-calling」を入力して、[OK] をクリックします。

今回は、シンプルな Java Cloud Functions アプリケーションを Gemini でブートストラップしました。有効化とアクティベーションの構成以外ですることはほとんどありませんでしたね。
プロジェクトの構造は次のようになります。

これで、関数をデプロイできるようになりました。しかし、目的はそれではありません。Java SDK を使用して、この Cloud Functions で Gemini Pro API の実装を構築しましょう。
次に、この Cloud Functions で Gemini Pro モデルを呼び出すというユースケースの機能を作成します。そのためには、プロンプトを追加して Gemini でコードを段階的に開発するか、自分でロジックを記述します。ここでは、両方を組み合わせて使用します。
6. 依存関係を追加する
Gemini チャット コンソール(左側のペインの Cloud Code エディタ内)に、次のプロンプトを入力します。
what is the maven dependency for com.google.cloud.vertexai library
com.google.cloud.vertexai パッケージを具体的にリクエストしているのは、Gemini 呼び出しコードを実装するソースコードで使用しているためです。
次のような結果が得られました。

<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-vertexai</artifactId>
<version>0.1.0</version>
</dependency>
これをコピーして、pom.xml ファイルの </dependencies> タグの直前に貼り付けます。バージョンを 0.1.0 に置き換えます(Spring Cloud GCP BOM を使用して spring-cloud-gcp のバージョン番号を管理している場合は、<version> タグを削除できます)。
依存関係セクションは次のようになります。

必要に応じて、バージョン番号を上記に合わせて更新してください。ご覧のとおり、これには別の依存関係も含まれています。
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10</version>
</dependency>
7. 関数のエントリ ポイントとクラス名を変更する
- [.vscode] フォルダにある launch.json ファイルに移動します。関数名を「function-hello-world」から「function-gemini-calling」に変更します。
- entryPoint の値を cloudcode.helloworld.HelloWorld から cloudcode.bookshelf.Bookshelf に更新します。
- Java クラスファイル「HelloWorld.java」に移動します。パッケージ名を package cloudcode.bookshelf; に変更します。表示されたエラーで、黄色の電球をクリックし、[Move HelloWorld.java] オプションをクリックして、package cloudcode.bookshelf; に移動します。

- クラス名を Bookshelf に更新し、表示されたエラーで小さな黄色の電球をクリックして、[Rename file to Bookshelf.java] を選択します。それを選択します。
8. Gemini Pro を呼び出すメソッドを作成する
この機能を Bookshelf.java クラスに実装しましょう。Bookshelf.java を次のコードに置き換えます。
package cloudcode.bookshelf;
import java.io.BufferedWriter;
import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
import com.google.cloud.vertexai.VertexAI;
import com.google.cloud.vertexai.api.GenerateContentResponse;
import com.google.cloud.vertexai.api.GenerationConfig;
import com.google.cloud.vertexai.generativeai.preview.GenerativeModel;
import com.google.cloud.vertexai.generativeai.preview.ResponseHandler;
import java.io.IOException;
import java.util.List;
import java.util.Arrays;
import java.util.Map;
import java.util.LinkedHashMap;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonArray;
public class Bookshelf implements HttpFunction {
private static final Gson gson = new Gson();
@Override
public void service(HttpRequest request, HttpResponse response) throws Exception {
BufferedWriter writer = response.getWriter();
// Get the request body as a JSON object.
JsonObject requestJson = new Gson().fromJson(request.getReader(), JsonObject.class);
JsonArray calls_array = requestJson.getAsJsonArray("calls");
JsonArray calls = (JsonArray) calls_array.get(0);
String context = calls.get(0).toString().replace("\"", "");
//Invoke Gemini model
String raw_result = callGemini(context);
raw_result = raw_result.replace("\n","");
String trimmed = raw_result.trim();
List<String> result_list = Arrays.asList(trimmed);
Map<String, List<String>> stringMap = new LinkedHashMap<>();
stringMap.put("replies", result_list);
// Serialization
String return_value = gson.toJson(stringMap);
writer.write(return_value);
}
public String callGemini(String context) throws IOException{
String res = "";
try (VertexAI vertexAi = new VertexAI("REPLACE_WITH_YOUR_PROJECT_ID", "us-central1"); ) {
GenerationConfig generationConfig =
GenerationConfig.newBuilder()
.setMaxOutputTokens(2048)
.setTemperature(0.4F)
.setTopK(32)
.setTopP(1)
.build();
GenerativeModel model = new GenerativeModel("gemini-pro", generationConfig, vertexAi);
GenerateContentResponse response = model.generateContent(context);
res = ResponseHandler.getText(response);
}catch(Exception e){
System.out.println(e);
}
return res;
}
}
このクラスは、次のような JSON 構造の入力を想定しています。
{ "calls": [["YOUR_PROMPT_HERE"]] }
次のようなレスポンスが返されます。
(Json)Map<String, List<String>> {"replies": ["response"]}
左側のペインの Cloud Shell エディタから Gemini チャット オプションを試して、コードの説明を生成します。または、コードをすべて選択し、選択範囲の左上にある黄色の電球をクリックして、[これを説明] オプションを選択することもできます。

9. Cloud Functions の関数をデプロイする
Cloud Functions の準備ができたので、デプロイ方法について Gemini に尋ねてみましょう。Cloud Code エディタで Gemini チャットに移動し、次の内容を入力します。
How to deploy this Cloud Function with a gcloud command?
次のような回答が届きました。

さらに詳しく調べたいと思います。そこで、Gemini に gcloud functions deploy コマンド全体を教えてもらうことにしました。レスポンスは次のようになります。

同じレスポンスが返されるかどうかはわかりませんが、下の画像のように、詳細情報が追加されていて驚きました。
リクエスト本文の形式:

と
回答形式:

次に、Gemini が提示した gcloud コマンドを実行して、関数をデプロイします。これを行うには、Cloud Shell ターミナルを開く必要があります。https://console.cloud.google.com の新しいタブで開き、正しいプロジェクトが選択されていることを確認します。コンソールの右上にある [Cloud Shell をアクティブにする] アイコンをクリックして Cloud Shell ターミナルを開き、次のコマンドを使用して正しいプロジェクト フォルダにいることを確認します。
cd duetai-gemini-calling
次のコマンドを実行します。
gcloud functions deploy bookshelf --runtime java17 --trigger-http --entry-point cloudcode.bookshelf.Bookshelf --allow-unauthenticated
「Allow unauthenticated invocations of new function [bookshelf]?」と表示されます。「y」と入力して Enter キーを押します。その後、該当する場合はいくつかの質問が表示され、デプロイされた URL(https://us-central1-*******.cloudfunctions.net/bookshelf)を使用してサーバーレス Cloud Functions の関数がデプロイされます。
デプロイされた Cloud Functions を呼び出してテストしましょう。
注: 「認証されていない呼び出しを許可しますか?」という質問を誤ってスキップした場合や、「N」を選択した場合は、追加の IAM 設定を付与しないと、Cloud Functions の結果にアクセスできず、「権限エラー」が表示されます。そのため、この点に注意してください。
10. デプロイされた Cloud Functions を呼び出す
Gemini に聞いてみましょう。プロンプトを入力しました
How to call the deployed cloud function?
以下のような結果が得られました(まったく同じレスポンスが表示されるとは限りません。プロンプトをいろいろ試して、レスポンスの違いを確認してみてください)。

デプロイされた関数を呼び出す代替方法、gcloud コマンドを使用した呼び出しなどに関する具体的な質問をチャットで試しました。次のプロンプトを送信しました。
how to call the deployed cloud function using gcloud
以下のような回答が届きました。
このレスポンス(「gcloud functions call」コマンド)をターミナルで使用して、シナリオに合わせて調整できます(または、プロンプト自体でパラメータを渡して、レスポンスで詳細な gcloud functions call を取得できるかどうかを試してください)。
gcloud functions call bookshelf --region=us-central1 --gen2 --data '{"calls":[["Hello! This is my test prompt."]]}'
結果は次のとおりです。

11. クリーンアップ
以前に作成した Cloud Functions を削除するには、Cloud Functions の詳細ページで [削除] ボタンをクリックします。
12. 完了
Gemini を使用して Gemini 1.0 Pro を呼び出す Java Cloud Functions のビルド、デプロイ、テストが完了しました。このアプリケーションは、書籍の概要とテーマを含む書籍のおすすめに関する入力プロンプトを受け取ります。