Notebooks
G
Google Gemini
Function Calling

Function Calling

quickstartsgemini-cookbookgemini-apigemini
Copyright 2025 Google LLC.
[21]

Gemini API: Function calling with Python

Function calling lets developers create a description of a function in their code, then pass that description to a language model in a request. The response from the model includes the name of a function that matches the description and the arguments to call it with. Function calling lets you use functions as tools in generative AI applications, and you can define more than one function within a single request.

This notebook provides code examples to help you get started. The documentation's quickstart is also a good place to start understanding function calling.

Setup

Install dependencies

[22]

Set up your API key

To run the following cell, your API key must be stored it in a Colab Secret named GOOGLE_API_KEY. If you don't already have an API key, or you're not sure how to create a Colab Secret, see the Authentication image quickstart for an example.

[23]

Choose a model

Function calling works on all Gemini models.

[24]
MODEL_ID

Setting up Functions as Tools

To use function calling, pass a list of functions to the tools parameter when creating a GenerativeModel. The model uses the function name, docstring, parameters, and parameter type annotations to decide if it needs the function to best answer a prompt.

Important: The SDK converts function parameter type annotations to a format the API understands (genai.types.FunctionDeclaration). The API only supports a limited selection of parameter types, and the Python SDK's automatic conversion only supports a subset of that: AllowedTypes = int | float | bool | str | list['AllowedTypes'] | dict

Example: Lighting System Functions

Here are 3 functions controlling a hypothetical lighting system. Note the docstrings and type hints.

[25]

Basic Function Calling with Chat

Function calls naturally fit into multi-turn conversations. The Python SDK's ChatSession (client.chats.create(...)) is ideal for this, as it automatically handles conversation history.

Furthermore, ChatSession simplifies function calling execution via its automatic_function_calling feature (enabled by default), which will be explored more later. For now, let's see a basic interaction where the model decides to call a function.

[26]
LIGHTBOT: Lights enabled.
No problem, I can turn the lights on for you.

Examining Function Calls and Execution History

To understand what happened in the background, you can examine the chat history.

The Chat.history property stores a chronological record of the conversation between the user and the Gemini model. You can get the history using Chat.get_history(). Each turn in the conversation is represented by a genai.types.Content object, which contains the following information:

Role: Identifies whether the content originated from the "user" or the "model".

Parts: A list of genai.types.Part objects that represent individual components of the message. With a text-only model, these parts can be:

  • Text: Plain text messages.
  • Function Call (genai.types.FunctionCall): A request from the model to execute a specific function with provided arguments.
  • Function Response (genai.types.FunctionResponse): The result returned by the user after executing the requested function.
[27]
--------------------------------------------------------------------------------
Function call: { id=None args={} name='enable_lights' }
--------------------------------------------------------------------------------
Function response: { id=None name='enable_lights' response={'result': None} }
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

This history shows the flow:

  1. User: Sends the message.

  2. Model: Responds not with text, but with a FunctionCall requesting enable_lights.

  3. User (SDK): The ChatSession automatically executes enable_lights() because automatic_function_calling is enabled. It sends the result back as a FunctionResponse.

  4. Model: Uses the function's result ("Lights enabled.") to formulate the final text response.

Automatic Function Execution (Python SDK Feature)

As demonstrated above, the ChatSession in the Python SDK has a powerful feature called Automatic Function Execution. When enabled (which it is by default), if the model responds with a FunctionCall, the SDK will:

  1. Find the corresponding Python function in the provided tools.

  2. Execute the function with the arguments provided by the model.

  3. Send the function's return value back to the model in a FunctionResponse.

  4. Return only the model's final response (usually text) to your code.

This significantly simplifies the workflow for common use cases.

Example: Math Operations

[28]
That would be 2508 mittens in total.
[29]
--------------------------------------------------------------------------------
Function call: { id=None args={'a': 57, 'b': 44} name='multiply' }
--------------------------------------------------------------------------------
Function response: { id=None name='multiply' response={'result': 2508} }
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

Automatic execution handled the multiply call seamlessly.

Automatic Function Schema Declaration

A key convenience of the Python SDK is its ability to automatically generate the required FunctionDeclaration schema from your Python functions. It inspects:

  • Function Name: (func.__name__)

  • Docstring: Used for the function's description.

  • Parameters: Names and type annotations (int, str, float, bool, list, dict). Docstrings for parameters (if using specific formats like Google style) can also enhance the description.

  • Return Type Annotation: Although not strictly used by the model for deciding which function to call, it's good practice.

You generally don't need to create FunctionDeclaration objects manually when using Python functions directly as tools.

However, you can generate the schema explicitly using genai.types.FunctionDeclaration.from_callable if you need to inspect it, modify it, or use it in scenarios where you don't have the Python function object readily available.

