Bookshelf ビルダー: Gemini を使用して Gemini アプリケーション用の Java Cloud Functions を作成する

1. はじめに

本を読むのは好きだけれど、選択肢が多すぎて困っている方へ。AI 搭載アプリが、最適な本をおすすめするだけでなく、選択したジャンルに基づいてあらすじを提供し、内容を簡単に紹介してくれるとしたらどうでしょう。この Codelab では、Gemini を活用した BigQuery と Cloud Functions を使用して、このようなアプリを作成する方法について説明します。

プロジェクトの概要

このユースケースは、次の 4 つの主要なコンポーネントが中心です。

  • 書籍データベース: インターネット アーカイブ書籍の大規模な BigQuery 一般公開データセットは、包括的な書籍カタログとして機能します。
  • AI Summarization Engine: 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. 要件

  • ブラウザ(ChromeFirefox など)
  • 課金を有効にした Google Cloud プロジェクト

前提条件は次のとおりです。

プロジェクトを作成する

  1. Google Cloud コンソールのプロジェクト選択ページで、Google Cloud プロジェクトを選択または作成します。
  2. Cloud プロジェクトに対して課金が有効になっていることを確認します。詳しくは、プロジェクトで課金が有効になっているかどうかを確認する方法をご覧ください。

Cloud Shell をアクティブにする

  1. Cloud Shell を使用します。Cloud Shell は Google Cloud で実行されるコマンドライン環境で、bq があらかじめ組み込まれています。

Cloud コンソールで、右上にある [Cloud Shell をアクティブにする] をクリックします。6757b2fb50ddcc2d.png

  1. Cloud Shell に接続すると、すでに認証は完了しており、プロジェクトに各自のプロジェクト ID が設定されていることがわかります。Cloud Shell で次のコマンドを実行して、認証されたことを確認します。
gcloud auth list
  1. Cloud Shell で次のコマンドを実行して、gcloud コマンドがプロジェクトを認識していることを確認します。
gcloud config list project
  1. プロジェクトが設定されていない場合は、次のコマンドを使用して設定します。
gcloud config set project <YOUR_PROJECT_ID>

gcloud コマンドとその使用方法については、ドキュメントをご覧ください。

4. Gemini for Google Cloud と必要な API を有効にする

Gemini を有効にする

  1. Marketplace の Gemini for Google Cloud に移動して API を有効にします。次のコマンドも使用できます。
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID
  1. Gemini のページにアクセスして、[Start chatting] をクリックします。

重要: こちらの Codelab のステップ 1 と 2 に沿って Gemini の使用を開始し、Cloud Shell IDE で Gemini を有効にします。

その他の必要な API を有効にする

どのように有効にするのでしょうか?Gemini に聞いてみましょう。ただし、その前に以下の点に注意してください。

LLM は非決定的です。そのため、これらのプロンプトを試しているときに受け取るレスポンスがスクリーンショット内のレスポンスとは異なる場合があります。

Google Cloud コンソールの右上の「Gemini を開く」アイコン(検索バーの横)をクリックして、Gemini チャット コンソールに移動します。

26e1491322855614.png

[ここにプロンプトを入力] に次の質問を入力します。

How do I enable the cloud functions api using a gcloud command? 

次のようなレスポンスが返されます。

gcloud services enable cloudfunctions.googleapis.com

これをコピーし(コマンド スニペットの上部にあるコピーアイコンを使用できます)、Cloud Shell ターミナルで実行して Cloud Functions を有効にします。Cloud Functions をビルドしてデプロイするには、Cloud Run でも同じ操作を行う必要があります。

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 エディタを開きます。ターミナルとエディタを別々のタブで同時に開き、一方でコードを記述し、もう一方でビルドする方法がおすすめです。

edd258384bc74f1f.png

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

両方がアクティブになったら、左下のプロジェクト名をクリックし、表示された [Cloud Code] というポップアップ リストで [New Application] までスクロールします。

ca08602b576ebd57.png

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

ac2b44245949da68.png

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

bf9cfe86e35cdced.png

今回は、シンプルな Java Cloud Functions アプリケーションを Gemini でブートストラップしましたが、構成の有効化と有効化以外はそれほど行われていませんでした。

プロジェクトの構造は次のようになります。

d56e410fb76f183f.png

これで、関数をデプロイできるようになりました。しかし、目的はそれではありません。次に、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 呼び出しコードを実装するソースコードで使用しているためです。

結果は次のとおりです。

