函式呼叫教學課程

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

您可以為 Gemini 模型提供函式說明。這些函式是使用應用程式語言編寫的函式 (也就是說,它們不是 Google Cloud Functions)。模型可能會要求您呼叫函式並傳回結果,以便模型處理您的查詢。

如果您還不熟悉,請參閱函式呼叫簡介瞭解詳情。

假設您有一個基本照明控制系統,其中包含應用程式設計介面 (API),且您希望允許使用者透過簡單的文字要求控制燈光。您可以使用函式呼叫功能,解讀使用者提出的燈光變更要求,並將這些要求轉譯為 API 呼叫,以便設定燈光值。這個假設的照明控制系統可讓您控制燈光的亮度和色溫,這兩者分別定義為兩個獨立的參數:

參數 類型 必要 說明
brightness 數字 光線強度從 0 到 100。0 代表關閉,100 代表全亮度。
colorTemperature 字串 燈具的色溫,可以是 daylightcoolwarm

為了簡化說明,這個假想的照明系統只有一盞燈,因此使用者不必指定房間或位置。以下是 JSON 要求範例,您可以將其傳送至照明控制 API,藉此使用日光色溫將光線亮度變更為 50%:

{
  "brightness": "50",
  "colorTemperature": "daylight"
}

本教學課程將說明如何為 Gemini API 設定函式呼叫,以便解讀使用者的照明要求,並將這些要求對應至 API 設定,以便控制燈光的亮度和色溫值。

事前準備:設定專案和 API 金鑰

在呼叫 Gemini API 之前,您需要設定專案並設定 API 金鑰。

取得並保護 API 金鑰

您需要 API 金鑰才能呼叫 Gemini API。如果還沒有金鑰,請在 Google AI Studio 建立。

取得 API 金鑰

強烈建議您不要將 API 金鑰登錄到版本管控系統。

您應將 API 金鑰儲存在 Google Cloud Secret Manager 等 Secret 儲存庫中。

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

匯入 SDK 套件並設定 API 金鑰

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

dart pub add google_generative_ai
flutter pub add google_generative_ai

定義 API 函式

建立可提出 API 要求的函式。這個函式應定義在應用程式的程式碼中,但可以呼叫應用程式以外的服務或 API。Gemini API 不會直接呼叫這個函式,因此您可以透過應用程式程式碼控制這個函式的執行方式和時機。為了示範,本教學課程會定義模擬 API 函式,只傳回要求的照明值:

Future<Map<String, Object?>> setLightValues(
  Map<String, Object?> arguments,
) async =>
    // This mock API returns the requested lighting values
    {
      'brightness': arguments['brightness'],
      'colorTemperature': arguments['colorTemp'],
    };

建立函式宣告

建立要傳遞至生成式模型的函式宣告。宣告模型可使用的函式時,請盡可能在函式和參數說明中加入詳細資料。生成式模型會使用這項資訊,判斷要選取哪個函式,以及如何在函式呼叫中提供參數的值。以下程式碼顯示如何宣告照明控制函式:

final lightControlTool = FunctionDeclaration(
    'setLightValues',
    'Set the brightness and color temperature of a room light.',
    Schema(SchemaType.object, properties: {
      'brightness': Schema(SchemaType.number,
          description: 'Light level from 0 to 100. '
              'Zero is off and 100 is full brightness.'),
      'colorTemperature': Schema(SchemaType.string,
          description: 'Color temperature of the light fixture, '
              'which can be `daylight`, `cool` or `warm`.'),
    }, requiredProperties: [
      'brightness',
      'colorTemperature'
    ]));

在模型初始化期間宣告函式

如要使用函式呼叫功能,您必須在初始化模型物件時提供函式宣告。您可以透過設定模型的 tools 參數來宣告函式。Dart SDK 也支援將函式宣告為 generateContentgenerateContentStream API 的引數。

final model = GenerativeModel(
  model: 'gemini-1.5-flash',
  apiKey: apiKey,

  // Specify the function declaration.
  tools: [
    Tool(functionDeclarations: [lightControlTool])
  ],
);

產生函式呼叫

使用函式宣告初始化模型後,您可以使用定義的函式提示模型。您應使用聊天提示 (sendMessage()) 進行函式呼叫,因為函式呼叫通常會受益於先前提示和回應的內容。

final chat = model.startChat(); final prompt =
  'Dim the lights so the room feels cozy and warm.';

// Send the message to the generative model.
var response = await chat.sendMessage(Content.text(prompt));

final functionCalls = response.functionCalls.toList();
// When the model response with a function call, invoke the function.
if (functionCalls.isNotEmpty) {
  final functionCall = functionCalls.first;
  final result = switch (functionCall.name) {
    // Forward arguments to the hypothetical API.
    'setLightValues' => await setLightValues(functionCall.args),
    // Throw an exception if the model attempted to call a function that was
    // not declared.
    _ => throw UnimplementedError(
        'Function not implemented: ${functionCall.name}')
  };
  // Send the response to the model so that it can use the result to generate
  // text for the user.
  response = await chat
      .sendMessage(Content.functionResponse(functionCall.name, result));
}
// When the model responds with non-null text content, print it.
if (response.text case final text?) {
  print(text);
}