Làm quen với Prompt API

Trang này mô tả cách thực hiện những việc sau:

  • Định cấu hình dự án để sử dụng Prompt API
  • Cung cấp dữ liệu đầu vào chỉ có văn bản và nhận câu trả lời
  • Cung cấp dữ liệu đầu vào dạng hình ảnh cùng với dữ liệu đầu vào dạng văn bản có liên quan và nhận câu trả lời

Để biết thêm thông tin chi tiết về Prompt API, hãy xem tài liệu tham khảo cho Kotlin (com.google.mlkit.genai.prompt) và Java (com.google.mlkit.genai.prompt.java, com.google.mlkit.genai.prompt).

Định cấu hình dự án

Thêm Prompt API của Bộ công cụ học máy làm phần phụ thuộc trong cấu hình build.gradle:

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

Nếu cần phản hồi ở một định dạng nhất định bằng Structured Output API, bạn cần định cấu hình KSP và thêm các phần phụ thuộc bổ sung. Để biết thông tin chi tiết, hãy xem bài viết Tạo kết quả có cấu trúc.

Triển khai mô hình tạo sinh

Để triển khai mã trong dự án, hãy làm theo các bước sau:

  • Tạo đối tượng generativeModel:

    Kotlin

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

    Java

    // Get a GenerativeModel instance
    GenerativeModelFutures generativeModelFutures = GenerativeModelFutures
        .from(Generation.INSTANCE.getClient());
    
  • Kiểm tra xem Gemini Nano có AVAILABLE, DOWNLOADABLE hay UNAVAILABLE hay không. Sau đó, hãy tải tính năng xuống nếu có thể tải xuống:

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

Cung cấp dữ liệu đầu vào chỉ có văn bản

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

Ngoài ra, bạn có thể thêm các tham số không bắt buộc:

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

Để biết thêm thông tin về các tham số không bắt buộc, hãy xem phần Cấu hình không bắt buộc.

Cung cấp dữ liệu đầu vào đa phương thức (hình ảnh và văn bản)

Gộp nhiều hình ảnh và một dữ liệu đầu vào dạng văn bản vào hàm generateContentRequest(), trong đó câu lệnh văn bản là một câu hỏi hoặc lệnh liên quan đến hình ảnh. Bạn có thể gộp tối đa 10 hình ảnh trong cùng một yêu cầu.

Kotlin

val response = generativeModel.generateContent(
    generateContentRequest(ImagePart(bitmap1), ImagePart(bitmap2), TextPart(textPrompt)) {
        // optional parameters
        ...
    },
)

Java

GenerateContentResponse response = generativeModelFutures.generateContent(
    new GenerateContentRequest.Builder(
        new Content.Builder()
            .addPart(new ImagePart(bitmap1))
            .addPart(new ImagePart(bitmap2))
            .addPart(new TextPart("textPrompt"))
            .build())
    // optional parameters
    .build())
.get();

Xử lý kết quả suy luận

  • Chạy suy luận và truy xuất kết quả. Bạn có thể chọn đợi kết quả đầy đủ hoặc truyền trực tuyến câu trả lời khi câu trả lời được tạo cho cả câu lệnh chỉ có văn bản và câu lệnh đa phương thức.

    • Thao tác này sử dụng suy luận không truyền trực tuyến, tức là truy xuất toàn bộ kết quả từ mô hình AI trước khi trả về kết quả:

    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();
    
    • Các đoạn mã sau đây là ví dụ về cách sử dụng tính năng suy luận trực tuyến, giúp truy xuất kết quả theo từng phần khi kết quả được tạo:

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

Để biết thêm thông tin về suy luận truyền trực tuyến và không truyền trực tuyến, hãy xem phần Truyền trực tuyến so với không truyền trực tuyến.

Tối ưu hoá độ trễ

Để tối ưu hoá cho lệnh gọi suy luận đầu tiên, ứng dụng của bạn có thể gọi warmup() (không bắt buộc). Thao tác này sẽ tải Gemini Nano vào bộ nhớ và khởi chạy các thành phần thời gian chạy.

