教程:函数调用

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

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

请参阅函数调用简介了解详情。

照明控制示例 API

假设您有一个带应用编程接口 (API) 的基本照明控制系统,并且您希望允许用户通过简单的文本请求来控制灯。您可以使用函数调用功能解释来自用户的光照更改请求,并将其转换为 API 调用以设置光照值。通过这个假设的照明控制系统,您可以控制光的亮度及其色温,通过两个单独的参数来定义:

参数 类型 必需 说明
brightness number 光级范围为 0 到 100。0 表示关闭,100 表示完整亮度。
colorTemperature string 灯具的色温,可以是 daylightcoolwarm

为简单起见,这个假想的照明系统只有一个灯,因此用户不必指定房间或位置。下面是一个 JSON 请求示例,您可以将其发送到 Light Control API,以使用日光色温将光级更改为 50%:

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

本教程介绍了如何为 Gemini API 设置函数调用,以解释用户的照明请求并将其映射到 API 设置,以控制灯的亮度和色温值。

准备工作:设置您的项目和 API 密钥

在调用 Gemini API 之前,您需要设置项目并配置 API 密钥。

定义 API 函数

创建一个发出 API 请求的函数。此函数应在应用的代码中定义,但可以在应用外部调用服务或 API。Gemini API 不会直接调用此函数,因此您可以通过应用代码控制此函数的执行方式和时间。为便于演示,本教程定义了一个模拟 API 函数,该函数仅返回请求的光照值:

func setLightValues(brightness: String,
                    colorTemp: String) -> JSONObject {
  // This mock API returns the requested lighting values
  return [
    "brightness": .string(brightness),
    "colorTemperature": .string(colorTemp)
  ]
}

创建函数声明

创建将传递给生成模型的函数声明。声明供模型使用的函数时,您应该在函数和参数说明中添加尽可能多的详细信息。生成模型使用这些信息来确定要选择的函数以及如何为函数调用中的参数提供值。以下代码展示了如何声明照明控制函数:

let controlLightFunctionDeclaration = FunctionDeclaration(
  name: "controlLight",
  description: "Set the brightness and color temperature of a room light.",
  parameters: [
    "brightness": Schema(
      type: .string,
      description: "Light level from 0 to 100. Zero is off and 100 is full brightness."
    ),
    "colorTemperature": Schema(
      type: .string,
      description: "Color temperature of the light fixture which can be `daylight`, `cool` or `warm`."
    ),
  ],
  requiredParameters: ["brightness", "colorTemperature"]
)

在模型初始化期间声明函数

如果要对模型使用函数调用,必须在初始化模型对象时提供函数声明。您可以通过设置模型的 tools 参数来声明函数:

// Use a model that supports function calling, like a Gemini 1.5 model
let generativeModel = GenerativeModel(
  name: "gemini-1.5-flash",
  apiKey: apiKey,
  // Specify the function declaration.
  tools: [Tool(functionDeclarations: [controlLightFunctionDeclaration])]
)

生成函数调用

使用函数声明初始化模型后,您可以使用定义的函数提示模型。您应该通过聊天提示 (sendMessage()) 使用函数调用,因为函数调用通常受益于先前提示和响应的上下文。

let chat = generativeModel.startChat()

let prompt = "Dim the lights so the room feels cozy and warm."

// Send the message to the generative model
let response1 = try await chat.sendMessage(prompt)

// Check if the model responded with a function call
guard let functionCall = response1.functionCalls.first else {
  fatalError("Model did not respond with a function call.")
}
// Print an error if the returned function was not declared
guard functionCall.name == "controlLight" else {
  fatalError("Unexpected function called: \(functionCall.name)")
}
// Verify that the names and types of the parameters match the declaration
guard case let .string(brightness) = functionCall.args["brightness"] else {
  fatalError("Missing argument: brightness")
}
guard case let .string(colorTemp) = functionCall.args["colorTemperature"] else {
  fatalError("Missing argument: colorTemperature")
}

// Call the hypothetical API
let apiResponse = setLightValues(brightness: brightness, colorTemperature: colorTemp)

// Send the API response back to the model so it can generate a text response that can be
// displayed to the user.
let response = try await chat.sendMessage([ModelContent(
  role: "function",
  parts: [.functionResponse(FunctionResponse(
    name: functionCall.name,
    response: apiResponse
  ))]
)])

// Log the text response.
guard let modelResponse = response.text else {
  fatalError("Model did not respond with text.")
}
print(modelResponse)