教學課程:開始使用 Gemini API


本教學課程示範如何使用 Android 版 Google AI 用戶端 SDK,直接從 Android 應用程式存取 Gemini API。如果您不想使用 REST API 或伺服器端程式碼 (例如 Python) 在 Android 應用程式中存取 Gemini 模型,您可以使用這個用戶端 SDK。

在本教學課程中,您將瞭解如何執行下列操作:

此外,本教學課程包含進階用途的相關章節 (例如計算符記),以及控管內容產生功能的選項。

建議在裝置上使用 Gemini

本教學課程所述的 Android 用戶端 SDK 可讓您存取 Google 伺服器執行的 Gemini Pro 模型。如果是需要處理機密資料、離線可用性,或針對常用使用者流程節省成本,建議您考慮存取在裝置端執行的 Gemini Nano。詳情請參閱 Android (裝置端) 教學課程

必要條件

本教學課程假設您已熟悉如何使用 Android Studio 開發 Android 應用程式。

如要完成本教學課程,請確認您的開發環境和 Android 應用程式符合下列規定:

  • Android Studio (最新版本)
  • 您的 Android 應用程式必須指定 API 級別 21 以上版本。

設定專案

呼叫 Gemini API 之前,您需要設定 Android 專案,包括設定 API 金鑰、將 SDK 依附元件加進 Android 專案,以及初始化模型。

設定 API 金鑰

如要使用 Gemini API,您必須具備 API 金鑰。如果您沒有金鑰 請在 Google AI Studio 中建立金鑰

取得 API 金鑰

確保 API 金鑰安全

強烈建議您「不要」在版本管控系統中登錄 API 金鑰。而是應該將 API 金鑰儲存在專案根目錄的 local.properties 檔案中 (位於專案根目錄中,但不在版本管控中),然後使用 Secrets Gradle 外掛程式 Android 版將 API 金鑰讀取為建構設定變數。

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;

本教學課程中的所有程式碼片段都採用這項最佳做法。此外,如要查看 Secrets Gradle 外掛程式的實作內容,請查看這個 SDK 的範例應用程式,或使用最新預先發布版的 Android Studio Iguana,其具有 Gemini API Starter 範本 (內含 local.properties 檔案,可協助您快速上手)。