[30]
{
    "description": "Set the light color. Lights must be enabled for this to work.",
    "name": "set_light_color",
    "parameters": {
        "properties": {
            "rgb_hex": {
                "type": "STRING"
            }
        },
        "required": [
            "rgb_hex"
        ],
        "type": "OBJECT"
    }
}

Manual function calling

For more control, or if automatic function calling is not available, you can process genai.types.FunctionCall requests from the model yourself. This would be the case if:

  • You use a Chat with the default "automatic_function_calling": {"disable": True}.
  • You use Client.model.generate_content (and manage the chat history yourself).

Example: Movies

The following example is a rough equivalent of the function calling single-turn curl sample in Python. It uses functions that return (mock) movie playtime information, possibly from a hypothetical API:

[31]

After using generate_content() to ask a question, the model requests a function_call:

[32]
{
    "function_call": {
        "args": {
            "location": "Mountain View, CA",
            "movie": "Barbie"
        },
        "name": "find_theaters"
    }
}

Since this is not using a ChatSession with automatic function calling, you have to call the function yourself.

A very simple way to do this would be with if statements:

if function_call.name == 'find_theaters':
  find_theaters(**function_call.args)
elif ...

However, since you already made the theater_functions list, this can be simplified to:

[33]
['Googleplex 16', 'Android Theatre']

Finally, pass the response plus the message history to the next generate_content() call to get a final text response from the model. The next code cell is showing on purpose different ways to write down Content so you can choose the one that you prefer.

[34]
The Barbie movie is currently playing at the Googleplex 16 and Android Theatre in Mountain View.

This demonstrates the manual workflow: call, check, execute, respond, call again.

Parallel function calls

The Gemini API can call multiple functions in a single turn. This caters for scenarios where there are multiple function calls that can take place independently to complete a task.

First set the tools up. Unlike the movie example above, these functions do not require input from each other to be called so they should be good candidates for parallel calling.

[35]

Now call the model with an instruction that could use all of the specified tools.

