Uwzględniaj duże pliki w żądaniach multimodalnych i zarządzaj plikami za pomocą Cloud Storage dla Firebase

Gdy wywołujesz funkcję Gemini API z aplikacji za pomocą pakietu SDK Vertex AI in Firebase, możesz poprosić model Gemini o wygenerowanie tekstu na podstawie danych wejściowych multimodalnych. Prompty multimodalne mogą zawierać wiele modalności (czyli typów danych wejściowych), takich jak tekst, obrazy, pliki PDF, filmy i dźwięk.

W przypadku części danych wejściowych innych niż tekst (np. plików multimedialnych) możesz opcjonalnie użyć znaku Cloud Storage for Firebase, aby uwzględnić pliki w żądaniu. Oto najważniejsze informacje o tej funkcji:

  • Możesz używać Cloud Storage for Firebase do obsługi dowolnych multimodalnych żądań (takich jak generowanie tekstu i czat). Przykłady w tym przewodniku pokazują podstawowe dane wejściowe w postaci tekstu i obrazu.

  • W danych wejściowych zapytania podajesz typ MIME pliku i adres URL Cloud Storage for Firebase (który zawsze zaczyna się od gs://). Te wartości to metadane automatycznie przypisane do każdego pliku przesłanego do zasobnika Cloud Storage.

  • Musisz użyć obsługiwanego typu pliku i adresu URL.


Z tego przewodnika dowiesz się, jak skonfigurować Cloud Storage for Firebase, przesłać plik do zasobnika Cloud Storage for Firebase z aplikacji, a potem dołączyć typ MIME pliku i adres URL Cloud Storage for Firebase do żądania multimodalnego do Gemini API.

Czy chcesz zobaczyć przykłady kodu? A może masz już skonfigurowany Cloud Storage for Firebase i chcesz zacząć używać go do obsługi żądań multimodalnych?

Przejdź do przykładów kodu

Dlaczego warto używać Cloud Storage for Firebase w aplikacji?

Cloud Storage for Firebase korzysta z tej samej szybkiej, bezpiecznej i skalowalnej infrastruktury co Google Cloud Storage do przechowywania blobów i plików. Pakiety SDK klienta są tworzone specjalnie na potrzeby aplikacji mobilnych i internetowych.

W przypadku pakietów SDK Vertex AI in Firebase maksymalny rozmiar żądania to 20 MB. Jeśli żądanie jest zbyt duże, otrzymasz błąd HTTP 413. Jeśli rozmiar pliku spowoduje, że łączny rozmiar żądania przekroczy 20 MB, użyj adresu URL Cloud Storage for Firebase, aby uwzględnić plik w żądaniu multimodalnym. Jeśli jednak plik jest mały, możesz go przekazać bezpośrednio jako dane wbudowane (pamiętaj jednak, że plik podany jako dane wbudowane jest kodowany w standardzie base64 w trakcie przesyłania, co zwiększa rozmiar żądania).

Oto dodatkowe korzyści płynące z użycia Cloud Storage for Firebase:

  • Możesz umożliwić użytkownikom przesyłanie obrazów bezpośrednio z aplikacji do zasobnika Cloud Storage for Firebase, a potem dołączać je do swoich multimodalnych promptów, określając typ MIME pliku i adres URL Cloud Storage for Firebase (który jest identyfikatorem pliku).

  • Jeśli użytkownicy muszą przesłać zdjęcia, możesz zaoszczędzić im czasu i przepustowości, zwłaszcza jeśli mają problemy z jakością połączenia.

    • Jeśli przesyłanie lub pobieranie pliku zostanie przerwane, Cloud Storage for Firebase SDK automatycznie wznowi działanie w miejscu, w którym zostało przerwane.
    • Przesłany plik może być używany wielokrotnie bez konieczności przesyłania go za każdym razem, gdy jest potrzebny w aplikacji (np. w przypadku nowego żądania multimodalnego).
  • Możesz ograniczyć dostęp użytkowników do plików przechowywanych w usłudze Cloud Storage for Firebase, używając Firebase Security Rules, która pozwala tylko autoryzowanemu użytkownikowi przesyłać, pobierać i usuwać pliki.

  • Do plików w Twoim zbiorniku możesz uzyskać dostęp z Firebase lub z poziomu Google Cloud, co daje Ci elastyczność w przetwarzaniu po stronie serwera, np. filtrowaniu obrazów czy transkodowaniu filmów za pomocą interfejsów API Google Cloud Storage.

Jakie typy plików i adresów URL są obsługiwane?

Oto wymagania dotyczące plików i adresów URL, gdy chcesz używać adresów Cloud Storage for Firebase w pakietach SDK Vertex AI in Firebase:

  • Podczas korzystania z pakietów SDK Vertex AI in Firebase plik musi spełniać wymagania dotyczące plików wejściowych w przypadku żądań multimodalnych. Dotyczy to wymagań takich jak typ MIME i rozmiar pliku.

  • Plik musi być przechowywany w zasobniku Cloud Storage for Firebase (co oznacza, że jest on dostępny dla usług Firebase, takich jak Firebase Security Rules). Jeśli możesz wyświetlić swój zasób w konsoli Firebase, oznacza to, że jest to zasób Cloud Storage for Firebase.

  • Zasobnik Cloud Storage for Firebase musi znajdować się w tym samym projekcie Firebase, w którym zarejestrowano aplikację.

  • Adres URL pliku Cloud Storage for Firebase musi się zaczynać od gs://, ponieważ w taki sposób budowane są wszystkie adresy URL Google Cloud Storage.

  • Adres URL pliku nie może być adresem „przeglądarki” (np. adresem URL obrazu znalezionego w internecie).

Ponadto zasób Firebase Security Rules musi zezwalać na odpowiedni dostęp do pliku. Przykład:

  • Jeśli masz reguły publiczne, każdy użytkownik lub klient może uzyskać dostęp do pliku i podać jego adres URL w wywołaniu za pomocą pakietu SDK Vertex AI in Firebase. Tego typu reguł należy używać tylko na początku i podczas wczesnego prototypowania (chyba że pliki mają być w pełni dostępne publicznie).

  • Jeśli masz solidne reguły (bardzo zalecane), Firebase sprawdzi, czy zalogowany użytkownik lub klient ma wystarczający dostęp do pliku, zanim zezwoli na wywołanie z podanym adresem URL.

Korzystanie z adresów URL Cloud Storage for Firebase w przypadku Vertex AI in Firebase

Krok 1. Skonfiguruj Cloud Storage for Firebase

Szczegółowe instrukcje konfigurowania Cloud Storage for Firebase znajdziesz w przewodniku: iOS+ | Android | Sieć | Flutter

Oto ogólne czynności, które musisz wykonać:

  1. Utwórz lub zaimportuj zasobnik Cloud Storage for Firebase w projekcie Firebase.

  2. Zastosuj Firebase Security Rules do tego zasobnika. Rules pomaga chronić pliki, ograniczając dostęp do autoryzowanych użytkowników.

  3. Dodaj do aplikacji bibliotekę klienta dla Cloud Storage for Firebase.

    Pamiętaj, że możesz pominąć to zadanie, ale wtedy zawsze musisz wyraźnie uwzględniać w żądaniach typ MIME i wartości adresów URL.

Krok 2. Prześlij plik do zasobnika

W dokumentacji Cloud Storage znajdziesz wszystkie sposoby przesyłania plików do zasobnika. Możesz na przykład przesłać pliki lokalne z urządzenia użytkownika, takie jak zdjęcia i filmy z aparatu. Więcej informacji: iOS+ | Android | Sieć | Flutter

Gdy przesyłasz plik do zasobnika, Cloud Storage automatycznie dodaje do niego te 2 informacje. Musisz uwzględnić te wartości w żądaniu (jak pokazano w następnym kroku tego przewodnika).

  • Typ MIME: typ pliku (np. image/png). Podczas przesyłania automatycznie spróbujemy wykryć typ MIME i zastosować te metadane do obiektu w zasobniku. Możesz jednak opcjonalnie określić typ MIME podczas przesyłania.

  • Cloud Storage for Firebase URL: unikalny identyfikator pliku. Adres URL musi zaczynać się od gs://.

Krok 3. Uwzględnij typ MIME i URL pliku w żądaniu multimodalnym

Po zapisaniu pliku w zasobniku możesz dołączyć jego typ MIME i adres URL do żądania. Pamiętaj, że te przykłady pokazują żądanie generateContent bez strumieniowego przesyłania danych, ale możesz też używać adresów URL z czatem i strumieniowym przesyłaniem danych.

Aby dołączyć plik do żądania, możesz użyć jednej z tych opcji:

Opcja 1. Uwzględnij typ MIME i adres URL za pomocą odwołania do Storage

Użyj tej opcji, jeśli plik został właśnie przesłany do zasobnika i chcesz go natychmiast uwzględnić w prośbie (za pomocą odwołania do Storage). Wywołanie wymaga zarówno typu MIME, jak i adresu URL Cloud Storage for Firebase.

Swift

// Upload an image file using Cloud Storage for Firebase.
let storageRef = Storage.storage().reference(withPath: "images/image.jpg")
guard let imageURL = Bundle.main.url(forResource: "image", withExtension: "jpg") else {
  fatalError("File 'image.jpg' not found in main bundle.")
}
let metadata = try await storageRef.putFileAsync(from: imageURL)

// Get the MIME type and Cloud Storage for Firebase URL.
guard let mimeType = metadata.contentType else {
  fatalError("The MIME type of the uploaded image is nil.")
}
// Construct a URL in the required format.
let storageURL = "gs://\(storageRef.bucket)/\(storageRef.fullPath)"

let prompt = "What's in this picture?"
// Construct the imagePart with the MIME type and the URL.
let imagePart = FileDataPart(uri: storageURL, mimeType: mimeType)

// To generate text output, call generateContent with the prompt and the imagePart.
let result = try await model.generateContent(prompt, imagePart)
if let text = result.text {
  print(text)
}

Kotlin

W przypadku Kotlina metody w tym pakiecie SDK są funkcjami zawieszającymi i muszą być wywoływane z zakresu współbieżności.
// 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

W przypadku Javy metody w tym pakiecie SDK zwracają wartość 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();
});

