Bookshelf 建構工具:使用 Gemini 建構 Gemini 應用程式的 Java Cloud 函式

1. 簡介

你喜歡閱讀書籍,但在眾多選擇中感到不知所措嗎?想像一下,如果有個 AI 輔助應用程式,不但能推薦適合你的閱讀內容,還能根據你偏好的類型提供精簡摘要,讓你一窺書籍精髓,那該有多好。在本程式碼研究室中,我將逐步說明如何使用 Gemini 提供的 BigQuery 和 Cloud Functions 建構這類應用程式。

專案總覽

我們的用途主要圍繞以下 4 個主要元件:

  • 圖書資料庫:我們擁有龐大的 BigQuery 公開資料集,內含眾多 網際網路封存書籍的公開資料集,做為我們完整的書籍目錄。
  • AI 摘要引擎:Google Cloud Functions 配備 Gemini-Pro 語言模型,可根據使用者要求產生有洞察力的摘要。
  • BigQuery 整合:BigQuery 中的遠端函式,可呼叫 Cloud Functions,以便隨選提供書籍摘要和主題。
  • 使用者介面:在 Cloud Run 上託管的網頁應用程式,可提供網頁應用程式供使用者查看結果。

我們會將實作項目分成 3 個程式碼研究室:

程式碼研究室 1:使用 Gemini 為 Gemini 應用程式建構 Java Cloud Function。

程式碼研究室 2:透過 BigQuery 使用 Gemini 建構 SQL 專用的生成式 AI 應用程式。

程式碼研究室 3:使用 Gemini 建立可與 BigQuery 互動的 Java Spring Boot 網頁應用程式。

2. 使用 Gemini,在 Java Cloud 函式以無伺服器的方式建構生成式 AI 應用程式

建構項目

您將建立

  • 實作 Gemini 1.0 Pro 的 Java Cloud Functions 應用程式,可將特定提示做為 JSON 陣列形式的輸入內容,並傳回回應 (標示為「replies」的 JSON 值)。
  • 您將在 Gemini 的協助下執行建構和部署步驟

3. 需求條件

  • ChromeFirefox 等瀏覽器
  • 已啟用計費功能的 Google Cloud 專案

使用條件如下:

建立專案

  1. Google Cloud 控制台的專案選取器頁面中,選取或建立 Google Cloud 專案
  2. 確認 Cloud 專案已啟用計費功能。瞭解如何檢查專案是否已啟用計費功能

啟用 Cloud Shell

  1. 您將使用 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. 啟用 Google Cloud 專用 Gemini 和必要的 API

啟用 Gemini

  1. 前往 Marketplace 中的 Gemini for Google Cloud 啟用 API。您也可以使用下列指令:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID
  1. 前往 Gemini 頁面,然後按一下「開始聊天」。

重要事項:請按照這個程式碼研究室中的步驟 1 和 2,分別開始使用 Gemini 和在 Cloud Shell IDE 中啟用 Gemini。

啟用其他必要的 API

我們要如何做到這一點?我們來問問 Gemini 吧。但在開始之前,請記住:

LLM 並非確定性,所以嘗試這些提示時,你收到的回應可能會與螢幕截圖中的回應不同。

前往 Gemini 對話主控台,在 Google Cloud 控制台的搜尋列旁邊,按一下右上角的「開啟 Gemini」圖示。

26e1491322855614.png

在「請輸入提示」部分輸入以下問題:

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

您應該會得到類似以下的回覆:

gcloud services enable cloudfunctions.googleapis.com

複製該指令 (您可以使用指令片段頂端的複製圖示),然後在 Cloud Shell 終端機中執行,即可啟用 Cloud 函式。請為 Cloud Run 執行相同的操作,因為我們需要這兩者才能建構及部署 Cloud 函式:

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 終端機右上角的「Open Editor」(開啟編輯器) 圖示,即可開啟 Cloud Shell 編輯器 (我通常會在不同的分頁中同時開啟終端機和編輯器,這樣就能在一個分頁中編寫程式碼,並在另一個分頁中進行建構)。

