教程:使用 Gemini API 进行函数调用


借助函数调用,您可以更轻松地从生成模型中获取结构化数据输出。然后,您可以使用这些输出调用其他 API,并将相关响应数据返回给模型。换言之,函数调用可帮助您将生成模型连接到外部系统,以使生成的内容包含最新且准确的信息。

您可以为 Gemini 模型提供函数说明。这些函数是使用应用的语言编写的(即,它们不是 Google Cloud Functions)。模型可能会要求您调用一个函数并发回结果,以帮助模型处理您的查询。

请参阅函数调用简介了解详情(如果您尚未这样做)。

设置项目

在调用 Gemini API 之前,您需要设置项目,包括设置 API 密钥、将 SDK 添加到 Pub/Sub 依赖项,以及初始化模型。

设置函数调用

在本教程中,您将让模型与支持以下参数的假设货币交易所 API 进行交互:

参数 类型 必需 说明
currencyDate 字符串 获取
汇率的日期(必须始终采用 YYYY-MM-DD 格式,如果未指定时间段,则采用值 latest
currencyFrom string 要换算的币种
currencyTo string 要换算成的币种

API 请求示例

{
  "currencyDate": "2024-04-17",
  "currencyFrom": "USD",
  "currencyTo": "SEK"
}

API 响应示例

{
  "base": "USD",
  "date": "2024-04-17",
  "rates": {"SEK": 0.091}
}

第 1 步:创建用于发出 API 请求的函数

如果尚未创建用于发出 API 请求的函数,请先创建。

在本教程中出于演示目的,您不会发送实际 API 请求,而是以与实际 API 返回的格式相同的格式返回硬编码值。

Future<Map<String, Object?>> findExchangeRate(
  Map<String, Object?> arguments,
) async =>
    // This hypothetical API returns a JSON such as:
    // {"base":"USD","date":"2024-04-17","rates":{"SEK": 0.091}}
    {
      'date': arguments['currencyDate'],
      'base': arguments['currencyFrom'],
      'rates': <String, Object?>{arguments['currencyTo'] as String: 0.091}
    };

第 2 步:创建函数声明

创建要传递给生成模型的函数声明(本教程的下一步)。

在函数和参数说明中添加尽可能多的详细信息。 生成模型使用这些信息来确定选择哪个函数,以及如何为函数调用中的形参提供值。

final exchangeRateTool = FunctionDeclaration(
    'findExchangeRate',
    'Returns the exchange rate between currencies on given date.',
    Schema(SchemaType.object, properties: {
      'currencyDate': Schema(SchemaType.string,
          description: 'A date in YYYY-MM-DD format or '
              'the exact value "latest" if a time period is not specified.'),
      'currencyFrom': Schema(SchemaType.string,
          description: 'The currency code of the currency to convert from, '
              'such as "USD".'),
      'currencyTo': Schema(SchemaType.string,
          description: 'The currency code of the currency to convert to, '
              'such as "USD".')
    }, requiredProperties: [
      'currencyDate',
      'currencyFrom'
    ]));

第 3 步:在模型初始化期间指定函数声明

在初始化生成模型时,通过将函数声明传递到模型的 tools 参数来指定函数声明:

final model = GenerativeModel(
  // Use a model that supports function calling, like a Gemini 1.5 model
  model: 'gemini-1.5-flash',
  apiKey: apiKey,

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

第 4 步:生成函数调用

现在,您可以使用定义的函数向模型发出提示。

建议使用聊天界面使用函数调用,因为函数调用非常适合聊天的多轮结构。

final chat = model.startChat();
final prompt = 'How much is 50 US dollars worth in Swedish krona?';

// 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.
    'findExchangeRate' => await findExchangeRate(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);
}