Mulai menggunakan Gemini API di aplikasi Android (SDK klien)

Tutorial ini menunjukkan cara mengakses Gemini API langsung dari aplikasi Android Anda menggunakan SDK klien AI Google untuk Android. Anda dapat menggunakan SDK klien ini jika tidak ingin bekerja secara langsung dengan REST API atau kode sisi server (seperti Python) untuk mengakses model Gemini di aplikasi Android.

Dalam tutorial ini, Anda akan mempelajari cara melakukan hal berikut:

Selain itu, tutorial ini berisi bagian tentang kasus penggunaan lanjutan (seperti token penghitungan) serta opsi untuk mengontrol pembuatan konten.

Pertimbangkan untuk mengakses Gemini di perangkat

SDK klien untuk Android yang dijelaskan dalam tutorial ini memungkinkan Anda mengakses model Gemini Pro yang berjalan di server Google. Untuk kasus penggunaan yang melibatkan pemrosesan data sensitif, ketersediaan offline, atau untuk menghemat biaya untuk alur penggunaan yang sering digunakan, Anda dapat mempertimbangkan untuk mengakses Gemini Nano yang berjalan di perangkat. Untuk mengetahui detail selengkapnya, lihat tutorial Android (di perangkat).

Prasyarat

Tutorial ini mengasumsikan bahwa Anda sudah terbiasa menggunakan Android Studio untuk mengembangkan aplikasi Android.

Untuk menyelesaikan tutorial ini, pastikan lingkungan pengembangan dan aplikasi Android Anda memenuhi persyaratan berikut:

  • Android Studio (versi terbaru)
  • Aplikasi Android Anda harus menargetkan API level 21 atau yang lebih tinggi.

Menyiapkan project

Sebelum memanggil Gemini API, Anda perlu menyiapkan project Android, yang mencakup penyiapan kunci API, menambahkan dependensi SDK ke project Android Anda, dan menginisialisasi model tersebut.

Menyiapkan kunci API

Untuk menggunakan Gemini API, Anda memerlukan kunci API. Jika Anda belum memilikinya, buat kunci di Google AI Studio.

Mendapatkan kunci API

Mengamankan kunci API Anda

Sebaiknya Anda tidak melakukan check in kunci API ke dalam sistem kontrol versi Anda. Sebagai gantinya, sebaiknya simpan kunci API dalam file local.properties (yang terletak di direktori utama project, tetapi dikecualikan dari kontrol versi), lalu gunakan plugin Secrets Gradle untuk Android untuk membaca kunci API Anda sebagai variabel Konfigurasi Build.

Kotlin

// Access your API key as a Build Configuration variable
val apiKey = BuildConfig.apiKey

Java

// Access your API key as a Build Configuration variable
String apiKey = BuildConfig.apiKey;

Semua cuplikan dalam tutorial ini menggunakan praktik terbaik ini. Selain itu, jika Anda ingin melihat implementasi plugin Secrets Gradle, tinjau aplikasi contoh untuk SDK ini atau gunakan pratinjau terbaru Android Studio Iguana yang memiliki template Gemini API Starter (yang mencakup file local.properties untuk membantu Anda memulai).

Menambahkan dependensi SDK ke project Anda

  1. Dalam file konfigurasi Gradle modul (level aplikasi) Anda (seperti <project>/<app-module>/build.gradle.kts), tambahkan dependensi untuk Google AI SDK untuk Android:

    Kotlin

    dependencies {
      // ... other androidx dependencies
    
      // add the dependency for the Google AI client SDK for Android
      implementation("com.google.ai.client.generativeai:generativeai:0.3.0")
    }
    

    Java

    Untuk Java, Anda perlu menambahkan dua library tambahan.

    dependencies {
        // ... other androidx dependencies
    
        // add the dependency for the Google AI client SDK for Android
        implementation("com.google.ai.client.generativeai:generativeai:0.3.0")
    
        // Required for one-shot operations (to use `ListenableFuture` from Guava Android)
        implementation("com.google.guava:guava:31.0.1-android")
    
        // Required for streaming operations (to use `Publisher` from Reactive Streams)
        implementation("org.reactivestreams:reactive-streams:1.0.4")
    }
    
  2. Sinkronkan project Android Anda dengan file Gradle.

Menginisialisasi Model Generatif

