借助函数调用,您可以更轻松地从生成模型中获取结构化数据输出。然后,您可以使用这些输出调用其他 API,并将相关响应数据返回给模型。换言之,函数调用可帮助您将生成模型连接到外部系统,以使生成的内容包含最新且准确的信息。
您可以为 Gemini 模型提供函数说明。这些函数是使用应用的语言编写的(即,它们不是 Google Cloud Functions)。模型可能会要求您调用一个函数并发回结果,以帮助模型处理您的查询。
请参阅函数调用简介了解详情(如果您尚未这样做)。
设置项目
在调用 Gemini API 之前,您需要设置 Android 项目,其中包括设置 API 密钥、将 SDK 依赖项添加到 Android 项目,以及初始化模型。
设置函数调用
在本教程中,您将让模型与支持以下参数的假设货币交易所 API 进行交互:
参数 | 类型 | 必需 | 说明 |
---|---|---|---|
currencyFrom |
string | 是 | 要换算的币种 |
currencyTo |
string | 是 | 要换算成的币种 |
API 请求示例
{
"currencyFrom": "USD",
"currencyTo": "SEK"
}
API 响应示例
{
"base": "USD",
"rates": {"SEK": 0.091}
}
第 1 步:创建用于发出 API 请求的函数
如果尚未创建用于发出 API 请求的函数,请先创建。
在本教程中出于演示目的,您不会发送实际 API 请求,而是以与实际 API 返回的格式相同的格式返回硬编码值。
suspend fun makeApiRequest(
currencyFrom: String,
currencyTo: String
): JSONObject {
// This hypothetical API returns a JSON such as:
// {"base":"USD","rates":{"SEK": 0.091}}
return JSONObject().apply {
put("base", currencyFrom)
put("rates", hashMapOf(currencyTo to 0.091))
}
}
第 2 步:创建函数声明
创建要传递给生成模型的函数声明(本教程的下一步)。
在函数和参数说明中添加尽可能多的详细信息。 生成模型使用这些信息来确定选择哪个函数,以及如何为函数调用中的形参提供值。
val getExchangeRate = defineFunction(
name = "getExchangeRate",
description = "Get the exchange rate for currencies between countries",
Schema.str("currencyFrom", "The currency to convert from."),
Schema.str("currencyTo", "The currency to convert to.")
) { from, to ->
// Call the function that you declared above
makeApiRequest(from, to)
}
第 3 步:在模型初始化期间指定函数声明
在初始化生成模型时,通过将函数声明传递到模型的 tools
参数来指定函数声明:
val generativeModel = GenerativeModel(
// Use a model that supports function calling, like a Gemini 1.5 model
modelName = "gemini-1.5-flash",
// Access your API key as a Build Configuration variable (see "Set up your API key" above)
apiKey = BuildConfig.apiKey,
// Specify the function declaration.
tools = listOf(Tool(listOf(getExchangeRate)))
)
第 4 步:生成函数调用
现在,您可以使用定义的函数向模型发出提示。
建议使用聊天界面使用函数调用,因为函数调用非常适合聊天的多轮结构。
val chat = generativeModel.startChat()
val prompt = "How much is 50 US dollars worth in Swedish krona?"
// Send the message to the generative model
var response = chat.sendMessage(prompt)
// Check if the model responded with a function call
response.functionCall?.let { functionCall ->
// Try to retrieve the stored lambda from the model's tools and
// throw an exception if the returned function was not declared
val matchedFunction = generativeModel.tools?.flatMap { it.functionDeclarations }
?.first { it.name == functionCall.name }
?: throw InvalidStateException("Function not found: ${functionCall.name}")
// Call the lambda retrieved above
val apiResponse: JSONObject = matchedFunction.execute(functionCall)
// Send the API response back to the generative model
// so that it generates a text response that can be displayed to the user
response = chat.sendMessage(
content(role = "function") {
part(FunctionResponsePart(functionCall.name, apiResponse))
}
)
}
// Whenever the model responds with text, show it in the UI
response.text?.let { modelResponse ->
println(modelResponse)
}