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.
Set up your project
Before calling the Gemini API, you need to set up your project, which includes setting up your API key, installing the SDK package, and initializing the model.
To use the Gemini API, you'll need an API key. If you don't already have one, create a key in Google AI Studio.
Secure your API key
It's strongly recommended that you do not check an API key into your version control system. Instead, you should use a secrets store for your API key.
This tutorial assumes that you're accessing your API key as an environment variable.
To use the Gemini API in your own application, you need to get
the Go SDK
package in your module directory:
go get github.com/google/generative-ai-go
Before you can make any API calls, you need to import and initialize the generative model. This is the basic initialization; later in this tutorial you'll update it for function calling.
import "github.com/google/generative-ai-go/genai"
import "google.golang.org/api/option"
ctx := context.Background()
// Access your API key as an environment variable (see "Set up your API key" above)
client, err := genai.NewClient(ctx, option.WithAPIKey(os.Getenv("API_KEY")))
if err != nil {
log.Fatal(err)
}
defer client.Close()
// Use a model that supports function calling, like Gemini 1.0 Pro.
// See "Supported models" in the "Introduction to function calling" page.
model := client.GenerativeModel("MODEL_NAME")
Set up a function call
For this tutorial, you'll have the model interact with a hypothetical currency exchange API that supports the following parameters:
Parameter | Type | Required | Description |
---|---|---|---|
currencyDate
|
string | yes | Date to fetch the exchange rate for (which must always be in YYYY-MM-DD format or the value latest if a time period is not specified) |
currencyFrom |
string | yes | Currency to convert from |
currencyTo |
string | no | Currency to convert to |
Example API request
{
"currencyDate": "2024-04-17",
"currencyFrom": "USD",
"currencyTo": "SEK"
}
Example API response
{
"base": "USD",
"date": "2024-04-17",
"rates": {"SEK": 0.091}
}
Step 1: Create the function that makes the API request
If you haven't already, start by creating the function that makes an API request.
For demonstration purposes in this tutorial, rather than sending an actual API request, you'll be returning hardcoded values in the same format that an actual API would return.
func exchangeRate(currencyDate string,
currencyFrom string, currencyTo string) map[string]any {
// This hypothetical API returns a JSON such as:
// {"base":"USD","date":"2024-04-17","rates":{"SEK": 0.091}}
return map[string]any{
"base": currencyFrom,
"date": currencyDate,
"rates": map[string]any{currencyTo: 0.091}}
}
Step 2: Create a function declaration
Create the function declaration that you'll pass to the generative model (next step of this tutorial).
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.
currencyExchangeTool := &genai.Tool{
FunctionDeclarations: []*genai.FunctionDeclaration{{
Name: "exchangeRate",
Description: "Lookup currency exchange rates by date",
Parameters: &genai.Schema{
Type: genai.TypeObject,
Properties: map[string]*genai.Schema{
"currencyDate": {
Type: genai.TypeString,
Description: "A date that must always be in YYYY-MM-DD format" +
" or the value 'latest' if a time period is not specified",
},
"currencyFrom": {
Type: genai.TypeString,
Description: "Currency to convert from",
},
"currencyTo": {
Type: genai.TypeString,
Description: "Currency to convert to",
},
},
Required: []string{"currencyDate", "currencyFrom"},
},
}},
}
Step 3: Specify the function declaration during model initialization
Specify the function declaration when initializing the generative model by
passing it into the model's Tools
parameter:
// ...
currencyExchangeTool := &genai.Tool{
// ...
}
// Use a model that supports function calling, like Gemini 1.0 Pro.
// See "Supported models" in the "Introduction to function calling" page.
model := client.GenerativeModel("gemini-1.0-pro")
// Specify the function declaration.
model.Tools = []*genai.Tool{currencyExchangeTool}
Step 4: Generate a function call
Now you can prompt the model with the defined function.
The recommended way to use function calling is through the chat interface, since function calls fit nicely into chat's multi-turn structure.
// Start new chat session.
session := model.StartChat()
prompt := "How much is 50 US dollars worth in Swedish krona?"
// Send the message to the generative model.
resp, err := session.SendMessage(ctx, genai.Text(prompt))
if err != nil {
log.Fatalf("Error sending message: %v\n", err)
}
// Check that you got the expected function call back.
part := resp.Candidates[0].Content.Parts[0]
funcall, ok := part.(genai.FunctionCall)
if !ok {
log.Fatalf("Expected type FunctionCall, got %T", part)
}
if g, e := funcall.Name, currencyExchangeTool.FunctionDeclarations[0].Name; g != e {
log.Fatalf("Expected FunctionCall.Name %q, got %q", e, g)
}
fmt.Printf("Received function call response:\n%q\n\n", part)
apiResult := map[string]any{
"base": "USD",
"date": "2024-04-17",
"rates": map[string]any{"SEK": 0.091}}
// Send the hypothetical API result back to the generative model.
fmt.Printf("Sending API result:\n%q\n\n", apiResult)
resp, err = session.SendMessage(ctx, genai.FunctionResponse{
Name: currencyExchangeTool.FunctionDeclarations[0].Name,
Response: apiResult,
})
if err != nil {
log.Fatalf("Error sending message: %v\n", err)
}
// Show the model's response, which is expected to be text.
for _, part := range resp.Candidates[0].Content.Parts {
fmt.Printf("%v\n", part)
}