GenAI Summarization API

使用 ML Kit 的 GenAI 摘要 API,即可自動生成文章和對話的摘要,並以項目符號清單的形式呈現。協助使用者瞭解大量文字內容。

裝置端生成式 AI 可解決資料隱私權和成本效益方面的疑慮,因此非常適合用於摘要功能。這類應用程式通常會處理私密資訊,因此裝置端處理程序對使用者隱私權至關重要。此外,摘要工作 (尤其是內容較長或項目較多的工作) 可能需要大量處理能力。在裝置上處理這類內容可減少伺服器負載、降低放送費用,同時保護使用者資料隱私。

主要功能

GenAI Summarization API 涵蓋下列功能:

  • 摘要文字,並分類為文章或對話。
  • 以一、二或三個項目符號總結輸出內容。

開始使用

build.gradle 設定中,將 ML Kit 摘要 API 新增為依附元件。

implementation("com.google.mlkit:genai-summarization:1.0.0-beta1")

接著,在專案中實作程式碼:

  1. 建立 Summarizer 物件。
  2. 如果可下載,請下載這項功能。
  3. 建立摘要要求。
  4. 執行推論並擷取結果。

Kotlin

val articleToSummarize = "Announcing a set of on-device GenAI APIs..."

// Define task with required input type, output type, and language
val summarizerOptions = SummarizerOptions.builder(context)
    .setInputType(InputType.ARTICLE)
    .setOutputType(OutputType.ONE_BULLET)
    .setLanguage(Language.ENGLISH)
    .build()
val summarizer = Summarization.getClient(summarizerOptions)

suspend fun prepareAndStartSummarization() {
    // Check feature availability. Status will be one of the following:
    // UNAVAILABLE, DOWNLOADABLE, DOWNLOADING, AVAILABLE
    val featureStatus = summarizer.checkFeatureStatus().await()

    if (featureStatus == FeatureStatus.DOWNLOADABLE) {
        // Download feature if necessary. If downloadFeature is not called,
        // the first inference request will also trigger the feature to be
        // downloaded if it's not already downloaded.
        summarizer.downloadFeature(object : DownloadCallback {
            override fun onDownloadStarted(bytesToDownload: Long) { }

            override fun onDownloadFailed(e: GenAiException) { }

            override fun onDownloadProgress(totalBytesDownloaded: Long) {}

            override fun onDownloadCompleted() {
                startSummarizationRequest(articleToSummarize, summarizer)
            }
        })
    } else if (featureStatus == FeatureStatus.DOWNLOADING) {
        // Inference request will automatically run once feature is
        // downloaded. If Gemini Nano is already downloaded on the device,
        // the feature-specific LoRA adapter model will be downloaded
        // quickly. However, if Gemini Nano is not already downloaded, the
        // download process may take longer.
        startSummarizationRequest(articleToSummarize, summarizer)
    } else if (featureStatus == FeatureStatus.AVAILABLE) {
        startSummarizationRequest(articleToSummarize, summarizer)
    }
}

fun startSummarizationRequest(text: String, summarizer: Summarizer) {
    // Create task request
    val summarizationRequest = SummarizationRequest.builder(text).build()

    // Start summarization request with streaming response
    summarizer.runInference(summarizationRequest) { newText ->
        // Show new text in UI
    }

    // You can also get a non-streaming response from the request
    // val summarizationResult = summarizer.runInference(
    //     summarizationRequest).get().summary
}

// Be sure to release the resource when no longer needed
// For example, on viewModel.onCleared() or activity.onDestroy()
summarizer.close()

Java

String articleToSummarize = "Announcing: a set of on-device GenAI AI APIs.";

// Define task with required input type, output type, and language
SummarizerOptions summarizerOptions = 
    SummarizerOptions.builder(context)
        .setInputType(SummarizerOptions.InputType.ARTICLE)
        .setOutputType(SummarizerOptions.OutputType.ONE_BULLET)
        .setLanguage(SummarizerOptions.Language.ENGLISH)
        .build();