Sebelum dapat melakukan panggilan API, Anda perlu melakukan inisialisasi objek GenerativeModel:

Kotlin

val generativeModel = GenerativeModel(
    // Use a model that's applicable for your use case (see "Implement basic use cases" below)
    modelName = "MODEL_NAME",
    // Access your API key as a Build Configuration variable (see "Set up your API key" above)
    apiKey = BuildConfig.apiKey
)

Java

Untuk Java, Anda juga perlu melakukan inisialisasi objek GenerativeModelFutures.

// Use a model that's applicable for your use case (see "Implement basic use cases" below)
GenerativeModel gm = new GenerativeModel(/* modelName */ "MODEL_NAME",
// Access your API key as a Build Configuration variable (see "Set up your API key" above)
    /* apiKey */ BuildConfig.apiKey);

// Use the GenerativeModelFutures Java compatibility layer which offers
// support for ListenableFuture and Publisher APIs
GenerativeModelFutures model = GenerativeModelFutures.from(gm);

Saat menetapkan model, perhatikan hal-hal berikut:

  • Gunakan model yang spesifik untuk kasus penggunaan Anda (misalnya, gemini-pro-vision untuk input multimodal). Dalam panduan ini, petunjuk untuk setiap penerapan mencantumkan model yang direkomendasikan untuk setiap kasus penggunaan.

Menerapkan kasus penggunaan umum

Setelah project siap, Anda dapat menjelajah menggunakan Gemini API untuk menerapkan berbagai kasus penggunaan:

Membuat teks dari input khusus teks

Jika input perintah hanya menyertakan teks, gunakan model gemini-pro dengan generateContent untuk menghasilkan output teks:

Kotlin

Perhatikan bahwa generateContent() adalah fungsi penangguhan dan perlu dipanggil dari cakupan Coroutine. Jika Anda belum terbiasa dengan Coroutine, baca Coroutine Kotlin di Android.

val generativeModel = GenerativeModel(
    // For text-only input, use the gemini-pro model
    modelName = "gemini-pro",
    // Access your API key as a Build Configuration variable (see "Set up your API key" above)
    apiKey = BuildConfig.apiKey
)

val prompt = "Write a story about a magic backpack."
val response = generativeModel.generateContent(prompt)
print(response.text)

Java

Perhatikan bahwa generateContent() menampilkan ListenableFuture. Jika Anda tidak terbiasa dengan API ini, lihat dokumentasi Android tentang Menggunakan ListenableFuture.

// For text-only input, use the gemini-pro model
GenerativeModel gm = new GenerativeModel(/* modelName */ "gemini-pro",
// Access your API key as a Build Configuration variable (see "Set up your API key" above)
    /* apiKey */ BuildConfig.apiKey);
GenerativeModelFutures model = GenerativeModelFutures.from(gm);

Content content = new Content.Builder()
    .addText("Write a story about a magic backpack.")
    .build();

Executor executor = // ...

ListenableFuture<GenerateContentResponse> response = model.generateContent(content);
Futures.addCallback(response, new FutureCallback<GenerateContentResponse>() {
    @Override
    public void onSuccess(GenerateContentResponse result) {
        String resultText = result.getText();
        System.out.println(resultText);
    }

    @Override
    public void onFailure(Throwable t) {
        t.printStackTrace();
    }
}, executor);

Membuat teks dari input teks dan gambar (multimodal)

Gemini menyediakan model multimodal (gemini-pro-vision), sehingga Anda dapat memasukkan teks dan gambar. Pastikan Anda meninjau persyaratan gambar untuk perintah.

Saat input perintah menyertakan teks dan gambar, gunakan model gemini-pro-vision dengan generateContent untuk menghasilkan output teks:

Kotlin

Perhatikan bahwa generateContent() adalah fungsi penangguhan dan perlu dipanggil dari cakupan Coroutine. Jika Anda belum terbiasa dengan Coroutine, baca Coroutine Kotlin di Android.

val generativeModel = GenerativeModel(
    // For text-and-images input (multimodal), use the gemini-pro-vision model
    modelName = "gemini-pro-vision",
    // Access your API key as a Build Configuration variable (see "Set up your API key" above)
    apiKey = BuildConfig.apiKey
)

val image1: Bitmap = // ...
val image2: Bitmap = // ...

