Começar a usar a API Prompt

Esta página explica como fazer o seguinte:

  • Configurar seu projeto para usar a API Prompt
  • Fornecer entrada somente de texto e receber uma resposta
  • Fornecer uma entrada de imagem com entrada de texto relacionada e receber uma resposta

Para mais detalhes sobre a API Prompt, consulte a documentação de referência para Kotlin (com.google.mlkit.genai.prompt) e Java (com.google.mlkit.genai.prompt.java, com.google.mlkit.genai.prompt).

Configurar projeto

Adicione a API Prompt do Kit de ML como uma dependência na configuração build.gradle:

implementation("com.google.mlkit:genai-prompt:1.0.0-beta2")

Se você precisar de respostas em um determinado formato usando a API Structured Output, configure o KSP e adicione outras dependências. Para mais detalhes, consulte Gerar saída estruturada.

Implementar modelo generativo

Para implementar o código no seu projeto, siga estas etapas:

  • Crie um objeto generativeModel:

    Kotlin

    // Get a GenerativeModel instance
    val generativeModel = Generation.getClient()
    

    Java

    // Get a GenerativeModel instance
    GenerativeModelFutures generativeModelFutures = GenerativeModelFutures
        .from(Generation.INSTANCE.getClient());
    
  • Verifique se o Gemini Nano está AVAILABLE, DOWNLOADABLE ou UNAVAILABLE. Em seguida, faça o download do recurso se ele estiver disponível:

    Kotlin

    val status = generativeModel.checkStatus()
    when (status) {
        FeatureStatus.UNAVAILABLE -> {
            // Gemini Nano not supported on this device or device hasn't fetched the latest configuration to support it
        }
    
        FeatureStatus.DOWNLOADABLE -> {
            // Gemini Nano can be downloaded on this device, but is not currently downloaded
            generativeModel.download().collect { status ->
                when (status) {
                    is DownloadStatus.DownloadStarted ->
                        Log.d(TAG, "starting download for Gemini Nano")
    
                    is DownloadStatus.DownloadProgress ->
                        Log.d(TAG, "Nano ${status.totalBytesDownloaded} bytes downloaded")
    
                    DownloadStatus.DownloadCompleted -> {
                        Log.d(TAG, "Gemini Nano download complete")
                        modelDownloaded = true
                    }
    
                    is DownloadStatus.DownloadFailed -> {
                        Log.e(TAG, "Nano download failed ${status.e.message}")
                    }
                }
            }
        }
    
        FeatureStatus.DOWNLOADING -> {
            // Gemini Nano currently being downloaded
        }
    
        FeatureStatus.AVAILABLE -> {
            // Gemini Nano currently downloaded and available to use on this device
        }
    }
    

    Java

    ListenableFuture<Integer> status = generativeModelFutures.checkStatus();
    Futures.addCallback(generativeModelFutures.checkStatus(), new FutureCallback<>() {
        @Override
        public void onSuccess(Integer featureStatus) {
            switch (featureStatus) {
                case FeatureStatus.AVAILABLE - > {
                    // Gemini Nano currently downloaded and available to use on this device
                }
                case FeatureStatus.UNAVAILABLE - > {
                    // Gemini Nano not supported on this device or device hasn't fetched the latest configuration to support it
                }
                case FeatureStatus.DOWNLOADING - > {
                    // Gemini Nano currently being downloaded
                }
                case FeatureStatus.DOWNLOADABLE - > {
                    generativeModelFutures.download(new DownloadCallback() {
                        @Override
                        public void onDownloadStarted(long l) {
                            Log.d(TAG, "starting download for Gemini Nano");
                        }
                        @Override
                        public void onDownloadProgress(long l) {
                            Log.d(TAG, "Nano " + l + " bytes downloaded");
                        }
                        @Override
                        public void onDownloadCompleted() {
                            Log.d(TAG, "Gemini Nano download complete");
                        }
                        @Override
                        public void onDownloadFailed(@NonNull GenAiException e) {
                            Log.e(TAG, "Nano download failed: " + e.getMessage());
                        }
                    });
                }
            }
        }
        @Override
        public void onFailure(@NonNull Throwable t) {
            // Failed to check status
        }
    }, ContextCompat.getMainExecutor(context));
    
    

Fornecer entrada somente de texto

Kotlin

val response = generativeModel.generateContent("Write a 3 sentence story about a magical dog.")

Java

GenerateContentResponse response = generativeModelFutures.generateContent(
  new GenerateContentRequest.Builder(
    new TextPart("Write a 3 sentence story about a magical dog."))
  .build())
  .get();

Como alternativa, adicione parâmetros opcionais:

Kotlin

val response = generativeModel.generateContent(
    generateContentRequest(
        TextPart("Write a 3 sentence story about a magical dog."),
    ) {
        // Optional parameters
        temperature = 0.2f
        topK = 10
        candidateCount = 3
    },
)

Java

GenerateContentRequest.Builder requestBuilder =
        new GenerateContentRequest.Builder(
                new TextPart("Write a 3 sentence story about a magical dog."));
requestBuilder.setTemperature(.2f);
requestBuilder.setTopK(10);
requestBuilder.setCandidateCount(3);

GenerateContentResponse response =
        generativeModelFutures.generateContent(requestBuilder.build()).get();

Para mais informações sobre os parâmetros opcionais, consulte Configurações opcionais.

Fornecer entrada multimodal (imagem e texto)