Summarizer summarizer = Summarization.getClient(summarizerOptions);

void prepareAndStartSummarization()
        throws ExecutionException, InterruptedException {
    // Check feature availability. Status will be one of the following:
    // UNAVAILABLE, DOWNLOADABLE, DOWNLOADING, AVAILABLE
    try {
        int featureStatus = summarizer.checkFeatureStatus().get();
        if (featureStatus == FeatureStatus.DOWNLOADABLE) {
            // Download feature if necessary.
            // If downloadFeature is not called, the first inference request
            // will also trigger the feature to be downloaded if it's not
            // already downloaded.
            summarizer.downloadFeature(new DownloadCallback() {
                @Override
                public void onDownloadCompleted() {
                    startSummarizationRequest(articleToSummarize, summarizer);
                }

                @Override
                public void onDownloadFailed(GenAiException e) { /* handle error */ }

                @Override
                public void onDownloadProgress(long totalBytesDownloaded) {}

                @Override
                public void onDownloadStarted(long bytesDownloaded) {}
            });
        } else if (featureStatus == FeatureStatus.DOWNLOADING) {
            // Inference request will automatically run once feature is
            // downloaded. If Gemini Nano is already downloaded on the
            // device, the feature-specific LoRA adapter model will be
            // downloaded quickly. However, if Gemini Nano is not already
            // downloaded, the download process may take longer.
            startSummarizationRequest(articleToSummarize, summarizer);
        } else if (featureStatus == FeatureStatus.AVAILABLE) {
            startSummarizationRequest(articleToSummarize, summarizer);
        }
    } catch (ExecutionException | InterruptedException e) {
        e.printStackTrace();
    }
}

void startSummarizationRequest(String text, Summarizer summarizer) {
    // Create task request
    SummarizationRequest summarizationRequest =
        SummarizationRequest.builder(text).build();

    // Start summarization request with streaming response
    summarizer.runInference(summarizationRequest, newText -> {
        // Show new text in UI
    });

    // You can also get a non-streaming response from the request
    // ListenableFuture<SummarizationResult> summarizationResult
    //         = summarizer.runInference(summarizationRequest);
    // String summary = summarizationResult.get().getSummary();
}

// Be sure to release the resource when no longer needed
// For example, on viewModel.onCleared() or activity.onDestroy()
summarizer.close();

模型如何處理不同的輸入類型

如果將文字輸入指定為 InputType.CONVERSATION,模型會預期輸入內容採用下列格式:

<name>: <message>
<name2>: <message2>
<name>: <message3>
<name3>: <message4>

這有助於模型進一步瞭解對話和互動,進而生成更準確的摘要。

支援的功能和限制

輸入內容不得超過 4,000 個符記 (或約 3,000 個英文字)。如果輸入內容超過 4000 個權杖,請考慮下列選項:

  • 優先摘要前 4000 個權杖。測試結果顯示,這通常能為較長的輸入內容產生優質結果。建議呼叫 setLongInputAutoTruncationEnabled 開啟自動截斷功能,系統就會自動截斷多餘的輸入內容。
  • 將輸入內容分成 4000 個權杖的群組,然後分別摘要。
  • 建議改用更適合大型輸入內容的雲端解決方案。

如果是 InputType.ARTICLE,輸入內容也必須超過 400 個半形字元,且文章至少要有 300 字,模型才能發揮最佳效用。

生成式 AI 摘要 API 支援英文、日文和韓文,並在 SummarizerOptions.Language 中定義。

特定功能設定 (由 SummarizerOptions 指定) 的可用性可能因特定裝置的設定,以及已下載至裝置的模型而異。

如要確保裝置支援所要求的 SummarizerOptions,開發人員最可靠的方式是呼叫 checkFeatureStatus() 方法。這個方法會在執行階段提供裝置上功能可用性的明確狀態。

常見設定問題

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 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 ... 保持網路連線,稍待幾分鐘後再試一次。