val inputContent = content {
    image(image1)
    image(image2)
    text("What's different between these pictures?")
}

val response = generativeModel.generateContent(inputContent)
print(response.text)

Java

Perhatikan bahwa generateContent() menampilkan ListenableFuture. Jika Anda tidak terbiasa dengan API ini, lihat dokumentasi Android tentang Menggunakan ListenableFuture.

// For text-and-images input (multimodal), use the gemini-pro-vision model
GenerativeModel gm = new GenerativeModel(/* modelName */ "gemini-pro-vision",
// Access your API key as a Build Configuration variable (see "Set up your API key" above)
    /* apiKey */ BuildConfig.apiKey);
GenerativeModelFutures model = GenerativeModelFutures.from(gm);

Bitmap image1 = // ...
Bitmap image2 = // ...

Content content = new Content.Builder()
    .addText("What's different between these pictures?")
    .addImage(image1)
    .addImage(image2)
    .build();

Executor executor = // ...

ListenableFuture<GenerateContentResponse> response = model.generateContent(content);
Futures.addCallback(response, new FutureCallback<GenerateContentResponse>() {
    @Override
    public void onSuccess(GenerateContentResponse result) {
        String resultText = result.getText();
        System.out.println(resultText);
    }

    @Override
    public void onFailure(Throwable t) {
        t.printStackTrace();
    }
}, executor);

Membuat percakapan multi-giliran (chat)

Dengan Gemini, Anda dapat membuat percakapan berformat bebas di berbagai kesempatan. SDK menyederhanakan proses dengan mengelola status percakapan, sehingga tidak seperti generateContent, Anda tidak perlu menyimpan sendiri histori percakapan sendiri.

Untuk membuat percakapan multi-giliran (seperti chat), gunakan model gemini-pro, dan lakukan inisialisasi chat dengan memanggil startChat(). Kemudian gunakan sendMessage() untuk mengirim pesan pengguna baru, yang juga akan menambahkan pesan dan respons ke histori chat.

Ada dua kemungkinan opsi untuk role yang dikaitkan dengan konten dalam percakapan:

  • user: peran yang menyediakan dialog. Nilai ini merupakan default untuk panggilan sendMessage.

  • model: peran yang memberikan respons. Peran ini dapat digunakan saat memanggil startChat() dengan history yang ada.

Kotlin

Perhatikan bahwa generateContent() adalah fungsi penangguhan dan perlu dipanggil dari cakupan Coroutine. Jika Anda belum terbiasa dengan Coroutine, baca Coroutine Kotlin di Android.

val generativeModel = GenerativeModel(
    // For text-only input, use the gemini-pro model
    modelName = "gemini-pro",
    // Access your API key as a Build Configuration variable (see "Set up your API key" above)
    apiKey = BuildConfig.apiKey
)

val chat = generativeModel.startChat(
    history = listOf(
        content(role = "user") { text("Hello, I have 2 dogs in my house.") },
        content(role = "model") { text("Great to meet you. What would you like to know?") }
    )
)

chat.sendMessage("How many paws are in my house?")

Java

Perhatikan bahwa generateContent() menampilkan ListenableFuture. Jika Anda tidak terbiasa dengan API ini, lihat dokumentasi Android tentang Menggunakan ListenableFuture.

// For text-only input, use the gemini-pro model
GenerativeModel gm = new GenerativeModel(/* modelName */ "gemini-pro",
// Access your API key as a Build Configuration variable (see "Set up your API key" above)
    /* apiKey */ BuildConfig.apiKey);
GenerativeModelFutures model = GenerativeModelFutures.from(gm);

// (optional) Create previous chat history for context
Content.Builder userContentBuilder = new Content.Builder();
userContentBuilder.setRole("user");
userContentBuilder.addText("Hello, I have 2 dogs in my house.");
Content userContent = userContentBuilder.build();

Content.Builder modelContentBuilder = new Content.Builder();
modelContentBuilder.setRole("model");
modelContentBuilder.addText("Great to meet you. What would you like to know?");
Content modelContent = userContentBuilder.build();

List<Content> history = Arrays.asList(userContent, modelContent);

// Initialize the chat
ChatFutures chat = model.startChat(history);

// Create a new user message
Content userMessage = new Content.Builder()
    .setRole("user")
    .addText("How many paws are in my house?")
    .build();