62c4295b9b4654e9.png

 <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>google-cloud-vertexai</artifactId>
      <version>0.1.0</version>
    </dependency>

これをコピーして、pom.xml ファイルの </identify> タグの直前に貼り付けます。バージョンを 0.1.0 に置き換えます(Spring Cloud GCP BOM を使用して spring-cloud-gcp バージョン番号を管理している場合は、<version> タグを削除できます)。

依存関係セクションは次のようになります。

1800f10af9331210.png

必要に応じて、バージョン番号を上記に合わせて更新してください。お気づきのように、ここに別の依存関係も含まれています。

    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.10</version>
    </dependency>

7. 関数のエントリ ポイントとクラス名を変更します。

  1. [.vscode] フォルダの [launch.json] ファイルに移動します。関数名を「function-hello-world」から「function-gemini-calling」に編集します。
  2. entryPoint 値を「cloudcode.helloworld.HelloWorld」から cloudcode.bookshelf.Bookshelf に更新します。
  3. Java クラスファイル「HelloWorld.java」に移動します。パッケージ名を package cloudcode.bookshelf に変更します。表示されたエラーで、黄色い電球をクリックし、[Move HelloWorld.java to package cloudcode.bookshelf] オプションをクリックします。

38d721978bddc8a8.png

  1. クラス名を 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 チャット オプションを使って、コードを説明してみてください。または、コードをすべて選択し、選択範囲の左上にある黄色い電球をクリックして、[これを説明] オプションを選択することもできます。

66fb67507793e368.png

9. Cloud Functions の関数をデプロイする

Cloud Functions の関数を作成したので、デプロイ方法を Gemini に尋ねてみましょう。Cloud Code エディタの Gemini チャットに移動し、次のように入力します。

   How to deploy this Cloud Function with a gcloud command?

以下の回答がありました。

9f9db98933841864.png

詳しく調査したいと思いました。そこで、Gemini に gcloud functions deploy コマンドの完全な形式を尋ねました。レスポンスは次のようになります。

b77701c00dc3eaf1.png

同じ回答が返されるかどうかはわかりませんが、以下の画像のように、詳細が追加されていることに驚きました。

リクエスト本文の形式:

82bf20304143a374.png

レスポンスの形式:

ade55b3de5d823a6.png

次に、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

「新しい関数 [bookshelf] の認証されていない呼び出しを許可しますか?」というメッセージが表示されます。「y」と言って Enter キーを押します。その後、必要に応じていくつかの質問に回答すると、デプロイされた URL(https://us-central1-*******.cloudfunctions.net/bookshelf)を使用してサーバーレス Cloud Functions がデプロイされます。

デプロイした Cloud Functions の関数を呼び出してテストしましょう。

注: 「認証されていない呼び出しを許可する」という質問を誤ってスキップした場合や、「いいえ」を選択した場合、Cloud Functions の結果にアクセスできず、追加の IAM 設定を付与しないと「権限エラー」が表示されます。ご注意ください。

10. デプロイされた Cloud Functions 関数を呼び出す

Gemini に聞いてみましょう。プロンプトを入力しました

How to call the deployed cloud function?

次の結果が返されました(まったく同じ回答が表示される場合もあれば、異なる場合もあります)。プロンプトをいろいろ試して、回答の違いを確認してください。

1d2242715571fe6f.png

デプロイされた関数を呼び出す別の方法、gcloud コマンドを使用した呼び出しなどについて、具体的な質問でチャットを探ります。私は次のメッセージを送信しました。

how to call the deployed cloud function using gcloud

次のようなレスポンスが返されました。e7b29b2cfb57782c.png

このレスポンス(「gcloud functions call」コマンド)をターミナルから使用し、シナリオに合わせて調整して使用できます(または、プロンプト自体でパラメータを渡して、レスポンスで詳細な gcloud functions 呼び出しを取得できるかどうかを確認することもできます)。

gcloud functions call bookshelf --region=us-central1 --gen2 --data '{"calls":[["Hello! This is my test prompt."]]}'

結果は次のとおりです。

6f396d915251db78.png

11. クリーンアップ

前に作成した Cloud Functions を削除するには、Cloud Functions の詳細ページで [削除] ボタンをクリックします。

12. 完了

Gemini を使用して Gemini 1.0 Pro を呼び出す Java Cloud Functions の関数をビルド、デプロイ、テストしました。このアプリケーションは、書籍の概要とテーマを含む書籍のおすすめに関する入力プロンプトを受け取ります。