Prompt API 시작하기

이 페이지에서는 다음 작업을 수행하는 방법을 설명합니다.

  • Prompt API를 사용하도록 프로젝트 구성
  • 텍스트 전용 입력 제공 및 대답 수신
  • 관련 텍스트 입력과 함께 이미지 입력을 제공하고 대답 받기

Prompt API에 관한 자세한 내용은 Kotlin (com.google.mlkit.genai.prompt) 및 Java (com.google.mlkit.genai.prompt.java, com.google.mlkit.genai.prompt)의 참고 문서를 확인하세요.

프로젝트 구성

build.gradle 구성에 ML Kit Prompt API를 종속 항목으로 추가합니다.

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

Structured Output API를 사용하여 특정 형식의 응답이 필요한 경우 KSP를 구성하고 추가 종속 항목을 추가해야 합니다. 자세한 내용은 구조화된 출력 생성을 참조하세요.

생성 모델 구현

프로젝트에서 코드를 구현하려면 다음 단계를 따르세요.

  • generativeModel 객체를 만듭니다.

    Kotlin

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

    자바

    // Get a GenerativeModel instance
    GenerativeModelFutures generativeModelFutures = GenerativeModelFutures
        .from(Generation.INSTANCE.getClient());
    
  • Gemini Nano가 AVAILABLE,, DOWNLOADABLE 또는 UNAVAILABLE인지 확인합니다. 그런 다음 다운로드 가능한 경우 특성을 다운로드합니다.

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

    자바

    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.")

자바

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

자바

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() 함수에서 여러 이미지와 텍스트 입력을 함께 번들로 묶습니다. 이때 텍스트 프롬프트는 이미지와 관련된 질문 또는 명령어입니다. 동일한 요청에 최대 10개의 이미지를 번들로 묶을 수 있습니다.

Kotlin

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

자바

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

추론 결과 처리

  • 추론을 실행하고 결과를 가져옵니다. 텍스트 전용 프롬프트와 멀티모달 프롬프트 모두에 대해 전체 결과를 기다리거나 생성된 응답을 스트리밍할 수 있습니다.

    • 이는 결과를 반환하기 전에 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")
    

    자바

    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
    }
    

    자바

    // 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 참조를 확인하세요.
  • 긴 출력 (4,000개 이상의 토큰)이 필요한 사용 사례는 피해야 합니다.
  • AICore는 앱당 추론 할당량을 적용합니다. 자세한 내용은 애플리케이션당 할당량을 참고하세요.

일반적인 설정 문제

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: 호스트 …을(를) 확인할 수 없음으로 실패했습니다. 네트워크 연결을 유지하고 몇 분 정도 기다린 후 다시 시도하세요.