[36]
Disco ball is spinning!
Starting music! energetic=True loud=True, bpm=130
Lights are now set to 30%
Disco ball is spinning!
Starting music! energetic=True loud=True, bpm=130
Lights are now set to 30%
Disco ball is spinning!
Starting music! energetic=True loud=True, bpm=130
Lights are now set to 30%
Disco ball is spinning!
Starting music! energetic=True loud=True, bpm=130
Lights are now set to 30%
Disco ball is spinning!
Starting music! energetic=True loud=True, bpm=130
Lights are now set to 30%
Disco ball is spinning!
Starting music! energetic=True loud=True, bpm=130
Lights are now set to 30%
Disco ball is spinning!
Starting music! energetic=True loud=True, bpm=130
Lights are now set to 30%
Disco ball is spinning!
Starting music! energetic=True loud=True, bpm=130
Lights are now set to 30%
Disco ball is spinning!
Starting music! energetic=True loud=True, bpm=130
Lights are now set to 30%
Disco ball is spinning!
Starting music! energetic=True loud=True, bpm=130
Lights are now set to 30%
--------------------------------------------------------------------------------
Function call: { id=None args={'power': True} name='power_disco_ball' }
Function call: { id=None args={'energetic': True, 'bpm': 130, 'loud': True} name='start_music' }
Function call: { id=None args={'brightness': 0.3} name='dim_lights' }
--------------------------------------------------------------------------------
Function response: { id=None name='power_disco_ball' response={'result': True} }
Function response: { id=None name='start_music' response={'result': 'Never gonna give you up.'} }
Function response: { id=None name='dim_lights' response={'result': True} }
--------------------------------------------------------------------------------
Function call: { id=None args={'power': True} name='power_disco_ball' }
Function call: { id=None args={'energetic': True, 'bpm': 130, 'loud': True} name='start_music' }
Function call: { id=None args={'brightness': 0.3} name='dim_lights' }
--------------------------------------------------------------------------------
Function response: { id=None name='power_disco_ball' response={'result': True} }
Function response: { id=None name='start_music' response={'result': 'Never gonna give you up.'} }
Function response: { id=None name='dim_lights' response={'result': True} }
--------------------------------------------------------------------------------
Function call: { id=None args={'power': True} name='power_disco_ball' }
Function call: { id=None args={'energetic': True, 'loud': True, 'bpm': 130} name='start_music' }
Function call: { id=None args={'brightness': 0.3} name='dim_lights' }
--------------------------------------------------------------------------------
Function response: { id=None name='power_disco_ball' response={'result': True} }
Function response: { id=None name='start_music' response={'result': 'Never gonna give you up.'} }
Function response: { id=None name='dim_lights' response={'result': True} }
--------------------------------------------------------------------------------
Function call: { id=None args={'power': True} name='power_disco_ball' }
Function call: { id=None args={'loud': True, 'energetic': True, 'bpm': 130} name='start_music' }
Function call: { id=None args={'brightness': 0.3} name='dim_lights' }
--------------------------------------------------------------------------------
Function response: { id=None name='power_disco_ball' response={'result': True} }
Function response: { id=None name='start_music' response={'result': 'Never gonna give you up.'} }
Function response: { id=None name='dim_lights' response={'result': True} }
--------------------------------------------------------------------------------
Function call: { id=None args={'power': True} name='power_disco_ball' }
Function call: { id=None args={'loud': True, 'energetic': True, 'bpm': 130} name='start_music' }
Function call: { id=None args={'brightness': 0.3} name='dim_lights' }
--------------------------------------------------------------------------------
Function response: { id=None name='power_disco_ball' response={'result': True} }
Function response: { id=None name='start_music' response={'result': 'Never gonna give you up.'} }
Function response: { id=None name='dim_lights' response={'result': True} }
--------------------------------------------------------------------------------
Function call: { id=None args={'power': True} name='power_disco_ball' }
Function call: { id=None args={'energetic': True, 'loud': True, 'bpm': 130} name='start_music' }
Function call: { id=None args={'brightness': 0.3} name='dim_lights' }
--------------------------------------------------------------------------------
Function response: { id=None name='power_disco_ball' response={'result': True} }
Function response: { id=None name='start_music' response={'result': 'Never gonna give you up.'} }
Function response: { id=None name='dim_lights' response={'result': True} }
--------------------------------------------------------------------------------
Function call: { id=None args={'power': True} name='power_disco_ball' }
Function call: { id=None args={'energetic': True, 'bpm': 130, 'loud': True} name='start_music' }
Function call: { id=None args={'brightness': 0.3} name='dim_lights' }
--------------------------------------------------------------------------------
Function response: { id=None name='power_disco_ball' response={'result': True} }
Function response: { id=None name='start_music' response={'result': 'Never gonna give you up.'} }
Function response: { id=None name='dim_lights' response={'result': True} }
--------------------------------------------------------------------------------
Function call: { id=None args={'power': True} name='power_disco_ball' }
Function call: { id=None args={'loud': True, 'bpm': 130, 'energetic': True} name='start_music' }
Function call: { id=None args={'brightness': 0.3} name='dim_lights' }
--------------------------------------------------------------------------------
Function response: { id=None name='power_disco_ball' response={'result': True} }
Function response: { id=None name='start_music' response={'result': 'Never gonna give you up.'} }
Function response: { id=None name='dim_lights' response={'result': True} }
--------------------------------------------------------------------------------
Function call: { id=None args={'power': True} name='power_disco_ball' }
Function call: { id=None args={'bpm': 130, 'loud': True, 'energetic': True} name='start_music' }
Function call: { id=None args={'brightness': 0.3} name='dim_lights' }
--------------------------------------------------------------------------------
Function response: { id=None name='power_disco_ball' response={'result': True} }
Function response: { id=None name='start_music' response={'result': 'Never gonna give you up.'} }
Function response: { id=None name='dim_lights' response={'result': True} }
--------------------------------------------------------------------------------
Function call: { id=None args={'power': True} name='power_disco_ball' }
Function call: { id=None args={'bpm': 130, 'loud': True, 'energetic': True} name='start_music' }
Function call: { id=None args={'brightness': 0.3} name='dim_lights' }
--------------------------------------------------------------------------------
Function response: { id=None name='power_disco_ball' response={'result': True} }
Function response: { id=None name='start_music' response={'result': 'Never gonna give you up.'} }
Function response: { id=None name='dim_lights' response={'result': True} }
--------------------------------------------------------------------------------
Function call: { id=None args={'power': True} name='power_disco_ball' }
Function call: { id=None args={'bpm': 130, 'loud': True, 'energetic': True} name='start_music' }
Function call: { id=None args={'brightness': 0.3} name='dim_lights' }
--------------------------------------------------------------------------------

Notice the single model turn contains three FunctionCall parts, which the SDK then executed before getting the final text response.

Compositional Function Calling

The model can chain function calls across multiple turns, using the result from one call to inform the next. This allows for complex, multi-step reasoning and task completion.

Example: Finding Specific Movie Showtimes

Let's reuse the theater_functions and ask a more complex query that requires finding movies first, then potentially theaters, then showtimes.

[37]
OK. I have found comedy movies playing in Mountain View, CA on 01/01/2025, the theaters they are playing in, and their showtimes. The comedy movies playing on 01/01/2025 in Mountain View, CA are Barbie and Oppenheimer.

