Inclua arquivos grandes em solicitações multimodais e gerencie arquivos usando o Cloud Storage para Firebase

Ao chamar o Gemini API do seu app usando um SDK Vertex AI in Firebase, você pode solicitar que o modelo Gemini gere texto com base em uma entrada multimodal. Os comandos multimodais podem incluir várias modalidades (ou tipos de entrada), como texto com imagens, PDFs, vídeo e áudio.

Para as partes não textuais da entrada (como arquivos de mídia), use Cloud Storage for Firebase para incluir arquivos na solicitação. Em um nível geral, confira o que você precisa saber sobre esse recurso:

  • É possível usar Cloud Storage for Firebase com qualquer solicitação multimodal, como geração de texto e chat. Os exemplos neste guia mostram uma entrada básica de texto e imagem.

  • Especifique o tipo MIME do arquivo e o URL Cloud Storage for Firebase (que sempre começa com gs://) na entrada de solicitação. Esses valores são metadados atribuídos automaticamente a qualquer arquivo enviado para um bucket Cloud Storage.

  • É necessário usar um tipo de arquivo e URL compatível.


Este guia de solução descreve como configurar o Cloud Storage for Firebase, fazer upload de um arquivo para um bucket Cloud Storage for Firebase no app e incluir o tipo MIME do arquivo e o URL Cloud Storage for Firebase na solicitação multimodal para o Gemini API.

Quer conferir os exemplos de código? Ou você já configurou o Cloud Storage for Firebase e está pronto para começar a usá-lo com suas solicitações multimodais?

Ir para os exemplos de código

Por que usar Cloud Storage for Firebase com seu app?

O Cloud Storage for Firebase usa a mesma infraestrutura rápida, segura e escalonável do Google Cloud Storage para armazenar blobs e arquivos. Os SDKs de cliente dele são criados especificamente para apps para dispositivos móveis e da Web.

Para SDKs Vertex AI in Firebase, o tamanho máximo da solicitação é de 20 MB. Você recebe um erro HTTP 413 se uma solicitação for muito grande. Se o tamanho de um arquivo fizer o tamanho total da solicitação exceder 20 MB, use um URL Cloud Storage for Firebase para incluir o arquivo na solicitação multimodal. No entanto, se um arquivo for pequeno, é possível transmiti-lo diretamente como dados inline. Observe que um arquivo fornecido como dados inline é codificado em base64 em trânsito, o que aumenta o tamanho da solicitação.

Confira outros benefícios do uso de Cloud Storage for Firebase:

  • Os usuários finais podem fazer upload de imagens diretamente do app para um bucket Cloud Storage for Firebase e, em seguida, incluir essas imagens nos comandos multimodais apenas especificando o tipo MIME do arquivo e o URL Cloud Storage for Firebase (que é um identificador do arquivo).

  • Você pode economizar tempo e largura de banda dos usuários finais se eles precisarem enviar imagens, principalmente se a qualidade da rede for ruim ou instável.

    • Se um upload ou download de arquivo for interrompido, os SDKs Cloud Storage for Firebase vão reiniciar automaticamente a operação de onde ela parou.
    • O mesmo arquivo enviado pode ser usado várias vezes sem que o usuário final precise fazer o upload dele toda vez que for necessário no app (como em uma nova solicitação multimodal).
  • É possível restringir o acesso do usuário final aos arquivos armazenados em Cloud Storage for Firebase usando Firebase Security Rules, que permite que apenas um usuário autorizado faça upload, download ou exclua arquivos.

  • Você pode acessar os arquivos no seu bucket pelo Firebase ou pelo Google Cloud, o que oferece flexibilidade para fazer processamento do lado do servidor, como filtragem de imagens ou transcodificação de vídeo usando as APIs Google Cloud Storage.

Quais tipos de arquivos e URLs são aceitos?

Confira os requisitos para arquivos e URLs quando você quiser usar URLs Cloud Storage for Firebase com os SDKs Vertex AI in Firebase:

  • O arquivo precisa atender aos requisitos de arquivos de entrada para solicitações multimodais ao usar os SDKs Vertex AI in Firebase. Isso inclui requisitos como tipo MIME e tamanho do arquivo.

  • O arquivo precisa ser armazenado em um bucket Cloud Storage for Firebase, o que significa que o bucket é acessível aos serviços do Firebase, como Firebase Security Rules. Se você conseguir acessar o bucket no console Firebase, ele será um bucket Cloud Storage for Firebase.

  • O bucket Cloud Storage for Firebase precisa estar no mesmo projeto do Firebase em que você registrou o app.

  • O URL Cloud Storage for Firebase do arquivo precisa começar com gs://, que é a maneira como todos os URLs Google Cloud Storage são construídos.

  • O URL do arquivo não pode ser um URL de "navegador" (por exemplo, o URL de uma imagem encontrada na Internet).

Além disso, o Firebase Security Rules do bucket precisa permitir o acesso adequado ao arquivo. Exemplo:

  • Se você tiver regras públicas, qualquer usuário ou cliente poderá acessar o arquivo e fornecer o URL dele em uma chamada usando um SDK Vertex AI in Firebase. Esses tipos de regras só devem ser usados para começar e durante a prototipagem inicial, a menos que os arquivos sejam totalmente acessíveis ao público.

  • Se você tiver regras robustas (recomendado), o Firebase vai verificar se o usuário ou cliente conectado tem acesso suficiente ao arquivo antes de permitir que a chamada seja feita com o URL fornecido.

Usar URLs Cloud Storage for Firebase com Vertex AI in Firebase

Etapa 1: configurar o Cloud Storage for Firebase

Confira instruções detalhadas sobre como configurar e usar o Cloud Storage for Firebase no guia de início rápido.

Acesse o guia de início Cloud Storage for Firebase

Estas são as tarefas gerais que você precisa realizar:

  1. Crie um bucket Cloud Storage for Firebase no seu projeto do Firebase.

    Se você já tiver um bucket Cloud Storage no seu projeto Google Cloud que queira usar com Vertex AI in Firebase, poderá torná-lo acessível aos serviços do Firebase (incluindo Vertex AI in Firebase) importando-o para o Firebase.

  2. Aplique Firebase Security Rules a este bucket. Os Firebase Security Rules ajudam a proteger seus arquivos restringindo o acesso a usuários finais autorizados.

  3. Adicione a biblioteca de cliente para Cloud Storage for Firebase ao app.

    Você pode pular esta tarefa, mas precisa sempre incluir explicitamente o tipo MIME e os valores de URL Cloud Storage for Firebase nas solicitações multimodais.

Etapa 2: fazer upload de um arquivo para um bucket

Na documentação do Cloud Storage for Firebase, você pode aprender todas as diferentes maneiras de fazer upload de arquivos para um bucket Cloud Storage for Firebase. Por exemplo, é possível fazer upload de arquivos locais do dispositivo do usuário final, como fotos e vídeos da câmera.

Quando você faz upload de um arquivo para um bucket, o Cloud Storage aplica automaticamente as duas informações a seguir ao arquivo. Você vai precisar incluir esses valores na solicitação multimodal, conforme mostrado na próxima etapa deste guia.

  • Tipo MIME: é o tipo de mídia do arquivo (por exemplo, image/png). O Cloud Storage for Firebase tenta detectar automaticamente o tipo MIME durante o upload e aplicar esses metadados ao objeto no bucket. No entanto, é possível especificar o tipo MIME durante o upload.

  • URL Cloud Storage for Firebase: é um identificador exclusivo do arquivo. O URL precisa começar com gs://.

Etapa 3: incluir o tipo MIME e o URL do arquivo em uma solicitação multimodal

Depois de armazenar um arquivo em um bucket Cloud Storage for Firebase, é possível incluir o tipo MIME e o URL Cloud Storage for Firebase dele em uma solicitação multimodal. Esses exemplos mostram uma solicitação generateContent sem streaming, mas você também pode usar URLs Cloud Storage for Firebase com streaming e chat.

Para incluir o arquivo na solicitação, use uma destas opções:

Opção 1: incluir o tipo MIME e o URL usando uma referência do Firebase Storage

Use essa opção se você acabou de fazer upload do arquivo para o bucket e quer incluí-lo imediatamente (por uma referência do Storage) na solicitação multimodal. A chamada exige o tipo MIME e o URL Cloud Storage for Firebase.

Kotlin+KTX

No Kotlin, os métodos neste SDK são funções de suspensão e precisam ser chamados de um escopo de corrotina.
// 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

Em Java, os métodos neste SDK retornam um 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();
});

Opção 2: incluir o tipo MIME e o URL explicitamente

Use essa opção se você souber os valores do tipo MIME e do URL Cloud Storage for Firebase e quiser incluí-los explicitamente na solicitação multimídia. A chamada exige o tipo MIME e o URL.

Kotlin+KTX

No Kotlin, os métodos neste SDK são funções de suspensão e precisam ser chamados de um escopo de corrotina.
// 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

Em Java, os métodos neste SDK retornam um 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);