Executor executor = // ...

// Send the message
ListenableFuture<GenerateContentResponse> response = chat.sendMessage(userMessage);

Futures.addCallback(response, new FutureCallback<GenerateContentResponse>() {
    @Override
    public void onSuccess(GenerateContentResponse result) {
        String resultText = result.getText();
        System.out.println(resultText);
    }

    @Override
    public void onFailure(Throwable t) {
        t.printStackTrace();
    }
}, executor);

Menggunakan streaming untuk interaksi yang lebih cepat

Secara default, model akan menampilkan respons setelah menyelesaikan seluruh proses pembuatan. Anda dapat mencapai interaksi yang lebih cepat dengan tidak menunggu seluruh hasil, dan sebagai gantinya menggunakan streaming untuk menangani hasil parsial.

Contoh berikut menunjukkan cara mengimplementasikan streaming dengan generateContentStream untuk menghasilkan teks dari prompt input teks dan gambar.

Kotlin

Perhatikan bahwa generateContentStream() adalah fungsi penangguhan dan perlu dipanggil dari cakupan Coroutine. Jika Anda belum terbiasa dengan Coroutine, baca Coroutine Kotlin di Android.

val generativeModel = GenerativeModel(
    // For text-and-image input (multimodal), use the gemini-pro-vision model
    modelName = "gemini-pro-vision",
    // Access your API key as a Build Configuration variable (see "Set up your API key" above)
    apiKey = BuildConfig.apiKey
)

val image1: Bitmap = // ...
val image2: Bitmap = // ...

val inputContent = content {
    image(image1)
    image(image2)
    text("What's the difference between these pictures?")
}

var fullResponse = ""
generativeModel.generateContentStream(inputContent).collect { chunk ->
    print(chunk.text)
    fullResponse += chunk.text
}

Java

Metode streaming Java di SDK ini menampilkan jenis Publisher dari library Reactive Streams.

// For text-and-images input (multimodal), use the gemini-pro-vision model
GenerativeModel gm = new GenerativeModel(/* modelName */ "gemini-pro-vision",
// Access your API key as a Build Configuration variable (see "Set up your API key" above)
    /* apiKey */ BuildConfig.apiKey);
GenerativeModelFutures model = GenerativeModelFutures.from(gm);

Bitmap image1 = // ...
Bitmap image2 = // ...

Content content = new Content.Builder()
    .addText("What's different between these pictures?")
    .addImage(image1)
    .addImage(image2)
    .build();

Publisher<GenerateContentResponse> streamingResponse =
    model.generateContentStream(content);

final String[] fullResponse = {""};

streamingResponse.subscribe(new Subscriber<GenerateContentResponse>() {
    @Override
    public void onNext(GenerateContentResponse generateContentResponse) {
        String chunk = generateContentResponse.getText();
        fullResponse[0] += chunk;
    }

    @Override
    public void onComplete() {
        System.out.println(fullResponse[0]);
    }

    @Override
    public void onError(Throwable t) {
        t.printStackTrace();
    }

    @Override
    public void onSubscribe(Subscription s) { }
});

Anda dapat menggunakan pendekatan serupa untuk kasus penggunaan chat dan input khusus teks:

Kotlin

Perhatikan bahwa generateContentStream() adalah fungsi penangguhan dan perlu dipanggil dari cakupan Coroutine. Jika Anda belum terbiasa dengan Coroutine, baca Coroutine Kotlin di Android.

// Use streaming with text-only input
generativeModel.generateContentStream(inputContent).collect { chunk ->
    print(chunk.text)
}
// Use streaming with multi-turn conversations (like chat)
val chat = generativeModel.startChat()
chat.sendMessageStream(inputContent).collect { chunk ->
    print(chunk.text)
}

Java

Metode streaming Java di SDK ini menampilkan jenis Publisher dari library Reactive Streams.

// Use streaming with text-only input
Publisher<GenerateContentResponse> streamingResponse =
    model.generateContentStream(inputContent);

final String[] fullResponse = {""};

streamingResponse.subscribe(new Subscriber<GenerateContentResponse>() {
    @Override
    public void onNext(GenerateContentResponse generateContentResponse) {
        String chunk = generateContentResponse.getText();
        fullResponse[0] += chunk;
    }

    @Override
    public void onComplete() {
        System.out.println(fullResponse[0]);
    }

    // ... other methods omitted for brevity
});
// Use streaming with multi-turn conversations (like chat)
ChatFutures chat = model.startChat(history);