Web

// Upload an image file using Cloud Storage for Firebase.
const storageRef = ref(storage, "image.jpg");
const uploadResult = await uploadBytes(storageRef, file);

// Get the MIME type and Cloud Storage for Firebase URL.
// toString() is the simplest way to construct the Cloud Storage for Firebase URL
// in the required format.
const mimeType = uploadResult.metadata.contentType;
const storageUrl = uploadResult.ref.toString();

// Construct the imagePart with the MIME type and the URL.
const imagePart = { fileData: { mimeType, fileUri: storageUrl }};

// To generate text output, call generateContent with the prompt and imagePart.
const result = await model.generateContent([prompt, imagePart]);
console.log(result.response.text());

Dart

// Upload an image file using Cloud Storage for Firebase.
final storageRef = FirebaseStorage.instance.ref();
final imageRef = storageRef.child("images/image.jpg");
await imageRef.putData(data);

// Get the MIME type and Cloud Storage for Firebase file path.
final metadata = await imageRef.getMetadata();
final mimeType = metadata.contentType;
final bucket = imageRef.bucket;
final fullPath = imageRef.fullPath;

final prompt = TextPart("What's in the picture?");
// Construct a URL in the required format.
final storageUrl = 'gs://$bucket/$fullPath';
// Construct the filePart with the MIME type and the URL.
final filePart = FileData(mimeType, storageUrl);
// To generate text output, call generateContent with the text and the filePart.
final response = await model.generateContent([
  Content.multi([prompt, filePart])
]);
print(response.text);