Cấu hình không bắt buộc

Trong mỗi GenerateContentRequest, bạn có thể đặt các tham số không bắt buộc sau:

  • temperature : Kiểm soát mức độ ngẫu nhiên trong việc chọn mã thông báo.
  • seed : Cho phép tạo kết quả ổn định và tất định.
  • topK : Kiểm soát tính ngẫu nhiên và đa dạng trong kết quả.
  • candidateCount : Yêu cầu số lượng phản hồi riêng biệt được trả về. Xin lưu ý rằng số lượng phản hồi chính xác có thể không giống với candidateCount vì các phản hồi trùng lặp sẽ tự động bị xoá.
  • maxOutputTokens : Xác định số lượng mã thông báo tối đa có thể được tạo trong phản hồi.

Để biết thêm hướng dẫn về cách thiết lập cấu hình không bắt buộc, hãy xem bài viết GenerateContentRequest.

Các tính năng được hỗ trợ và điểm hạn chế

  • Nội dung nhập phải dưới 4.000 mã thông báo (hoặc khoảng 3.000 từ tiếng Anh). Để biết thêm thông tin, hãy xem tài liệu tham khảo về countTokens.
  • Bạn nên tránh các trường hợp sử dụng yêu cầu kết quả dài (hơn 4.000 mã thông báo).
  • AICore thực thi hạn mức suy luận cho mỗi ứng dụng. Để biết thêm thông tin, hãy xem phần Hạn mức cho mỗi ứng dụng.

Các vấn đề thường gặp khi thiết lập

Các API GenAI của Bộ công cụ học máy dựa vào ứng dụng Android AICore để truy cập vào Gemini Nano. Khi một thiết bị vừa được thiết lập (bao gồm cả việc đặt lại) hoặc ứng dụng AICore vừa được đặt lại (ví dụ: xoá dữ liệu, gỡ cài đặt rồi cài đặt lại), ứng dụng AICore có thể không có đủ thời gian để hoàn tất quá trình khởi chạy (bao gồm cả việc tải các cấu hình mới nhất xuống từ máy chủ). Do đó, các API GenAI của Bộ công cụ học máy có thể không hoạt động như mong đợi. Dưới đây là các thông báo lỗi thiết lập thường gặp mà bạn có thể thấy và cách xử lý:

Ví dụ về thông báo lỗi Cách xử lý
AICore không thành công với loại lỗi 4-CONNECTION_ERROR và mã lỗi 601-BINDING_FAILURE: Dịch vụ AICore không liên kết được. Điều này có thể xảy ra khi bạn cài đặt ứng dụng bằng API GenAI của Bộ công cụ học máy ngay sau khi thiết lập thiết bị hoặc khi AICore bị gỡ cài đặt sau khi ứng dụng của bạn được cài đặt. Bạn có thể khắc phục vấn đề này bằng cách cập nhật ứng dụng AICore rồi cài đặt lại ứng dụng.
AICore không thành công với loại lỗi 3-PREPARATION_ERROR và mã lỗi 606-FEATURE_NOT_FOUND: Tính năng ... không hoạt động. Điều này có thể xảy ra khi AICore chưa tải xong các cấu hình mới nhất. Khi thiết bị kết nối với Internet, quá trình cập nhật thường mất từ vài phút đến vài giờ. Việc khởi động lại thiết bị có thể đẩy nhanh quá trình cập nhật.

Lưu ý rằng nếu trình tải khởi động của thiết bị được mở khoá, bạn cũng sẽ thấy lỗi này. API này không hỗ trợ các thiết bị có trình tải khởi động đã mở khoá.
AICore không thành công với loại lỗi 1-DOWNLOAD_ERROR và mã lỗi 0-UNKNOWN: Tính năng ... không thành công với trạng thái không thành công 0 và lỗi esz: UNAVAILABLE: Không thể phân giải máy chủ lưu trữ ... Duy trì kết nối mạng, đợi vài phút rồi thử lại.