Agrupe uma imagem e uma entrada de texto na função generateContentRequest(), com o comando de texto sendo uma pergunta ou comando relacionado à imagem. É possível agrupar várias imagens e textos na mesma solicitação.

Kotlin

val response = generativeModel.generateContent(
    generateContentRequest(ImagePart(bitmap), TextPart(textPrompt)) {
        // optional parameters
        ...
    },
)

Java

GenerateContentResponse response = generativeModelFutures.generateContent(
    new GenerateContentRequest.Builder(
        new ImagePart(bitmap),
        new TextPart("textPrompt"))
    // optional parameters
    .build())
.get();

Processar resultado de inferência

  • Execute a inferência e recupere o resultado. Você pode esperar o resultado completo ou transmitir a resposta à medida que ela é gerada para comandos somente de texto e multimodais.

    • Isso usa a inferência sem streaming, que recupera todo o resultado do modelo de IA antes de retornar o resultado:

    Kotlin

    // Call the AI model to generate content and store the complete
    // in a new variable named 'response' once it's finished
    val response = generativeModel.generateContent("Write a 3 sentence story about a magical dog")
    

    Java

    GenerateContentResponse response = generativeModelFutures.generateContent(
            new GenerateContentRequest.Builder(
                    new TextPart("Write a 3 sentence story about a magical dog."))
                    .build())
            .get();
    
    • Os snippets a seguir são exemplos de como usar a inferência de streaming, que recupera o resultado em partes à medida que ele é gerado:

    Kotlin

    // Streaming inference
    var fullResponse = ""
    generativeModel.generateContentStream("Write a 3 sentence story about a magical dog").collect { chunk ->
        val newChunkReceived = chunk.candidates[0].text
        print(newChunkReceived)
        fullResponse += newChunkReceived
    }
    

    Java

    // Streaming inference
    StringBuilder fullResponse = new StringBuilder();
    generativeModelFutures.generateContent(new GenerateContentRequest.Builder(
        (new TextPart("Write a 3 sentence story about a magical dog"))).build(),
            chunk -> {
                Log.d(TAG, chunk);
                fullResponse.append(chunk);
            });
    

Para mais informações sobre inferência de streaming e sem streaming, consulte Streaming versus não streaming.

Otimização da latência

Para otimizar a primeira chamada de inferência, seu aplicativo pode chamar warmup(). Isso carrega o Gemini Nano na memória e inicializa os componentes de execução.

Configurações opcionais

Como parte de cada GenerateContentRequest, é possível definir os seguintes parâmetros opcionais:

  • temperature : controla o grau de aleatoriedade na seleção de token.
  • seed : permite gerar resultados estáveis e determinísticos.
  • topK : controla a aleatoriedade e a diversidade nos resultados.
  • candidateCount : solicita o número de respostas exclusivas retornadas. O número exato de respostas pode não ser o mesmo que candidateCount, porque as respostas duplicadas são removidas automaticamente.
  • maxOutputTokens : define o número máximo de tokens que podem ser gerados na resposta.

Para mais orientações sobre como definir configurações opcionais, consulte GenerateContentRequest.

Recursos e limitações compatíveis

  • A entrada precisa ter menos de 4.000 tokens (ou aproximadamente 3.000 palavras em inglês). Para mais informações, consulte a countTokens referência.
  • Evite casos de uso que exigem uma saída longa (mais de 4 mil tokens).
  • O AICore aplica uma cota de inferência por app. Para mais informações, consulte Cota por aplicativo.

Problemas comuns de configuração

As APIs GenAI do Kit de ML dependem do Android AICore para acessar o Gemini Nano. Quando um dispositivo é configurado (incluindo a redefinição) ou o app AICore é redefinido (por exemplo, dados limpos, desinstalados e reinstalados), o app AICore pode não ter tempo suficiente para concluir a inicialização (incluindo o download das configurações mais recentes do servidor). Como resultado, as APIs de IA generativa do Kit de ML podem não funcionar como esperado. Confira as mensagens de erro de configuração comuns que podem aparecer e como lidar com elas:

Exemplo de mensagem de erro Como lidar
O AICore falhou com o tipo de erro 4-CONNECTION_ERROR e o código de erro 601-BINDING_FAILURE: falha ao vincular o serviço do AICore. Isso pode acontecer quando você instala o app usando as APIs de IA generativa do Kit de ML imediatamente após a configuração do dispositivo ou quando o AICore é desinstalado após a instalação do app. Atualizar o app AICore e reinstalar o app deve corrigir o problema.
O AICore falhou com o tipo de erro 3-PREPARATION_ERROR e o código de erro 606-FEATURE_NOT_FOUND: o recurso ... não está disponível. Isso pode acontecer quando o AICore não terminou de fazer o download das configurações mais recentes. Quando o dispositivo está conectado à Internet, geralmente leva de alguns minutos a algumas horas para atualizar. Reiniciar o dispositivo pode acelerar a atualização.

Se o bootloader do dispositivo estiver desbloqueado, esse erro também vai aparecer. Essa API não oferece suporte a dispositivos com bootloaders desbloqueados.
O AICore falhou com o tipo de erro 1-DOWNLOAD_ERROR e o código de erro 0-UNKNOWN: o recurso ... falhou com o status de falha 0 e o erro esz: UNAVAILABLE: não foi possível resolver o host ... Mantenha a conexão de rede, aguarde alguns minutos e tente de novo.