edd258384bc74f1f.png

開啟編輯器後,請確認編輯器控制台右下角的 Gemini 標誌處於啟用狀態 (且未取消)。此外,請確認左下角的 Google Cloud 專案指向您要使用的現有專案。如果這些專案處於「未啟用」狀態,請按一下並授權,選取要指向的 Google Cloud 專案,並啟用專案。

兩者都啟用後,請按一下左下角的專案名稱,然後在名為「Cloud Code」的彈出式清單中,向下捲動至「New Application」(新增應用程式)。

ca08602b576ebd57.png

在清單中選取 Cloud Functions 應用程式。在彈出的清單中,選取「Java」:

ac2b44245949da68.png

在結果清單中,輸入專案名稱「duetai-gemini-calling」(不要輸入 helloworld),然後按一下「OK」。

bf9cfe86e35cdced.png

太棒了!您已使用 Gemini 啟動簡單的 Java Cloud Functions 應用程式,除了啟用和啟動設定之外,您並未執行其他操作,對嗎?

您應該會看到以下專案結構:

d56e410fb76f183f.png

您現在可以部署函式了。但這並不是我們推出這項功能的原因。繼續使用 Java SDK,在這個 Cloud 函式中建構 Gemini Pro API 實作項目。

現在,讓我們根據用途建構功能,以在這個 Cloud 函式中叫用 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 檔案中,位於 </dependencies> 標記的「前面」。將版本替換為 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. 將 itemPoint 值從「cloudcode.helloworld.HelloWorld」更新為 cloudcode.Book.Bookshelf。
  3. 接著前往 Java 類別檔案「HelloWorld.java」。將套件名稱變更為 cloudcode.bookshelf;在彈出的錯誤訊息中,按一下黃色燈泡,然後點選「Move HelloWorld.java」至套件 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 結構如下:

{ &quot;calls&quot;: [[&quot;YOUR_PROMPT_HERE&quot;]] }

它會傳回以下回應:

(Json) Map<String, List<String>> {"replies": ["response"]}

請試著在左側窗格中使用 Cloud Shell 編輯器的 Gemini Chat 選項來說明程式碼。您也可以選取所有程式碼,然後按一下所選範圍左上角的黃色燈泡,然後選擇「說明」選項。

66fb67507793e368.png

9. 部署 Cloud 函式

Cloud 函式已準備就緒,接下來讓我們詢問 Gemini 的部署方式。前往 Cloud Code 編輯器中的 Gemini 對話,然後輸入以下內容:

   How to deploy this Cloud Function with a gcloud command?

我收到以下回覆:

9f9db98933841864.png

我現在想進一步探討這個問題。因此我請 Gemini 提供完整的 gcloud 函式部署指令。回應如下所示:

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 鍵。之後,系統會詢問幾個問題 (如適用),並透過下列部署網址部署無伺服器 Cloud Function:https://us-central1-*******.cloudfunctions.net/bookshelf。

現在,我們來叫用部署的 Cloud Functions 並進行測試!

注意:如果您不小心略過「允許未經認證的叫用」問題,或選取「否」,就無法存取 Cloud Functions 的結果,而且如果未授予其他 IAM 設定,就會看到「權限錯誤」訊息。請留意這一點

10. 呼叫已部署的 Cloud 函式

我們來問問 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 函式呼叫):

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

以下是我的結果:

6f396d915251db78.png

11. 清除所用資源

在 Cloud Functions 的詳細資料頁面中,按一下 [DELETE] (刪除) 按鈕,即可刪除您先前建立的 Cloud Functions。

12. 恭喜

您已成功建構、部署及測試 Java Cloud 函式,以便使用 Gemini 呼叫 Gemini 1.0 Pro!這個應用程式會使用書籍的摘要和主題,接收與書籍推薦相關的輸入提示。