Começar a usar a API Prompt

Esta página explica como fazer o seguinte:

  • Configurar o projeto para usar a API Prompt
  • Fornecer entrada somente de texto e receber uma resposta
  • Fornecer entradas 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-beta4")

Se você precisar que as respostas estejam 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 várias imagens e uma entrada de texto na função generateContentRequest(), com o comando de texto sendo uma pergunta ou um comando relacionado à imagem. É possível agrupar até 10 imagens na mesma solicitação.

Kotlin

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

Java

GenerateContentResponse response = generativeModelFutures.generateContent(
    new GenerateContentRequest.Builder(
        new Content.Builder()
            .addPart(new ImagePart(bitmap1))
            .addPart(new ImagePart(bitmap2))
            .addPart(new TextPart("textPrompt"))
            .build())
    // optional parameters
    .build())
.get();

Processar resultado de inferência

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

    • Isso usa inferência sem streaming, que recupera todo o resultado do modelo de IA antes de retorná-lo:

    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 uso da inferência de streaming, que recupera o resultado em blocos à 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 com e sem streaming, consulte Com streaming versus sem 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 do 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 únicas 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 referência de countTokens.
  • Evite casos de uso que exijam uma saída longa (mais de 4 mil tokens).
  • A 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 app Android AICore para acessar o Gemini Nano. Quando um dispositivo é configurado (incluindo 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). Por isso, as APIs GenAI 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 proceder
O AICore falhou com o tipo de erro 4-CONNECTION_ERROR e o código do erro 601-BINDING_FAILURE: falha ao vincular o serviço do AICore. Isso pode acontecer quando você instala o app usando as APIs GenAI do Kit de ML imediatamente após a configuração do dispositivo ou quando o AICore é desinstalado depois que o app é instalado. Atualize o app AICore e reinstale o seu app para corrigir o problema.
O AICore falhou com o tipo de erro 3-PREPARATION_ERROR e o código do erro 606-FEATURE_NOT_FOUND: o recurso ... não está disponível. Isso pode acontecer quando o AICore não terminou de baixar as 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 carregador de inicialização do dispositivo estiver desbloqueado, você também vai receber esse erro. Essa API não é compatível com dispositivos que têm carregadores de inicialização desbloqueados.
O AICore falhou com o tipo de erro 1-DOWNLOAD_ERROR e o código do 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.