Korzystanie z interfejsu Prompt API

Na tej stronie dowiesz się, jak:

  • Konfigurowanie projektu pod kątem korzystania z interfejsu Prompt API
  • przesyłać dane wejściowe w formie tekstu i otrzymywać odpowiedź;
  • Prześlij obraz wraz z powiązanym tekstem i otrzymaj odpowiedź.

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

[Opcjonalnie] Testowanie prompta za pomocą modelu Gemma 3n

Przed wdrożeniem przetestuj prompt w AI Studio za pomocą modelu Gemma 3n E4B. Dane wyjściowe modelu Gemma 3n mogą być bardzo podobne do danych wyjściowych modelu nano-v3.

Konfigurowanie projektu

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

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

Wdrażanie modelu generatywnego

Aby wdrożyć kod w projekcie:

  • 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 Gemini Nano jest AVAILABLE,, DOWNLOADABLE lub 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 w formie tekstu

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.

Przekazywanie danych wejściowych multimodalnych (obrazów i tekstu)

Połącz obraz i dane wejściowe w postaci tekstu 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

  • Przeprowadź 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.

    • Wykorzystuje to wnioskowanie bez przesyłania strumieniowego, które pobiera cały wynik z modelu AI przed jego zwróceniem:

    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 pokazują, jak używać wnioskowania strumieniowego, 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 strumieniowym i niestrumieniowym znajdziesz w sekcji Strumieniowanie a niestrumieniowanie.

Optymalizacja czasu oczekiwania

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

Konfiguracje opcjonalne

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

  • 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 : żąda liczby unikalnych zwróconych odpowiedzi. Pamiętaj, że dokładna liczba odpowiedzi może być inna niż candidateCount, ponieważ duplikaty odpowiedzi są automatycznie usuwane.
  • maxOutputTokens : określa maksymalną liczbę tokenów, które mogą zostać wygenerowane w odpowiedzi.

Więcej wskazówek dotyczących konfigurowania opcjonalnych ustawień znajdziesz w sekcji GenerateContentRequest.

Obsługiwane funkcje i ograniczenia

  • Dane wejściowe muszą zawierać mniej niż 4000 tokenów (czyli około 3000 słów w języku angielskim). Więcej informacji znajdziesz w sekcji countTokens.
  • Unikaj przypadków użycia, które wymagają długiego wyniku (ponad 256 tokenów).
  • AICore wymusza limit wnioskowania dla każdej aplikacji. 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 Gemini Nano. Gdy urządzenie jest dopiero konfigurowane (w tym resetowane) lub aplikacja AICore jest dopiero resetowana (np. przez wyczyszczenie danych, odinstalowanie i ponowne zainstalowanie), może nie mieć wystarczająco dużo czasu na zakończenie inicjowania (w tym pobranie najnowszych konfiguracji z serwera). W związku z tym interfejsy ML Kit GenAI API mogą nie działać zgodnie z oczekiwaniami. Oto typowe komunikaty o błędach konfiguracji, które możesz zobaczyć, oraz sposoby ich rozwiązywania:

Przykładowy komunikat o błędzie Jak sobie z tym poradzić
Usługa AICore nie działa z powodu błędu typu 4-CONNECTION_ERROR i kodu błędu 601-BINDING_FAILURE: nie udało się powiązać usługi AICore. Może się to zdarzyć, gdy zainstalujesz aplikację za pomocą interfejsów ML Kit GenAI API natychmiast po skonfigurowaniu urządzenia lub gdy po zainstalowaniu aplikacji odinstalujesz AICore. Zaktualizowanie aplikacji AICore, a następnie ponowne zainstalowanie aplikacji powinno rozwiązać ten problem.
Usługa AICore nie działa z błędem typu 3-PREPARATION_ERROR i kodem błędu 606-FEATURE_NOT_FOUND: funkcja ... jest niedostępna. Może się tak zdarzyć, gdy AICore nie zakończyło 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 ten błąd pojawi się też, jeśli program rozruchowy urządzenia jest odblokowany – ten interfejs API nie obsługuje urządzeń z odblokowanymi programami rozruchowymi.
Usługa AICore zwróciła błąd typu 1-DOWNLOAD_ERROR i kod błędu 0-UNKNOWN: funkcja ... nie powiodła się ze stanem błędu 0 i błędem esz: UNAVAILABLE: nie udało się rozpoznać hosta ... Utrzymuj połączenie z siecią, poczekaj kilka minut i spróbuj ponownie.