Publisher<GenerateContentResponse> streamingResponse =
    chat.sendMessageStream(inputContent);

final String[] fullResponse = {""};

streamingResponse.subscribe(new Subscriber<GenerateContentResponse>() {
    @Override
    public void onNext(GenerateContentResponse generateContentResponse) {
        String chunk = generateContentResponse.getText();
        fullResponse[0] += chunk;
    }

    @Override
    public void onComplete() {
        System.out.println(fullResponse[0]);
    }

    // ... other methods omitted for brevity
});

Menerapkan kasus penggunaan lanjutan

Kasus penggunaan umum yang dijelaskan di bagian tutorial sebelumnya membantu Anda merasa nyaman dalam menggunakan Gemini API. Bagian ini menjelaskan beberapa kasus penggunaan yang mungkin dianggap lebih lanjut.

Hitung token

Saat menggunakan perintah panjang, sebaiknya hitung token sebelum mengirim konten apa pun ke model. Contoh berikut menunjukkan cara menggunakan countTokens() untuk berbagai kasus penggunaan:

Kotlin

Perhatikan bahwa countTokens() adalah fungsi penangguhan dan perlu dipanggil dari cakupan Coroutine. Jika Anda belum terbiasa dengan Coroutine, baca Coroutine Kotlin di Android.

// For text-only input
val (totalTokens) = generativeModel.countTokens("Write a story about a magic backpack.")

// For text-and-image input (multi-modal)
val multiModalContent = content {
    image(image1)
    image(image2)
    text("What's the difference between these pictures?")
}

val (totalTokens) = generativeModel.countTokens(multiModalContent)

// For multi-turn conversations (like chat)
val history = chat.history
val messageContent = content { text("This is the message I intend to send")}
val (totalTokens) = generativeModel.countTokens(*history.toTypedArray(), messageContent)

Java

Perhatikan bahwa countTokens() menampilkan ListenableFuture. Jika Anda tidak terbiasa dengan API ini, lihat dokumentasi Android tentang Menggunakan ListenableFuture.

Content text = new Content.Builder()
    .addText("Write a story about a magic backpack.")
    .build();

Executor executor = // ...

// For text-only input
ListenableFuture<CountTokensResponse> countTokensResponse = model.countTokens(text);

Futures.addCallback(countTokensResponse, new FutureCallback<CountTokensResponse>() {
    @Override
    public void onSuccess(CountTokensResponse result) {
        int totalTokens = result.getTotalTokens();
        System.out.println("TotalTokens = " + totalTokens);
    }

    @Override
    public void onFailure(Throwable t) {
        t.printStackTrace();
    }
}, executor);

// For text-and-image input
Bitmap image1 = // ...
Bitmap image2 = // ...

Content multiModalContent = new Content.Builder()
    .addImage(image1)
    .addImage(image2)
    .addText("What's different between these pictures?")
    .build();

ListenableFuture<CountTokensResponse> countTokensResponse = model.countTokens(multiModalContent);

// For multi-turn conversations (like chat)
List<Content> history = chat.getChat().getHistory();

Content messageContent = new Content.Builder()
    .addText("This is the message I intend to send")
    .build();

Collections.addAll(history, messageContent);

ListenableFuture<CountTokensResponse> countTokensResponse = model.countTokens(history.toArray(new Content[0]));

Opsi untuk mengontrol pembuatan konten

Anda dapat mengontrol pembuatan konten dengan mengonfigurasi parameter model dan dengan menggunakan setelan keamanan.

Mengonfigurasi parameter model

Setiap prompt yang Anda kirim ke model menyertakan parameter value yang mengontrol cara model menghasilkan respons. Model ini dapat memberikan hasil yang berbeda untuk parameter value yang berbeda. Pelajari Parameter model lebih lanjut.

Kotlin

val config = generationConfig {
    temperature = 0.9f
    topK = 16
    topP = 0.1f
    maxOutputTokens = 200
    stopSequences = listOf("red")
}

val generativeModel = GenerativeModel(
    modelName = "MODEL_NAME",
    apiKey = BuildConfig.apiKey,
    generationConfig = config
)

