借助函数调用,您可以更轻松地从生成模型中获取结构化数据输出。然后,您可以使用这些输出调用其他 API,并将相关响应数据返回给模型。换言之,函数调用可帮助您将生成模型连接到外部系统,以使生成的内容包含最新且准确的信息。
您可以为 Gemini 模型提供函数说明。这些函数是使用应用的语言编写的(即,它们不是 Google Cloud Functions)。模型可能会要求您调用一个函数并发回结果,以帮助模型处理您的查询。
请参阅函数调用简介了解详情(如果您尚未这样做)。
设置项目
在调用 Gemini API 之前,您需要设置 Xcode 项目,其中包括设置 API 密钥、将 SDK 软件包添加到 Xcode 项目以及初始化模型。
设置函数调用
在本教程中,您将让模型与支持以下参数的假设货币交易所 API 进行交互:
参数 | 类型 | 必需 | 说明 |
---|---|---|---|
currencyFrom |
string | 是 | 要换算的币种 |
currencyTo |
string | 是 | 要换算成的币种 |
API 请求示例
{
"currencyFrom": "USD",
"currencyTo": "SEK"
}
API 响应示例
{
"base": "USD",
"rates": {"SEK": 0.091}
}
第 1 步:创建用于发出 API 请求的函数
如果尚未创建用于发出 API 请求的函数,请先创建。
在本教程中出于演示目的,您不会发送实际 API 请求,而是以与实际 API 返回的格式相同的格式返回硬编码值。
func makeAPIRequest(currencyFrom: String,
currencyTo: String) -> JSONObject {
// This hypothetical API returns a JSON such as:
// {"base":"USD","rates":{"SEK": 0.091}}
return [
"base": .string(currencyFrom),
"rates": .object([currencyTo: .number(0.091)]),
]
}
第 2 步:创建函数声明
创建要传递给生成模型的函数声明(本教程的下一步)。
在函数和参数说明中添加尽可能多的详细信息。 生成模型使用这些信息来确定选择哪个函数,以及如何为函数调用中的形参提供值。
let getExchangeRate = FunctionDeclaration(
name: "getExchangeRate",
description: "Get the exchange rate for currencies between countries",
parameters: [
"currencyFrom": Schema(
type: .string,
description: "The currency to convert from."
),
"currencyTo": Schema(
type: .string,
description: "The currency to convert to."
),
],
requiredParameters: ["currencyFrom", "currencyTo"]
)
第 3 步:在模型初始化期间指定函数声明
在初始化生成模型时,通过设置模型的 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: [getExchangeRate])]
)
第 4 步:生成函数调用
现在,您可以使用定义的函数向模型发出提示。
建议使用聊天界面使用函数调用,因为函数调用非常适合聊天的多轮结构。
let chat = generativeModel.startChat()
let prompt = "How much is 50 US dollars worth in Swedish krona?"
// 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 == "getExchangeRate" else {
fatalError("Unexpected function called: \(functionCall.name)")
}
// Verify that the names and types of the parameters match the declaration
guard case let .string(currencyFrom) = functionCall.args["currencyFrom"] else {
fatalError("Missing argument: currencyFrom")
}
guard case let .string(currencyTo) = functionCall.args["currencyTo"] else {
fatalError("Missing argument: currencyTo")
}
// Call the hypothetical API
let apiResponse = makeAPIRequest(currencyFrom: currencyFrom, currencyTo: currencyTo)
// 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)