Premiers pas avec l'API Prompt

Cette page explique comment effectuer les opérations suivantes :

  • Configurer votre projet pour utiliser l'API Prompt
  • Fournir une entrée textuelle et recevoir une réponse
  • Fournir une entrée d'image avec une entrée de texte associée et recevoir une réponse

Pour en savoir plus sur l'API Prompt, consultez la documentation de référence pour Kotlin (com.google.mlkit.genai.prompt) et Java (com.google.mlkit.genai.prompt.java, com.google.mlkit.genai.prompt).

[Facultatif] Tester l'invite avec le modèle Gemma 3n

Avant l'implémentation, pensez à tester votre requête dans AI Studio avec le modèle Gemma 3n E4B. Les résultats de Gemma 3n devraient être très similaires à ceux de nano-v3.

Configurer le projet

Ajoutez l'API ML Kit Prompt en tant que dépendance dans votre configuration build.gradle :

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

Implémenter un modèle génératif

Pour implémenter le code dans votre projet, procédez comme suit :

  • Créez un objet generativeModel :

    Kotlin

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

    Java

    // Get a GenerativeModel instance
    GenerativeModelFutures generativeModelFutures = GenerativeModelFutures
        .from(Generation.INSTANCE.getClient());
    
  • Vérifiez si Gemini Nano est AVAILABLE,, DOWNLOADABLE ou UNAVAILABLE. Ensuite, téléchargez la fonctionnalité si elle est téléchargeable :

    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));
    
    

Fournir une entrée uniquement basée sur du texte

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();

Vous pouvez également ajouter des paramètres facultatifs :

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();

Pour en savoir plus sur les paramètres facultatifs, consultez Configurations facultatives.

Fournir une entrée multimodale (image et texte)

Regroupez une image et une entrée de texte dans la fonction generateContentRequest(), la requête textuelle étant une question ou une commande liée à l'image :

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();

Traiter le résultat de l'inférence

  • Exécutez l'inférence et récupérez le résultat. Vous pouvez choisir d'attendre le résultat complet ou de diffuser la réponse au fur et à mesure de sa génération pour les requêtes textuelles et multimodales.

    • Cela utilise l'inférence sans flux, qui récupère l'intégralité du résultat du modèle d'IA avant de le renvoyer :

    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();
    
    • Les extraits suivants sont des exemples d'utilisation de l'inférence de streaming, qui récupère le résultat par blocs au fur et à mesure de sa génération :

    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);
            });
    

Pour en savoir plus sur l'inférence en streaming et non en streaming, consultez Streaming ou non-streaming.

Optimisation de la latence

Pour optimiser le premier appel d'inférence, votre application peut éventuellement appeler warmup(). Cela charge Gemini Nano en mémoire et initialise les composants d'exécution.

Configurations facultatives

Dans chaque GenerateContentRequest, vous pouvez définir les paramètres facultatifs suivants :

  • temperature : contrôle le degré de hasard dans la sélection des jetons.
  • seed : permet de générer des résultats stables et déterministes.
  • topK : contrôle le caractère aléatoire et la diversité des résultats.
  • candidateCount : demande le nombre de réponses uniques renvoyées. Notez que le nombre exact de réponses peut ne pas être le même que candidateCount, car les réponses en double sont automatiquement supprimées.
  • maxOutputTokens : définit le nombre maximal de jetons pouvant être générés dans la réponse.

Pour obtenir plus d'informations sur la définition des configurations facultatives, consultez GenerateContentRequest.

Fonctionnalités et limites

  • L'entrée ne doit pas dépasser 4 000 jetons (environ 3 000 mots en anglais). Pour en savoir plus, consultez la référence countTokens.
  • Évitez les cas d'utilisation qui nécessitent une longue sortie (plus de 256 jetons).
  • AICore applique un quota d'inférence par application. Pour en savoir plus, consultez Quota par application.
  • Les langues suivantes ont été validées pour l'API Prompt :
    • Anglais
    • Coréen

Problèmes de configuration courants

Les API d'IA générative de ML Kit s'appuient sur l'application Android AICore pour accéder à Gemini Nano. Lorsqu'un appareil vient d'être configuré (y compris réinitialisé) ou que l'application AICore vient d'être réinitialisée (par exemple, en effaçant les données, puis en la désinstallant et en la réinstallant), il se peut que l'application AICore n'ait pas eu suffisamment de temps pour terminer l'initialisation (y compris le téléchargement des dernières configurations depuis le serveur). Par conséquent, il est possible que les API ML Kit GenAI ne fonctionnent pas comme prévu. Voici les messages d'erreur de configuration courants que vous pouvez rencontrer et comment les résoudre :

Exemple de message d'erreur Comment répondre à une telle objection
AICore a échoué avec le type d'erreur 4-CONNECTION_ERROR et le code d'erreur 601-BINDING_FAILURE : échec de la liaison du service AICore. Cela peut se produire lorsque vous installez l'application à l'aide des API ML Kit GenAI immédiatement après la configuration de l'appareil ou lorsque AICore est désinstallé après l'installation de votre application. Mettre à jour l'application AICore, puis réinstaller votre application devrait résoudre le problème.
AICore a échoué avec le type d'erreur 3-PREPARATION_ERROR et le code d'erreur 606-FEATURE_NOT_FOUND : la fonctionnalité ... n'est pas disponible. Cela peut se produire lorsque AICore n'a pas terminé de télécharger les dernières configurations. Lorsque l'appareil est connecté à Internet, la mise à jour prend généralement de quelques minutes à quelques heures. Redémarrer l'appareil peut accélérer la mise à jour.

Notez que si le bootloader de l'appareil est déverrouillé, cette erreur s'affichera également. Cette API n'est pas compatible avec les appareils dont le bootloader est déverrouillé.
AICore a échoué avec le type d'erreur 1-DOWNLOAD_ERROR et le code d'erreur 0-UNKNOWN : la fonctionnalité ... a échoué avec l'état d'échec 0 et l'erreur esz : UNAVAILABLE : Impossible de résoudre l'hôte ... Maintenez la connexion réseau, patientez quelques minutes, puis réessayez.