在多模態要求中包含大型檔案,並使用 Cloud Storage for Firebase 管理檔案

使用 Vertex AI in Firebase SDK 從應用程式呼叫 Gemini API 時,您可以提示 Gemini 模型根據多模態輸入內容產生文字。多模態提示可包含多種模態 (或輸入類型),例如文字、圖片、PDF、影片和音訊。

針對輸入內容的非文字部分 (例如媒體檔案),您可以選擇使用 Cloud Storage for Firebase 在要求中加入檔案。以下是這項功能的概略說明:

  • 您可以將 Cloud Storage for Firebase 與任何多模態要求 (例如文字產生和聊天) 搭配使用。本指南的範例會顯示基本文字和圖片輸入內容。

  • 您可以在要求輸入內容中指定檔案的 MIME 類型和 Cloud Storage for Firebase 網址 (一律以 gs:// 開頭)。這些值是自動指派給上傳至 Cloud Storage 儲存桶的任何檔案的中繼資料。

  • 你必須使用系統支援的檔案類型和網址


本解決方案指南說明如何設定 Cloud Storage for Firebase、從應用程式將檔案上傳至 Cloud Storage for Firebase 儲存體,然後在 Gemini API 的多模式要求中加入檔案的 MIME 類型和 Cloud Storage for Firebase 網址。

您想查看程式碼範例嗎?或者,您是否已設定 Cloud Storage for Firebase,並準備開始在多模態要求中使用它?

跳至程式碼範例

為什麼要將 Cloud Storage for Firebase 與應用程式搭配使用?

Cloud Storage for Firebase 使用與 Google Cloud Storage 相同的快速、安全且可擴充基礎架構來儲存 Blob 和檔案,其用戶端 SDK 是專為行動和網頁應用程式而建構。

對於 Vertex AI in Firebase SDK,要求大小上限為 20 MB。如果要求過大,您會收到 HTTP 413 錯誤。如果檔案大小會使總要求大小超過 20 MB,請使用 Cloud Storage for Firebase 網址,在多模態要求中加入該檔案。不過,如果檔案很小,您通常可以直接將其做為內嵌資料傳遞 (但請注意,以內嵌資料提供的檔案會在傳輸期間編碼為 base64,因此會增加要求的大小)。

使用 Cloud Storage for Firebase 還有以下幾項額外優點:

  • 您可以讓使用者直接從應用程式將圖片上傳至 Cloud Storage for Firebase 儲存體,然後只要指定檔案的 MIME 類型和 Cloud Storage for Firebase 網址 (也就是檔案的 ID),即可在多模式提示中加入這些圖片。

  • 如果使用者需要提供圖片,您可以節省他們的時間和頻寬,尤其是網路品質不佳或不穩定的使用者。

    • 如果檔案上傳或下載作業中斷,Cloud Storage for Firebase SDK 會自動重新啟動作業,從中斷處開始執行。
    • 同一個上傳檔案可重複使用,使用者不必每次在應用程式中需要相同檔案時 (例如在新的多模式要求中) 上傳相同檔案。
  • 您可以使用 Firebase Security Rules 限制使用者存取儲存在 Cloud Storage for Firebase 中的檔案,只允許授權使用者上傳、下載或刪除檔案。

  • 您可以透過 Firebase 或 Google Cloud 存取儲存桶中的檔案,藉此靈活運用 Google Cloud Storage API 執行伺服器端處理作業,例如圖片篩選或影片轉碼。

系統支援哪些檔案類型和網址?

如要搭配 Vertex AI in Firebase SDK 使用 Cloud Storage for Firebase 網址,請遵守下列檔案和網址規定:

  • 使用 Vertex AI in Firebase SDK 時,檔案必須符合多模態要求的輸入檔案要求。包括 MIME 類型和檔案大小等規定。

  • 檔案必須儲存在 Cloud Storage for Firebase 值區 (也就是 Firebase Security Rules 等 Firebase 服務可存取的值區)。如果您可以在 Firebase 主控台中查看值區,那就是 Cloud Storage for Firebase 值區。

  • Cloud Storage for Firebase 值區必須位於您註冊應用程式的 Firebase 專案中。

  • 檔案的 Cloud Storage for Firebase 網址開頭必須是 gs://,這是所有 Google Cloud Storage 網址的建構方式。

  • 檔案網址不得是「瀏覽器」網址 (例如在網路上找到的圖片網址)。

此外,值區的 Firebase Security Rules 必須允許適當的檔案存取權。例如:

  • 如果您有公開規則,則任何使用者或用戶端都可以使用 Vertex AI in Firebase SDK 在呼叫中存取檔案並提供其網址。這類規則應僅用於啟動和早期原型設計期間 (除非檔案實際上是完全公開存取的檔案)。

  • 如果您有完善的規則 (強烈建議),Firebase 會先檢查已登入使用者或用戶端是否有足夠的檔案存取權,然後才允許呼叫透過提供的網址傳送。

使用 Cloud Storage for Firebase 網址搭配 Vertex AI in Firebase

步驟 1:設定 Cloud Storage for Firebase

如要瞭解如何設定及使用 Cloud Storage for Firebase,請參閱入門指南

前往Cloud Storage for Firebase入門指南

以下是您需要執行的整體工作:

  1. 在 Firebase 專案中建立 Cloud Storage for Firebase 儲存體。

    如果您在 Google Cloud 專案中已建立要與 Vertex AI in Firebase 搭配使用的 Cloud Storage 儲存體,您可以「匯入」儲存體至 Firebase,讓 Firebase 服務 (包括 Vertex AI in Firebase) 存取該儲存體。

  2. Firebase Security Rules 套用至這個值區。Firebase Security Rules 可限制授權使用者的存取權,協助您保護檔案。

  3. Cloud Storage for Firebase 的用戶端程式庫新增至應用程式。

    請注意,您可以略過這項工作,但必須一律 在多模態要求中明確加入 MIME 類型和 Cloud Storage for Firebase 網址值

步驟 2:將檔案上傳至儲存桶

您可以在 Cloud Storage for Firebase 說明文件中瞭解將檔案上傳至 Cloud Storage for Firebase 儲存空間的所有不同方法。舉例來說,您可以從使用者的裝置上傳本機檔案,例如相機中的相片和影片。

當您將檔案上傳至值區時,Cloud Storage 會自動將下列兩項資訊套用至檔案。您必須在多模態要求中加入這些值 (如本指南的下一節所示)。

  • MIME 類型:這是檔案的媒體類型 (例如 image/png)。Cloud Storage for Firebase 會在上傳期間自動嘗試偵測 MIME 類型,並將該中繼資料套用至儲存桶中的物件。不過,您可以在上傳時選擇指定 MIME 類型。

  • Cloud Storage for Firebase 網址:這是檔案的專屬 ID。網址開頭必須是 gs://

步驟 3:在多模態要求中加入檔案的 MIME 類型和網址

將檔案儲存在 Cloud Storage for Firebase 值區後,您可以在多模態要求中加入檔案的 MIME 類型和 Cloud Storage for Firebase 網址。請注意,這些範例顯示非串流 generateContent 要求,但您也可以使用 Cloud Storage for Firebase 網址搭配串流和聊天功能。

如要在要求中加入檔案,您可以使用下列任一選項:

方法 1:使用儲存空間參照加入 MIME 類型和網址

如果您剛將檔案上傳至值區,且希望在多模態要求中立即加入檔案 (透過 Storage 參照),請使用這個選項。這個呼叫需要 MIME 類型和 Cloud Storage for Firebase 網址。

Kotlin+KTX

對於 Kotlin,這個 SDK 中的函式為暫停函式,需要從 協同程式範圍中呼叫。
// Upload an image file using Cloud Storage for Firebase.
val storageRef = Firebase.storage.reference.child("images/image.jpg")
val fileUri = Uri.fromFile(File("image.jpg"))
try {
    val taskSnapshot = storageRef.putFile(fileUri).await()
    // Get the MIME type and Cloud Storage for Firebase file path.
    val mimeType = taskSnapshot.metadata?.contentType
    val bucket = taskSnapshot.metadata?.bucket
    val filePath = taskSnapshot.metadata?.path

    if (mimeType != null && bucket != null) {
        // Construct a URL in the required format.
        val storageUrl = "gs://$bucket/$filePath"
        // Construct a prompt that includes text, the MIME type, and the URL.
        val prompt = content {
            fileData(mimeType = mimeType, uri = storageUrl)
            text("What's in this picture?")
        }
        // To generate text output, call generateContent with the prompt.
        val response = generativeModel.generateContent(prompt)
        println(response.text)
    }
} catch (e: StorageException) {
    // An error occurred while uploading the file.
} catch (e: GoogleGenerativeAIException) {
    // An error occurred while generating text.
}

Java

對於 Java,這個 SDK 中的各個方法會傳回 ListenableFuture
// Upload an image file using Cloud Storage for Firebase.
StorageReference storage = FirebaseStorage.getInstance().getReference("images/image.jpg");
Uri fileUri = Uri.fromFile(new File("images/image.jpg"));

storage.putFile(fileUri).addOnSuccessListener(taskSnapshot -> {
    // Get the MIME type and Cloud Storage for Firebase file path.
    String mimeType = taskSnapshot.getMetadata().getContentType();
    String bucket = taskSnapshot.getMetadata().getBucket();
    String filePath = taskSnapshot.getMetadata().getPath();

    if (mimeType != null && bucket != null) {
        // Construct a URL in the required format.
        String storageUrl = "gs://" + bucket + "/" + filePath;
        // Create a prompt that includes text, the MIME type, and the URL.
        Content prompt = new Content.Builder()
                .addFileData(storageUrl, mimeType)
                .addText("What's in this picture?")
                .build();

        // To generate text output, call generateContent with the prompt.
        GenerativeModelFutures modelFutures = GenerativeModelFutures.from(model);
        ListenableFuture<GenerateContentResponse> response = modelFutures.generateContent(prompt);
        Futures.addCallback(response, new FutureCallback<>() {
            @Override
            public void onSuccess(GenerateContentResponse result) {
                String resultText = result.getText();
                System.out.println(resultText);
            }

            @Override
            public void onFailure(@NonNull Throwable t) {
                t.printStackTrace();
            }
        }, executor);
    }
}).addOnFailureListener(e -> {
    // An error occurred while uploading the file.
    e.printStackTrace();
});

方法 2:明確加入 MIME 類型和網址

如果您知道 MIME 類型和 Cloud Storage for Firebase 網址的值,且想要明確將這些值納入多模態要求,請使用這個選項。這個呼叫需要 MIME 類型和網址。

Kotlin+KTX

對於 Kotlin,這個 SDK 中的函式為暫停函式,需要從 協同程式範圍中呼叫。
// Construct a prompt that explicitly includes the MIME type and Cloud Storage for Firebase URL values.
val prompt = content {
    fileData(mimeType = "image/jpeg", uri = "gs://bucket-name/path/image.jpg")
    text("What's in this picture?")
}
// To generate text output, call generateContent with the prompt.
val response = generativeModel.generateContent(prompt)
println(response.text)

Java

對於 Java,這個 SDK 中的各個方法會傳回 ListenableFuture
// Construct a prompt that explicitly includes the MIME type and Cloud Storage for Firebase URL values.
Content prompt = new Content.Builder()
        .addFilePart("gs://bucket-name/path/image.jpg", "image/jpeg")
        .addText("What's in this picture?")
        .build();

// To generate text output, call generateContent with the prompt
GenerativeModelFutures modelFutures = GenerativeModelFutures.from(model);
ListenableFuture<GenerateContentResponse> response = modelFutures.generateContent(prompt);
Futures.addCallback(response, new FutureCallback<>() {
    @Override
    public void onSuccess(GenerateContentResponse result) {
        String resultText = result.getText();
        System.out.println(resultText);
    }

    @Override
    public void onFailure(@NonNull Throwable t) {
        t.printStackTrace();
    }
}, executor);