Java

GenerationConfig.Builder configBuilder = new GenerationConfig.Builder();
configBuilder.temperature = 0.9f;
configBuilder.topK = 16;
configBuilder.topP = 0.1f;
configBuilder.maxOutputTokens = 200;
configBuilder.stopSequences = Arrays.asList("red");

GenerationConfig generationConfig = configBuilder.build();

GenerativeModel gm = new GenerativeModel(
    "MODEL_NAME",
    BuildConfig.apiKey,
    generationConfig
);

GenerativeModelFutures model = GenerativeModelFutures.from(gm);

Gunakan setelan keamanan

Anda dapat menggunakan setelan keamanan untuk menyesuaikan kemungkinan mendapatkan respons yang mungkin dianggap berbahaya. Secara default, setelan keamanan memblokir konten yang memiliki kemungkinan sedang dan/atau tinggi sebagai konten yang tidak aman di semua dimensi. Pelajari Setelan keamanan lebih lanjut.

Berikut cara menetapkan satu setelan keamanan:

Kotlin

val generativeModel = GenerativeModel(
    modelName = "MODEL_NAME",
    apiKey = BuildConfig.apiKey,
    safetySettings = listOf(
        SafetySetting(HarmCategory.HARASSMENT, BlockThreshold.ONLY_HIGH)
    )
)

Java

SafetySetting harassmentSafety = new SafetySetting(HarmCategory.HARASSMENT,
    BlockThreshold.ONLY_HIGH);

GenerativeModel gm = new GenerativeModel(
    "MODEL_NAME",
    BuildConfig.apiKey,
    null, // generation config is optional
    Collections.singletonList(harassmentSafety)
);

GenerativeModelFutures model = GenerativeModelFutures.from(gm);

Anda juga dapat menetapkan lebih dari satu setelan keamanan:

Kotlin

val harassmentSafety = SafetySetting(HarmCategory.HARASSMENT, BlockThreshold.ONLY_HIGH)

val hateSpeechSafety = SafetySetting(HarmCategory.HATE_SPEECH, BlockThreshold.MEDIUM_AND_ABOVE)

val generativeModel = GenerativeModel(
    modelName = "MODEL_NAME",
    apiKey = BuildConfig.apiKey,
    safetySettings = listOf(harassmentSafety, hateSpeechSafety)
)

Java

SafetySetting harassmentSafety = new SafetySetting(HarmCategory.HARASSMENT,
    BlockThreshold.ONLY_HIGH);

SafetySetting hateSpeechSafety = new SafetySetting(HarmCategory.HATE_SPEECH,
    BlockThreshold.MEDIUM_AND_ABOVE);

GenerativeModel gm = new GenerativeModel(
    "MODEL_NAME",
    BuildConfig.apiKey,
    null, // generation config is optional
    Arrays.asList(harassmentSafety, hateSpeechSafety)
);

GenerativeModelFutures model = GenerativeModelFutures.from(gm);

Langkah selanjutnya

  • Desain prompt adalah proses pembuatan prompt yang mendapatkan respons yang diinginkan dari model bahasa. Menulis dialog yang terstruktur dengan baik adalah bagian penting untuk memastikan respons yang akurat dan berkualitas tinggi dari model bahasa. Pelajari praktik terbaik untuk penulisan perintah.

  • Gemini menawarkan beberapa variasi model untuk memenuhi kebutuhan berbagai kasus penggunaan, seperti jenis input dan kompleksitas, implementasi untuk chat atau tugas bahasa dialog lainnya, dan batasan ukuran. Pelajari model Gemini yang tersedia.

  • Gemini menawarkan opsi untuk meminta peningkatan batas kapasitas. Batas kapasitas untuk model Gemini Pro adalah 60 permintaan per menit (RPM).

  • SDK klien untuk Android yang dijelaskan dalam tutorial ini memungkinkan Anda mengakses model Gemini Pro yang berjalan di server Google. Untuk kasus penggunaan yang melibatkan pemrosesan data sensitif, ketersediaan offline, atau untuk menghemat biaya untuk alur penggunaan yang sering digunakan, Anda dapat mempertimbangkan untuk mengakses Gemini Nano yang berjalan di perangkat. Untuk mengetahui detail selengkapnya, lihat tutorial Android (di perangkat).