在專案中新增 SDK 依附元件

  1. 模組 (應用程式層級) Gradle 設定檔 (例如 <project>/<app-module>/build.gradle.kts) 中新增 Google AI SDK for 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.9.0")
    }
    

    Java

    針對 Java,您必須額外新增兩個程式庫。

    dependencies {
        // ... other androidx dependencies
    
        // add the dependency for the Google AI client SDK for Android
        implementation("com.google.ai.client.generativeai:generativeai:0.9.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. 將 Android 專案與 Gradle 檔案同步處理。

初始化生成式模型

您必須先初始化生成式模型,才能發出 API 呼叫:

Kotlin

val generativeModel = GenerativeModel(
    // The Gemini 1.5 models are versatile and work with most use cases
    modelName = "gemini-1.5-flash",
    // Access your API key as a Build Configuration variable (see "Set up your API key" above)
    apiKey = BuildConfig.apiKey
)

Java

如果是 Java,您也需要初始化 GenerativeModelFutures 物件。

// Use a model that's applicable for your use case
// The Gemini 1.5 models are versatile and work with most use cases
GenerativeModel gm = new GenerativeModel(/* modelName */ "gemini-1.5-flash",
// 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);

指定模型時,請注意下列事項:

  • 使用您用途專屬的模型 (例如,gemini-1.5-flash 適用於多模態輸入)。在本指南中,各實作方法的操作說明會列出每種用途的建議模型。

實作常見用途

專案設定完成後,您就可以瞭解如何使用 Gemini API 實作不同的用途:

從純文字輸入來生成文字

如果提示內容只包含文字,請使用 Gemini 1.5 模型或搭載 generateContent 的 Gemini 1.0 Pro 模型,生成文字輸出:

Kotlin

請注意,generateContent() 是暫停函式,需要從協同程式範圍呼叫。如果您不熟悉協同程式,請參閱「Android 上的 Kotlin 協同程式」。

val generativeModel = GenerativeModel(
    // The Gemini 1.5 models are versatile and work with both text-only and multimodal prompts
    modelName = "gemini-1.5-flash",
    // 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

請注意,generateContent() 會傳回 ListenableFuture。如果您不熟悉這個 API,請參閱有關使用 ListenableFuture 的 Android 說明文件。

// The Gemini 1.5 models are versatile and work with both text-only and multimodal prompts
GenerativeModel gm = new GenerativeModel(/* modelName */ "gemini-1.5-flash",
// 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);

根據文字和圖片輸入內容產生文字 (多模態)

Gemini 提供多種可處理多模態輸入的模型 (Gemini 1.5 模型),方便您輸入文字和圖片。請務必查看提示的圖片規定

如果提示輸入內容包含文字和圖片,請使用搭載 generateContent 的 Gemini 1.5 模型來產生文字:

Kotlin

請注意,generateContent() 是暫停函式,需要從協同程式範圍呼叫。如果您不熟悉協同程式,請參閱「Android 上的 Kotlin 協同程式」。

val generativeModel = GenerativeModel(
    // The Gemini 1.5 models are versatile and work with both text-only and multimodal prompts
    modelName = "gemini-1.5-flash",
    // 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

請注意,generateContent() 會傳回 ListenableFuture。如果您不熟悉這個 API,請參閱有關使用 ListenableFuture 的 Android 說明文件。

// The Gemini 1.5 models are versatile and work with both text-only and multimodal prompts
GenerativeModel gm = new GenerativeModel(/* modelName */ "gemini-1.5-flash",
// 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);

打造多輪對話 (聊天)

使用 Gemini 即可多回合,建立任意形式的對話。SDK 會透過管理對話狀態來簡化程序,因此與 generateContent 不同,您不需要自行儲存對話記錄。

如要建構多輪對話 (例如對話),請使用 Gemini 1.5 模型或 Gemini 1.0 Pro 模型,然後呼叫 startChat() 初始化對話。接著使用 sendMessage() 傳送新的使用者訊息,這個訊息也會將訊息和回應附加到即時通訊記錄中。

與對話中的內容相關的 role 有兩種可能的選項:

  • user:提供提示的角色。這個值是 sendMessage 呼叫的預設值。

  • model:提供回應的角色。透過現有的 history 呼叫 startChat() 時,您可以使用這個角色。

Kotlin

請注意,generateContent() 是暫停函式,需要從協同程式範圍呼叫。如果您不熟悉協同程式,請參閱「Android 上的 Kotlin 協同程式」。

val generativeModel = GenerativeModel(
    // The Gemini 1.5 models are versatile and work with multi-turn conversations (like chat)
    modelName = "gemini-1.5-flash",
    // 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

請注意,generateContent() 會傳回 ListenableFuture。如果您不熟悉這個 API,請參閱有關使用 ListenableFuture 的 Android 說明文件。

// The Gemini 1.5 models are versatile and work with multi-turn conversations (like chat)
GenerativeModel gm = new GenerativeModel(/* modelName */ "gemini-1.5-flash",
// 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.Builder userMessageBuilder = new Content.Builder();
userMessageBuilder.setRole("user");
userMessageBuilder.addText("How many paws are in my house?");
Content userMessage = userMessageBuilder.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);

使用串流加快互動速度

根據預設,模型會在完成整個產生程序後傳回回應。您不必等待整個結果,就能實現更快速的互動,並改用串流處理部分結果。

以下範例說明如何使用 generateContentStream 實作串流,根據文字和圖片輸入提示產生文字。

Kotlin

請注意,generateContentStream() 是暫停函式,需要從協同程式範圍呼叫。如果您不熟悉協同程式,請參閱「Android 上的 Kotlin 協同程式」。

val generativeModel = GenerativeModel(
    // The Gemini 1.5 models are versatile and work with both text-only and multimodal prompts
    modelName = "gemini-1.5-flash",
    // 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

這個 SDK 中的 Java 串流方法會從 Reactive Streams 程式庫傳回 Publisher 類型。

// The Gemini 1.5 models are versatile and work with both text-only and multimodal prompts
GenerativeModel gm = new GenerativeModel(/* modelName */ "gemini-1.5-flash",
// 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);

StringBuilder outputContent = new StringBuilder();

streamingResponse.subscribe(new Subscriber<GenerateContentResponse>() {
    @Override
    public void onNext(GenerateContentResponse generateContentResponse) {
        String chunk = generateContentResponse.getText();
        outputContent.append(chunk);
    }

    @Override
    public void onComplete() {
        System.out.println(outputContent);
    }

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

    @Override
    public void onSubscribe(Subscription s) {
      s.request(Long.MAX_VALUE);
    }
});

在純文字輸入和聊天用途上,您也可以採取類似的做法:

Kotlin

請注意,generateContentStream() 是暫停函式,需要從協同程式範圍呼叫。如果您不熟悉協同程式,請參閱「Android 上的 Kotlin 協同程式」。

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

這個 SDK 中的 Java 串流方法會從 Reactive Streams 程式庫傳回 Publisher 類型。

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

StringBuilder outputContent = new StringBuilder();

streamingResponse.subscribe(new Subscriber<GenerateContentResponse>() {
    @Override
    public void onNext(GenerateContentResponse generateContentResponse) {
        String chunk = generateContentResponse.getText();
        outputContent.append(chunk);
    }

    @Override
    public void onComplete() {
        System.out.println(outputContent);
    }

    @Override
    public void onSubscribe(Subscription s) {
      s.request(Long.MAX_VALUE);
    }

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

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

StringBuilder outputContent = new StringBuilder();

streamingResponse.subscribe(new Subscriber<GenerateContentResponse>() {
    @Override
    public void onNext(GenerateContentResponse generateContentResponse) {
        String chunk = generateContentResponse.getText();
        outputContent.append(chunk);
    }

    @Override
    public void onComplete() {
        System.out.println(outputContent);
    }

    @Override
    public void onSubscribe(Subscription s) {
      s.request(Long.MAX_VALUE);
    }

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

實作進階用途

本教學課程前一節所述的常見用途,可協助您熟悉 Gemini API 的使用方式。本節說明一些較進階的用途。

函式呼叫

函式呼叫可讓您輕鬆從生成式模型取得結構化資料輸出內容。接著,您可以使用這些輸出內容呼叫其他 API,並將相關的回應資料傳回模型。換句話說,函式呼叫可協助您將生成式模型連結至外部系統,讓產生的內容包含最新且準確的資訊。詳情請參閱函式呼叫教學課程

計算符記數量

使用長提示時,建議先計算符記再傳送任何內容至模型。下列範例說明如何將 countTokens() 用於各種用途:

Kotlin

請注意,countTokens() 是暫停函式,需要從協同程式範圍呼叫。如果您不熟悉協同程式,請參閱「Android 上的 Kotlin 協同程式」。

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

請注意,countTokens() 會傳回 ListenableFuture。如果您不熟悉這個 API,請參閱有關使用 ListenableFuture 的 Android 說明文件。

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

控管內容生成功能的選項

您可以設定模型參數及使用安全設定,控管內容產生作業。

設定模型參數

您傳送至模型的每個提示都含有參數值,用來控制模型生成回覆的方式。模型可能會針對不同的參數值產生不同的結果。進一步瞭解模型參數

Kotlin

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

val generativeModel = GenerativeModel(
    // The Gemini 1.5 models are versatile and work with most use cases
    modelName = "gemini-1.5-flash",
    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();

// The Gemini 1.5 models are versatile and work with most use cases
GenerativeModel gm = new GenerativeModel(
    "gemini-1.5-flash",
    BuildConfig.apiKey,
    generationConfig
);

GenerativeModelFutures model = GenerativeModelFutures.from(gm);

使用安全性設定

您可以使用安全性設定,調整收到可能視為有害回應的機率。根據預設,安全性設定會封鎖中等和/或很有可能為不安全的內容。進一步瞭解安全性設定

以下說明如何進行各項安全性設定:

Kotlin

val generativeModel = GenerativeModel(
    // The Gemini 1.5 models are versatile and work with most use cases
    modelName = "gemini-1.5-flash",
    apiKey = BuildConfig.apiKey,
    safetySettings = listOf(
        SafetySetting(HarmCategory.HARASSMENT, BlockThreshold.ONLY_HIGH)
    )
)

Java

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

// The Gemini 1.5 models are versatile and work with most use cases
GenerativeModel gm = new GenerativeModel(
    "gemini-1.5-flash",
    BuildConfig.apiKey,
    null, // generation config is optional
    Collections.singletonList(harassmentSafety)
);

GenerativeModelFutures model = GenerativeModelFutures.from(gm);

你也可以設置多項安全性設定:

Kotlin

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

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

val generativeModel = GenerativeModel(
    // The Gemini 1.5 models are versatile and work with most use cases
    modelName = "gemini-1.5-flash",
    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);

// The Gemini 1.5 models are versatile and work with most use cases
GenerativeModel gm = new GenerativeModel(
    "gemini-1.5-flash",
    BuildConfig.apiKey,
    null, // generation config is optional
    Arrays.asList(harassmentSafety, hateSpeechSafety)
);

GenerativeModelFutures model = GenerativeModelFutures.from(gm);

後續步驟

  • 「提示設計」是指建立提示的程序,會從語言模型中取得所需回應。想確保語言模型提供準確且高品質的回覆,就必須撰寫條理分明的提示。瞭解撰寫提示的最佳做法

  • Gemini 提供多種不同模型版本,可滿足不同用途的需求,例如輸入類型和複雜度、對話或其他對話方塊語言工作的實作方式,以及大小限制。瞭解可用的 Gemini 模型

  • 本教學課程所述的 Android 用戶端 SDK 可讓您存取 Google 伺服器執行的 Gemini Pro 模型。如果是需要處理機密資料、離線可用性,或針對常用使用者流程節省成本,建議您考慮存取在裝置端執行的 Gemini Nano。詳情請參閱 Android (裝置端) 教學課程