Function calling makes it easier for you to get structured data outputs from generative models. You can then use these outputs to call other APIs and return the relevant response data to the model. In other words, function calling helps you connect generative models to external systems so that the generated content includes the most up-to-date and accurate information.
You can provide Gemini models with descriptions of functions. These are functions that you write in the language of your app (that is, they're not Google Cloud Functions). The model may ask you to call a function and send back the result to help the model handle your query.
If you haven't already, check out the Introduction to function calling to learn more.
Example API for lighting control
Imagine you have a basic lighting control system with an application programming interface (API) and you want to allow users to control the lights through simple text requests. You can use the Function Calling feature to interpret lighting change requests from users and translate them into API calls to set the lighting values. This hypothetical lighting control system lets you control the brightness of the light and it's color temperature, defined as two separate parameters:
Parameter | Type | Required | Description |
---|---|---|---|
brightness |
number | yes | Light level from 0 to 100. Zero is off and 100 is full brightness. |
colorTemperature |
string | yes | Color temperature of the light fixture which can be daylight , cool or warm . |
For simplicity, this imaginary lighting system only has one light, so the user does not have to specify a room or location. Here is an example JSON request you could send to the lighting control API to change the light level to 50% using the daylight color temperature:
{
"brightness": "50",
"colorTemperature": "daylight"
}
This tutorial shows you how to set up a Function Call for the Gemini API to interpret users lighting requests and map them to API settings to control a light's brightness and color temperature values.
Before you begin: Set up your project and API key
Before calling the Gemini API, you need to set up your project and configure your API key.
Get and secure your API key
You need an API key to call the Gemini API. If you don't already have one, create a key in Google AI Studio.
Keep your API key secure. You should not include the API key directly in your code, or save files that contain the key in version control systems. Instead, you should use a secrets store for your API key, such as Google Cloud Secret Manager.
Another alternative option is to store it in a GenerativeAI-Info.plist
file,
and then read the API key from the .plist
file. Make sure to put this .plist
file in the root folder of your app and exclude it from version control. The
following code shows how to retrieve an API key from a .plist
file:
enum APIKey {
// Fetch the API key from `GenerativeAI-Info.plist`
static var `default`: String {
guard let filePath = Bundle.main.path(forResource: "GenerativeAI-Info", ofType: "plist")
else {
fatalError("Couldn't find file 'GenerativeAI-Info.plist'.")
}
let plist = NSDictionary(contentsOfFile: filePath)
guard let value = plist?.object(forKey: "API_KEY") as? String else {
fatalError("Couldn't find key 'API_KEY' in 'GenerativeAI-Info.plist'.")
}
if value.starts(with: "_") {
fatalError(
"Follow the instructions at https://ai.google.dev/tutorials/setup to get an API key."
)
}
return value
}
}
You can also review the Swift generative AI
sample app
to learn how to store your API key in a .plist
file. This tutorial assumes
that you're accessing your API key from this on-demand resource .plist
file.
Import the SDK package and configure your API key
To use the Gemini API in your own Swift app, add the GoogleGenerativeAI
package to your Xcode application development project:
In Xcode, right-click on your project in the project navigator.
Select Add Packages from the context menu.
In the Add Packages dialog, paste the package URL in the search bar:
https://github.com/google/generative-ai-swift
Click Add Package to have Xcode add the
GoogleGenerativeAI
package to your project.
Define an API function
Create a function that makes an API request. This function should be defined within the code of your application, but could call services or APIs outside of your application. The Gemini API does not call this function directly, so you can control how and when this function is executed through your application code. For demonstration purposes, this tutorial defines a mock API function that just returns the requested lighting values:
func setLightValues(brightness: String,
colorTemp: String) -> JSONObject {
// This mock API returns the requested lighting values
return [
"brightness": .string(brightness),
"colorTemperature": .string(colorTemp)
]
}
Create function declarations
Create the function declaration that you'll pass to the generative model. When you declare a function for use by the model, you should include as much detail as possible in the function and parameter descriptions. The generative model uses this information to determine which function to select and how to provide values for the parameters in the function call. The following code shows how to declare the lighting control function:
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"]
)
Declare functions during model initialization
When you want to use function calling with a model, you must provide your
function declarations when you initialize the model object. You declare functions
by setting the model's tools
parameter:
// 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])]
)
Generate a function call
Once you have initialized model with your function declarations, you can prompt
the model with the defined function. You should use function calling using
chat prompting (sendMessage()
), since function calling generally benefits from
having the context of previous prompts and responses.
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)