Opcja 2. Wyraźnie podaj typ MIME i adres URL

Użyj tej opcji, jeśli znasz wartości typu MIME i adresu URL Cloud Storage for Firebase oraz chcesz je wyraźnie uwzględnić w prośbie multimodalnej. Wywołanie wymaga zarówno typu MIME, jak i adresu URL.

Swift

let prompt = "What's in this picture?"
// Construct an imagePart that explicitly includes the MIME type and
// Cloud Storage for Firebase URL values.
let imagePart = FileDataPart(uri: "gs://bucket-name/path/image.jpg", mimeType: "image/jpeg")

// To generate text output, call generateContent with the prompt and imagePart.
let result = try await model.generateContent(prompt, imagePart)
if let text = result.text {
  print(text)
}

Kotlin

W przypadku Kotlina metody w tym pakiecie SDK są funkcjami zawieszającymi i muszą być wywoływane z zakresu współbieżności.
// 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

W przypadku Javy metody w tym pakiecie SDK zwracają wartość 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);

Web

const prompt = "What's in this picture?";
// Construct an imagePart that explicitly includes the MIME type and Cloud Storage for Firebase URL values.
const imagePart = { fileData: { mimeType: "image/jpeg", fileUri: "gs://bucket-name/path/image.jpg" }};

// To generate text output, call generateContent with the prompt and imagePart.
const result = await model.generateContent([prompt, imagePart]);
console.log(result.response.text());

Dart

final prompt = TextPart("What's in the picture?");
// Construct a filePart that explicitly includes the MIME type and Cloud Storage for Firebase URL values.
final filePart = FileData('image/jpeg', 'gs://bucket-name/path/image.jpg'),
// To generate text output, call generateContent with the prompt and filePart.
final response = await model.generateContent([
  Content.multi([prompt, filePart])
]);
print(response.text);