Prompt API を使ってみる

このページでは、次の操作を行う方法について説明します。

  • Prompt API を使用するようにプロジェクトを構成する
  • テキストのみの入力を提供してレスポンスを受け取る
  • 関連するテキスト入力とともに画像入力を提供し、レスポンスを受け取る

Prompt API の詳細については、Kotlin(com.google.mlkit.genai.prompt)と Java(com.google.mlkit.genai.prompt.javacom.google.mlkit.genai.prompt)のリファレンス ドキュメントをご覧ください。

[省略可] Gemma 3n モデルでプロンプトをテストする

実装する前に、Gemma 3n E4B モデルを使用して AI Studio でプロンプトをテストすることを検討してください。Gemma 3n の出力は、nano-v3 の出力と非常に類似していることが予想されます。

プロジェクトの構成

build.gradle 構成で ML Kit Prompt API を依存関係として追加します。

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

生成モデルを実装する

プロジェクトにコードを実装する手順は次のとおりです。

  • generativeModel オブジェクトを作成します。

    Kotlin

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

    Java

    // Get a GenerativeModel instance
    GenerativeModelFutures generativeModelFutures = GenerativeModelFutures
        .from(Generation.INSTANCE.getClient());
    
  • Gemini Nano が AVAILABLE,DOWNLOADABLEUNAVAILABLE のいずれであるかを確認します。ダウンロード可能な場合は、機能をダウンロードします。

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

テキストのみの入力を提供する

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

または、オプション パラメータを追加します。

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

省略可能なパラメータの詳細については、省略可能な構成をご覧ください。

マルチモーダル(画像とテキスト)入力を行う

generateContentRequest() 関数で画像とテキスト入力をバンドルします。テキスト プロンプトは、画像に関連する質問またはコマンドです。

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

推論結果を処理する

  • 推論を実行して結果を取得します。テキストのみのプロンプトとマルチモーダル プロンプトの両方で、完全な結果を待つか、生成されたレスポンスをストリーミングするかを選択できます。

    • これは、結果を返す前に AI モデルから結果全体を取得する非ストリーミング推論を使用します。

    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();
    
    • 次のスニペットは、ストリーミング推論を使用して結果を生成中にチャンク単位で取得する例です。

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

ストリーミング推論と非ストリーミング推論の詳細については、ストリーミングと非ストリーミングをご覧ください。

レイテンシの最適化

最初の推論呼び出しを最適化するために、アプリケーションは必要に応じて warmup() を呼び出すことができます。これにより、Gemini Nano がメモリに読み込まれ、ランタイム コンポーネントが初期化されます。

オプションの構成

GenerateContentRequest の一部として、次のオプション パラメータを設定できます。

  • temperature : トークン選択のランダム性の度合いを制御します。
  • seed : 安定した決定論的な結果を生成できるようにします。
  • topK : 結果のランダム性と多様性を制御します。
  • candidateCount : 返された一意のレスポンスの数をリクエストします。重複する回答は自動的に削除されるため、回答の正確な数は candidateCount と同じにならない場合があります。
  • maxOutputTokens : レスポンスで生成できるトークンの最大数を定義します。

オプションの構成の設定に関する詳しいガイダンスについては、GenerateContentRequest をご覧ください。

サポートされている機能と制限事項

  • 入力は 4,000 トークン(約 3,000 ワード(英語))未満にする必要があります。詳細については、countTokens リファレンスをご覧ください。
  • 長い出力(256 トークン以上)が必要なユースケースは避ける必要があります。
  • AICore は、アプリごとに推論割り当てを適用します。詳細については、アプリごとの割り当てをご覧ください。
  • Prompt API で次の言語が検証されています。
    • 英語
    • 韓国語

セットアップに関する一般的な問題

ML Kit GenAI API は、Android AICore アプリを使用して Gemini Nano にアクセスします。デバイスのセットアップ直後(リセット後を含む)や、AICore アプリのリセット直後(データの消去、アンインストール後の再インストールなど)は、AICore アプリが初期化(サーバーからの最新の設定のダウンロードなど)を完了するのに十分な時間がないことがあります。そのため、ML Kit GenAI API が想定どおりに機能しない可能性があります。表示される可能性のある一般的な設定エラー メッセージとその対処方法は次のとおりです。

エラー メッセージの例 対応方法
AICore がエラータイプ 4-CONNECTION_ERROR とエラーコード 601-BINDING_FAILURE で失敗しました。AICore サービスをバインドできませんでした。 この問題は、デバイスのセットアップ直後に ML Kit GenAI API を使用してアプリをインストールした場合や、アプリのインストール後に AICore がアンインストールされた場合に発生する可能性があります。AICore アプリを更新してからアプリを再インストールすると、問題が解決します。
AICore がエラータイプ 3-PREPARATION_ERROR とエラーコード 606-FEATURE_NOT_FOUND で失敗しました。機能 ... は利用できません。 これは、AICore が最新の構成のダウンロードを完了していない場合に発生する可能性があります。デバイスがインターネットに接続されている場合、通常は数分から数時間で更新が完了します。デバイスを再起動すると、更新を速めることができます。

デバイスのブートローダーがロック解除されている場合も、このエラーが表示されます。この API は、ブートローダーがロック解除されているデバイスをサポートしていません。
AICore がエラータイプ 1(DOWNLOAD_ERROR)とエラーコード 0(UNKNOWN)で失敗しました。機能 ... が失敗ステータス 0 とエラー esz(UNAVAILABLE: Unable to resolve host ...)で失敗しました。 ネットワーク接続を維持し、数分待ってから再試行します。