在 Dart 或 Flutter 應用程式中開始使用 Gemini API

本教學課程說明如何使用 Google AI Dart SDK 為 Dart 或 Flutter 應用程式存取 Gemini API。如果您不想直接與 REST API 搭配使用,以便在應用程式中存取 Gemini 模型,可以使用這個 SDK。

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

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

必要條件

本教學課程假設您已熟悉如何使用 Dart 建構應用程式。

如要完成本教學課程,請確保您的開發環境符合下列需求:

  • Dart 3.2.0 以上

設定專案

呼叫 Gemini API 之前,您需要先設定專案,包括設定 API 金鑰、將 SDK 新增至發布商依附元件,以及初始化模型。

設定 API 金鑰

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

取得 API 金鑰

保護 API 金鑰安全

妥善保管 API 金鑰。強烈建議您「不要」直接在程式碼中納入 API 金鑰,或在版本管控系統中檢查含有金鑰的檔案。請改用密鑰存放區做為 API 金鑰。

本教學課程中的所有程式碼片段均假設您存取 API 金鑰做為程序環境變數。如要開發 Flutter 應用程式,您可以使用 String.fromEnvironment 並將 --dart-define=API_KEY=$API_KEY 傳遞至 flutter buildflutter run,以使用 API 金鑰進行編譯,因為在執行應用程式時,程序環境將會不同。

安裝 SDK 套件

如要在自己的應用程式中使用 Gemini API,您必須將 google_generative_ai 套件 add 至 Dart 或 Flutter 應用程式:

飛鏢

dart pub add google_generative_ai

飄逸袖

flutter pub add google_generative_ai

初始化生成式模型

您必須先匯入並初始化生成式模型,才能進行任何 API 呼叫。

import 'package:google_generative_ai/google_generative_ai.dart';

// Access your API key as an environment variable (see "Set up your API key" above)
final apiKey = Platform.environment['API_KEY'];
if (apiKey == null) {
  print('No \$API_KEY environment variable');
  exit(1);
}

final model = GenerativeModel(model: 'MODEL_NAME', apiKey: apiKey);

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

  • 使用特定用途專屬的模型 (例如,gemini-pro-vision 適用於多模態輸入)。在本指南中,每個實作項目的操作說明都會列出每個用途的建議模型。

實作常見用途

現在專案已設定完成,您可以使用 Gemini API 來實作不同的使用案例:

您可以在進階用途區段中,查看 Gemini API 和嵌入的相關資訊。

根據純文字產生文字

如果提示輸入內容只包含文字,請使用 gemini-pro 模型與 generateContent 方法,產生文字輸出:

import 'dart:io';

import 'package:google_generative_ai/google_generative_ai.dart';

void main() async {
  // Access your API key as an environment variable (see "Set up your API key" above)
  final apiKey = Platform.environment['API_KEY'];
  if (apiKey == null) {
    print('No \$API_KEY environment variable');
    exit(1);
  }
  // For text-only input, use the gemini-pro model
  final model = GenerativeModel(model: 'gemini-pro', apiKey: apiKey);
  final content = [Content.text('Write a story about a magic backpack.')];
  final response = await model.generateContent(content);
  print(response.text);
}

依據文字和圖片輸入產生文字 (多模態)

Gemini 提供多模態模型 (gemini-pro-vision),因此您可以同時輸入文字和圖片。請務必詳閱輸入的圖片規定

如果提示輸入內容包含文字和圖片,請使用 gemini-pro-vision 模型搭配 generateContent 方法產生文字輸出:

import 'dart:io';

import 'package:google_generative_ai/google_generative_ai.dart';

void main() async {
  // Access your API key as an environment variable (see "Set up your API key" above)
  final apiKey = Platform.environment['API_KEY'];
  if (apiKey == null) {
    print('No \$API_KEY environment variable');
    exit(1);
  }
  // For text-and-image input (multimodal), use the gemini-pro-vision model
  final model = GenerativeModel(model: 'gemini-pro-vision', apiKey: apiKey);
  final (firstImage, secondImage) = await (
    File('image0.jpg').readAsBytes(),
    File('image1.jpg').readAsBytes()
  ).wait;
  final prompt = TextPart("What's different between these pictures?");
  final imageParts = [
    DataPart('image/jpeg', firstImage),
    DataPart('image/jpeg', secondImage),
  ];
  final response = await model.generateContent([
    Content.multi([prompt, ...imageParts])
  ]);
  print(response.text);
}

建立多輪對話 (即時通訊)

只要使用 Gemini,就能跨輪建立形式不限的對話。這個 SDK 可藉由管理對話狀態來簡化程序,因此與 generateContent 不同,您不必自行儲存對話記錄。

如要建構多輪對話 (例如即時通訊),請使用 gemini-pro 模型,並呼叫 startChat() 來初始化即時通訊。接著使用 sendMessage() 傳送新使用者訊息,這樣訊息和回應也會附加到即時通訊記錄中。

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

  • user:提供提示的角色。這是 sendMessage 呼叫的預設值,如果傳遞其他角色,函式會擲回例外狀況。

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