Barbie is playing at Googleplex 16 and Android Theatre at 10:00 and 11:00.
Oppenheimer is playing at Googleplex 16 and Android Theatre at 10:00 and 11:00.

--- History ---
--------------------------------------------------------------------------------
Function call: { id=None args={'location': 'Mountain View, CA', 'description': 'comedy'} name='find_movies' }
--------------------------------------------------------------------------------
Function response: { id=None name='find_movies' response={'result': ['Barbie', 'Oppenheimer']} }
--------------------------------------------------------------------------------
Function call: { id=None args={'location': 'Mountain View, CA', 'movie': 'Barbie'} name='find_theaters' }
Function call: { id=None args={'movie': 'Oppenheimer', 'location': 'Mountain View, CA'} name='find_theaters' }
--------------------------------------------------------------------------------
Function response: { id=None name='find_theaters' response={'result': ['Googleplex 16', 'Android Theatre']} }
Function response: { id=None name='find_theaters' response={'result': ['Googleplex 16', 'Android Theatre']} }
--------------------------------------------------------------------------------
Function call: { id=None args={'date': '01/01/2025', 'location': 'Mountain View, CA', 'movie': 'Barbie', 'theater': 'Googleplex 16'} name='get_showtimes' }
Function call: { id=None args={'theater': 'Android Theatre', 'date': '01/01/2025', 'location': 'Mountain View, CA', 'movie': 'Barbie'} name='get_showtimes' }
Function call: { id=None args={'theater': 'Googleplex 16', 'movie': 'Oppenheimer', 'date': '01/01/2025', 'location': 'Mountain View, CA'} name='get_showtimes' }
Function call: { id=None args={'theater': 'Android Theatre', 'location': 'Mountain View, CA', 'movie': 'Oppenheimer', 'date': '01/01/2025'} name='get_showtimes' }
--------------------------------------------------------------------------------
Function response: { id=None name='get_showtimes' response={'result': ['10:00', '11:00']} }
Function response: { id=None name='get_showtimes' response={'result': ['10:00', '11:00']} }
Function response: { id=None name='get_showtimes' response={'result': ['10:00', '11:00']} }
Function response: { id=None name='get_showtimes' response={'result': ['10:00', '11:00']} }
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

Here you can see that the model made seven calls to answer your question and used the outputs of them in the subsequent calls and in the final answer.

Function Calling Configuration using Modes

While AUTO mode (or the SDK's default automatic execution) is often sufficient, you can precisely control when and which functions the model is allowed to call using the tool_config parameter during model/chat initialization or in send_message.

The tool_config accepts a ToolConfig object, which contains a FunctionCallingConfig.

The FunctionCallingConfig has two main fields:

  • mode: Controls the overall function calling behavior (AUTO, ANY, NONE).

  • allowed_function_names: An optional list of function names the model is restricted to calling in this turn.

AUTO (Default Mode)

  • Behavior: The model decides whether to respond with text or to call one or more functions from the provided tools. This is the most flexible mode.

  • SDK Default: When using ChatSession with automatic execution enabled, the underlying behavior effectively uses AUTO mode unless overridden by tool_config.

[38]
LIGHTBOT: Lights enabled.
--------------------------------------------------------------------------------
Function call: { id=None args={} name='enable_lights' }
--------------------------------------------------------------------------------
Function response: { id=None name='enable_lights' response={'result': None} }
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

NONE Mode

Behavior: The model is explicitly prohibited from calling any functions, even if tools are provided. It will only respond with text. Useful for turns where you want a purely conversational response.

[39]
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

ANY Mode

  • Behavior: Forces the model to call at least one function.

    • If allowed_function_names is set, the model must choose one or more functions from that list.

    • If allowed_function_names is not set, the model must choose one or more functions from the full tools list.

  • If automatic function calling is enabled, the SDK will call functions automatically until maximum_remote_calls is reached (default: 10).

  • To allow x automatic function calls, set maximum_remote_calls to x + 1. Read more

  • Use Case: Useful when the application state dictates that the next step must involve a specific action or set of actions.

[40]
LIGHTBOT: Lights enabled.
--------------------------------------------------------------------------------
Function call: { id=None args={} name='enable_lights' }
--------------------------------------------------------------------------------
Function response: { id=None name='enable_lights' response={'result': None} }
--------------------------------------------------------------------------------
Function call: { id=None args={} name='enable_lights' }
--------------------------------------------------------------------------------

Next Steps

Useful API references:

Related examples

Check out these examples using function calling to give you more ideas on how to use that very useful feature:

Continue your discovery of the Gemini API

Learn how to control how the Gemini API interact with your functions in the function calling config quickstart, discover how to control the model output in JSON or using an Enum or learn how the Gemini API can generate and run code by itself using Code execution