
在 2024/02/21,Flutter Team 釋出了 Google Generative AI 這個 SDK,這個 SDK 大幅簡化了 Google Gemini API 呼叫的過程。讓 Flutter 或 Dart 開發者,只要在幾行的程式碼內,就能完成 Google Gemini API 的實作;這我們只要專注在 Flutter 的開發即可。
不囉嗦!我們直接來看怎麼使用!
在導入 Gemini API SDK 後,讓我們可以用這短短的幾行程式碼,便能獲得 Gemini API 的結果。
我們先來疏理一下需要準備的步驟
- 取得 API Key
- Flutter 專案設定 SDK
- 自由開發~
1. 取得 API Key
1.1 Google AI Studio
首先,我們需要到
Google AI Studio 取得 API Key,
如下圖,進到 Google Ai Studio 平臺中的 Get Api Key
頁面,可以看到
Create API Key
的按鈕

1.2 Create API Key
選擇我們 Google Cloud 上的 projects,再點擊下方的
Create API key in existing project

等待一下,就能看到如下圖一樣,可以被複製的 API Key

如果還沒有 Google Cloud 的專案,請先到 Google Cloud Console 建立專案後,再回到 Google AI Studio 這邊來操作。
2. 在 Flutter 中加入 SDK
在 Flutter 的套件庫 (pub.dev) 中,其實存在了不少實作 Gemini API 的整合套件,我們這邊要使用 Google 出品的 google_generative_ai。

只要按平常各位習慣加入套件的方式去操作即可。比方說
flutter pub add google_generative_ai
3. 開發 Flutter APP
這樣便能開始自由開發的環節啦!
如果你目前還沒想好要做什麼,但也想嘗試玩看看,那你可以先從我這邊為大家準備好的程式碼繼續往下看。
3.1 取得程式碼
請先到
Github:flutter-google-gemini-api
(https://github.com/mosil/flutter-google-gemini-api)
取得本篇接下來要實作的程式碼。
裡面有三個分支,從預設的
main
分支執行起來會像是下方這樣的畫面:

3.2 加入 google_generative_ai
main 分支在順利執行後,僅有如上方的畫面截圖,以及操作文字送出到畫面上所需要用到的應程式碼,而套件尚未加入。如之前提到,大家可以使用自己習慣的方式,將 SDK — google_generative_ai 加入專案中。比方說,
flutter pub add google_generative_ai
加入後,可以在
pubspec.yaml
的
dependencies
中看到如下圖最末行的
google_generative_ai: ^0.2.2

3.3 放入 API Key
在
lib/core/constants.dart
程式碼中有兩個變數,
- apiKey:從 AI Studio 取得的 API Key。
-
aiModel:這邊放入要使用的模型版本,像是
gemini-pro
或是gemini-1.0-pro
從上方的程式碼片段能看到
aiModel
這個變數,我們可以填入
model name
或是
model code
;後者看起來像是個路徑的片段,那是因為,當今天我們沒有透過 SDK
來開發時,它的確是一段如下圖紅框圈起來的地方,是路徑的其中一部份,

這時
models/
這段就是必要路徑,而 SDK 中很貼心地,幫我們補上
models/
這個前輟,

讓我們得以單純放入
modelName
,同時也能保留能放入完整的
modelCode
的彈性。
3.4 開始加入 SDK 程式碼嘍
這邊請各位開啟
lib/ui/chat_page.dart
找到
_send
函式中的
// TODO: Add Gemini API Code
3.4.1 呼叫 Gemini API
在這邊加入我們在上面提到過的 SDK 的程式碼
// 宣告生成物件
final GenerativeModel model = GenerativeModel(
apiKey: apiKey,
model: aiModel,
);
// 將輸入的文字,放入代表 mutli-part Content 的物件中
final List<Content> contents = [Content.text(text)];
// 呼叫 API
final GenerateContentResponse response = await model.generateContent(contents);
基本上就是這樣短短的幾行就能輕鬆完成呼叫 Gemin API 的實作。
3.4.2 將收到的回應,放入聊天畫面中
chat_page
在是這邊定義為
StatefulWidget
,所以我們就用
setStaet()
來觸發畫面更新
setState(() {
MessageModel feedback = MessageModel(
type: MessageType.feedback,
text: response.text ?? "",
);
messages.add(feedback);
_scrollDown();
_inputController.text = "";
isLoading = false;
});
基本上,我們寫到這邊,一個可以執行的聊天機器人已經完成了。各位可以將程式碼的分支切換
1-gemini-api
去對照看看。
不過,隨著自己持續在發送訊息出去,我們有機會發現它…
卡住了!
4. 處理例外狀況
為什麼會卡住呢?我們來看看 SDK 的原始碼

在紅框起來的程式碼中,我們能看到可以被解析出來的
response
才會被回傳,倘若解析錯誤,而它會走向
FormatException
的錯誤中。接著我們來看看裡面的錯誤格式原始碼

當 Gemini API 有錯誤時,這邊用了
GenerativeAIException
做為其承接物件,裡面的錯誤訊息會被放在
message
這個物件成員中。
因此,我們接下來要完善這段處理,避免當 Gemini API 給我們錯誤訊息時,我們只能被卡住的窘境。
final GenerativeModel model = GenerativeModel(
apiKey: apiKey,
model: aiModel,
);
final List<content> contents = [Content.text(text)];
try {
final GenerateContentResponse response = await model.generateContent(contents);
// Success: show correct text to message list in chat.
setState(() {
MessageModel feedback = MessageModel(
type: MessageType.feedback,
text: response.text ?? "",
);
messages.add(feedback);
_scrollDown();
});
} on GenerativeAIException catch (e) {
// Error: show dialog.
setState(() {
// 這邊即是在處理當獲得錯誤時,將錯誤訊息 [e.message] 以跳窗呈現
_showError(context: context, error: e.message);
});
} finally {
// 無論結果正確或是錯誤,都要清空輸入框以及關掉 loading 的畫面
setState(() {
_inputController.text = "";
isLoading = false;
});
}
將這段補完後,我們就算是將當前要處理的功能都弄好了!
最後完整的程式碼,請將分支切到
2-gemini-api-complated
對照看看。
以下是完成影片
以上內容如果有錯誤,歡迎各位留言告知!
留言
張貼留言