import 'dart:io';

import 'package:google_generative_ai/google_generative_ai.dart';

Future<void> main() async {
  // Access your API key as an environment variable (see "Set up your API key" above)
  final apiKey = Platform.environment['API_KEY'];
  if (apiKey == null) {
    print('No \$API_KEY environment variable');
    exit(1);
  }
  // For text-only input, use the gemini-pro model
  final model = GenerativeModel(
      model: 'gemini-pro',
      apiKey: apiKey,
      generationConfig: GenerationConfig(maxOutputTokens: 100));
  // Initialize the chat
  final chat = model.startChat(history: [
    Content.text('Hello, I have 2 dogs in my house.'),
    Content.model([TextPart('Great to meet you. What would you like to know?')])
  ]);
  var content = Content.text('How many paws are in my house?');
  var response = await chat.sendMessage(content);
  print(response.text);
}

使用串流功能享受更便捷的互動體驗

根據預設,模型會在完成整個產生程序後傳回回應。您不必等待整個結果,就能以串流方式處理部分結果,藉此加快互動速度。

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

// ...

final response = model.generateContentStream([
  Content.multi([prompt, ...imageParts])
]);
await for (final chunk in response) {
  print(chunk.text);
}

// ...

您可以透過類似的方法執行純文字輸入和即時通訊用途。

// Use streaming with text-only input
final response = model.generateContentStream(content);
// Use streaming with multi-turn conversations (like chat)
final response = chat.sendMessageStream(content);

實作進階用途

本教學課程前一節所述的常見用途,可協助您熟悉使用 Gemini API。本節說明部分可能更進階的用途。

函式呼叫

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

使用嵌入

「嵌入」是一種技術,用來在陣列中以浮點數清單表示資訊。使用 Gemini 時,您可以使用向量化格式來表示文字 (字詞、句子和文字區塊),更輕鬆地比較及對比嵌入。舉例來說,具有相同主題或情緒的兩個文字應有類似的嵌入,而您可以透過餘弦相似度等數學比較技巧加以識別。

搭配 embedContent 方法 (或 batchEmbedContent 方法) 使用 embedding-001 模型來產生嵌入。以下範例會產生單一字串的嵌入:

final model = GenerativeModel(model: 'embedding-001', apiKey: apiKey);
final content = Content.text('The quick brown fox jumps over the lazy dog.');
final result = await model.embedContent(content);
print(result.embedding.values);

計算符記

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

// For text-only input
final tokenCount = await model.countTokens(Content.text(prompt));
print('Token count: ${tokenCount.totalTokens}');
// For text-and-image input (multimodal)
final tokenCount = await model.countTokens([
  Content.multi([prompt, ...imageParts])
]);
print('Token count: ${tokenCount.totalTokens}');
// For multi-turn conversations (like chat)
final prompt = Content.text(message);
final allContent = [...chat.history, prompt];
final tokenCount = await model.countTokens(allContent);
print('Token count: ${tokenCount.totalTokens}');

控管內容產生功能的選項

您可以透過設定模型參數和安全設定來控制內容產生作業。

請注意,將 generationConfigsafetySettings 傳遞至模型要求方法 (例如 generateContent) 後,會在 getGenerativeModel 中傳遞相同的名稱,完全覆寫設定物件。

設定模型參數

您傳送至模型的每個提示都含有參數值,用來控制模型生成回覆的方式。模型可能會為不同參數值產生不同的結果。進一步瞭解模型參數。設定會在模型執行個體的生命週期內保留。

final generationConfig = GenerationConfig(
  stopSequences: ["red"],
  maxOutputTokens: 200,
  temperature: 0.9,
  topP: 0.1,
  topK: 16,
);
final model = GenerativeModel(
  model: 'MODEL_NAME',
  apiKey: apiKey,
  generationConfig: generationConfig,
);

使用安全性設定

您可以使用安全性設定,調整取得可能有害回應的機率。根據預設,安全設定會在所有維度中封鎖中度和/或極有可能為不安全的內容。進一步瞭解安全設定

以下說明如何設定一項安全性設定:

final safetySettings = [
  SafetySetting(HarmCategory.harassment, HarmBlockThreshold.high)
];
final model = GenerativeModel(
  model: 'MODEL_NAME',
  apiKey: apiKey,
  safetySettings: safetySettings,
);

您也可以設定多項安全性設定:

final safetySettings = [
  SafetySetting(HarmCategory.harassment, HarmBlockThreshold.high),
  SafetySetting(HarmCategory.hateSpeech, HarmBlockThreshold.high),
];

後續步驟

  • 提示設計是指建立提示,從語言模型中提取所需回應的程序。編寫結構周全的提示,是確保語言模型提供準確優質回覆的關鍵。瞭解提示撰寫的最佳做法

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

  • Gemini 提供要求提高頻率限制的選項。Genmini Pro 模型的頻率限制為每分鐘 60 次 (RPM)。