Korzystanie z interfejsu Prompt API

Na tej stronie opisujemy, jak wykonać te czynności:

  • Skonfigurować projekt do korzystania z interfejsu Prompt API
  • Przesłać dane wejściowe zawierające tylko tekst i otrzymać odpowiedź
  • Przesłać dane wejściowe w postaci obrazu z powiązanym tekstem i otrzymać odpowiedź

Więcej informacji o interfejsie Prompt API znajdziesz w dokumentacji referencyjnej dla języka Kotlin (com.google.mlkit.genai.prompt) i Java (com.google.mlkit.genai.prompt.java, com.google.mlkit.genai.prompt).

Konfigurowanie projektu

Dodaj interfejs ML Kit Prompt API jako zależność w konfiguracji build.gradle:

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

Implementowanie modelu generatywnego

Aby zaimplementować kod w projekcie, wykonaj te czynności:

  • Utwórz obiekt generativeModel:

    Kotlin

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

    Java

    // Get a GenerativeModel instance
    GenerativeModelFutures generativeModelFutures = GenerativeModelFutures
        .from(Generation.INSTANCE.getClient());
    
  • Sprawdź, czy model Gemini Nano jest AVAILABLE, DOWNLOADABLE czy UNAVAILABLE. Następnie pobierz funkcję, jeśli jest dostępna do pobrania:

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

Przesyłanie danych wejściowych zawierających tylko tekst

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

Możesz też dodać parametry opcjonalne:

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

Więcej informacji o parametrach opcjonalnych znajdziesz w sekcji Konfiguracje opcjonalne.

Przesyłanie danych wejściowych multimodalnych (obraz i tekst)

Połącz obraz i tekst w funkcji generateContentRequest(), a tekstowy prompt niech będzie pytaniem lub poleceniem związanym z obrazem:

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

Przetwarzanie wyniku wnioskowania

  • Uruchom wnioskowanie i pobierz wynik. Możesz poczekać na pełny wynik lub przesyłać strumieniowo odpowiedź w miarę jej generowania w przypadku promptów zawierających tylko tekst i promptów multimodalnych.

    • Używa to wnioskowania bez przesyłania strumieniowego, które pobiera cały wynik z modelu AI, zanim go zwróci:

    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();
    
    • Poniższe fragmenty kodu to przykłady użycia wnioskowania z przesyłaniem strumieniowym, które pobiera wynik w częściach w miarę jego generowania:

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

Więcej informacji o wnioskowaniu z przesyłaniem strumieniowym i bez niego znajdziesz w sekcji Przesyłanie strumieniowe a brak przesyłania strumieniowego.

Optymalizacja czasu oczekiwania

Aby zoptymalizować pierwsze wywołanie wnioskowania, aplikacja może opcjonalnie wywołać funkcję warmup(). Spowoduje to wczytanie modelu Gemini Nano do pamięci i zainicjowanie komponentów środowiska wykonawczego.

Konfiguracje opcjonalne

W ramach każdego GenerateContentRequest możesz ustawić te parametry opcjonalne:

  • temperature : określa stopień losowości wyboru tokenów.
  • seed : umożliwia generowanie stabilnych i deterministycznych wyników.
  • topK : określa losowość i różnorodność wyników.
  • candidateCount : określa liczbę zwracanych unikalnych odpowiedzi. Pamiętaj, że dokładna liczba odpowiedzi może się różnić od wartości candidateCount, ponieważ duplikaty są automatycznie usuwane.
  • maxOutputTokens : określa maksymalną liczbę tokenów, które mogą zostać wygenerowane w odpowiedzi.

Więcej wskazówek dotyczących ustawiania konfiguracji opcjonalnych znajdziesz w sekcji GenerateContentRequest.

Obsługiwane funkcje i ograniczenia

  • Dane wejściowe muszą mieć mniej niż 4000 tokenów (czyli około 3000 słów w języku angielskim). Więcej informacji znajdziesz w dokumentacji referencyjnej countTokens.
  • Należy unikać przypadków użycia, które wymagają długiego wyniku (ponad 256 tokenów).
  • AICore wymusza limit wnioskowania na aplikację. Więcej informacji znajdziesz w sekcji Limit na aplikację.
  • W przypadku interfejsu Prompt API zweryfikowano te języki:
    • angielski
    • koreański

Typowe problemy z konfiguracją

Interfejsy ML Kit GenAI API korzystają z aplikacji Android AICore, aby uzyskać dostęp do modelu Gemini Nano. Gdy urządzenie jest dopiero skonfigurowane (w tym zresetowane) lub aplikacja AICore jest dopiero zresetowana (np. wyczyszczono dane, odinstalowano i ponownie zainstalowano), aplikacja AICore może nie mieć wystarczająco dużo czasu na dokończenie inicjowania (w tym pobrania najnowszych konfiguracji z serwera). W rezultacie interfejsy ML Kit GenAI API mogą nie działać zgodnie z oczekiwaniami. Oto typowe komunikaty o błędach konfiguracji, które mogą się pojawić, oraz sposoby ich rozwiązywania:

Przykładowy komunikat o błędzie Jak odpowiedzieć
AICore failed with error type 4-CONNECTION_ERROR and error code 601-BINDING_FAILURE: AICore service failed to bind. Może się to zdarzyć, gdy zainstalujesz aplikację za pomocą interfejsów ML Kit GenAI API natychmiast po skonfigurowaniu urządzenia lub gdy aplikacja AICore zostanie odinstalowana po zainstalowaniu aplikacji. Problem powinien rozwiązać się po zaktualizowaniu aplikacji AICore i ponownym zainstalowaniu aplikacji.
AICore failed with error type 3-PREPARATION_ERROR and error code 606-FEATURE_NOT_FOUND: Feature ... is not available. Może się to zdarzyć, gdy aplikacja AICore nie zakończyła pobierania najnowszych konfiguracji. Gdy urządzenie jest połączone z internetem, aktualizacja trwa zwykle od kilku minut do kilku godzin. Ponowne uruchomienie urządzenia może przyspieszyć aktualizację.

Pamiętaj, że jeśli program rozruchowy urządzenia jest bez blokady SIM, też zobaczysz ten błąd – ten interfejs API nie obsługuje urządzeń z programem rozruchowym bez blokady SIM.
AICore failed with error type 1-DOWNLOAD_ERROR and error code 0-UNKNOWN: Feature ... failed with failure status 0 and error esz: UNAVAILABLE: Unable to resolve host ... Utrzymuj połączenie z siecią, odczekaj kilka minut i spróbuj ponownie.