> ## AI Agent Context
> Get the complete documentation index at: https://aistudio.google.com/llms.txt
> Use this file to discover all available pages.
> For the full documentation in a single file, fetch: https://aistudio.google.com/llms-full.txt

# Combine built-in tools and function calling

{% callout type="note" %}
  This feature is in [preview](/docs/models#preview) and supported for [Gemini 4](/docs/models#gemini-4) and [Gemini 3](/docs/models#gemini-3) models.

{% /callout %}

Gemini allows the combination of [built-in tools](/docs/tools), such
as `google_search`, and [function calling](/docs/function-calling)
(also known as *custom tools*) in a single interaction by preserving and
exposing the context history of tool calls. Built-in and custom tool
combinations allow for complex, agentic workflows where, for example, the model
can ground itself in real-time web data before calling your specific business
logic.

Here's an example that enables built-in and custom tool combinations with
`google_search` and a custom function `getWeather`:

{% tabs %}
  {% tab label="Python" %}
  ```python
  # This will only work for SDK newer than 2.0.0
  from google import genai
  
  client = genai.Client()
  
  getWeather = {
      "type": "function",
      "name": "getWeather",
      "description": "Gets the weather for a requested city.",
      "parameters": {
          "type": "object",
          "properties": {
              "city": {
                  "type": "string",
                  "description": "The city and state, e.g. Utqiaġvik, Alaska",
              },
          },
          "required": ["city"],
      },
  }
  
  # The Interactions API manages context automatically across tool calls.
  # The model will first use Google Search, then call getWeather.
  interaction = client.interactions.create(
      model="gemini-3.8-flash",
      input="What is the northernmost city in the United States? What's the weather like there today?",
      tools=[
          {"type": "google_search"},
          getWeather,
      ],
  )
  
  # Process steps: the interaction contains search results and a function call
  for step in interaction.steps:
      if step.type == "function_call":
          print(f"Function call: {step.name} with args: {step.arguments}")
          # In a real application, you would execute the function here
          # and provide the result back to the model.
  ```

  {% /tab %}

  {% tab label="JavaScript" %}
  ```javascript
  // This will only work for SDK newer than 2.0.0
  import { GoogleGenAI } from '@google/genai';
  
  const client = new GoogleGenAI({});
  
  // The Interactions API manages context automatically across tool calls.
  // The model will first use Google Search, then call getWeather.
  const interaction = await client.interactions.create({
      model: "gemini-3.8-flash",
      input: "What is the northernmost city in the United States? What's the weather like there today?",
      tools: [
          { type: "google_search" },
          {
              type: "function",
              name: "get_weather",
              description: "Get current weather",
              parameters: {
                  type: "object",
                  properties: { location: { type: "string" } },
                  required: ["location"],
              },
          },
      ],
  });
  
  // Process steps: the interaction contains search results and a function call
  for (const step of interaction.steps) {
      if (step.type === "function_call") {
          console.log(`Function call: ${step.name} with args: ${JSON.stringify(step.arguments)}`);
          // In a real application, you would execute the function here
          // and provide the result back to the model.
      }
  }
  ```

  {% /tab %}

  {% tab label="Java" %}
  ```java
  import com.google.genai.Client;
  import com.google.genai.gaos.models.interactions.CreateModelInteraction;
  import com.google.genai.gaos.models.interactions.Function;
  import com.google.genai.gaos.models.interactions.GoogleSearch;
  import com.google.genai.gaos.models.interactions.Interaction;
  import com.google.genai.gaos.models.interactions.InteractionsInput;
  import com.google.genai.gaos.models.interactions.Model;
  import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
  import java.util.Arrays;
  import java.util.HashMap;
  import java.util.Map;
  
  Client client = new Client();
  
  Map<String, Object> parameters = new HashMap<>();
  parameters.put("type", "object");
  
  Function customFunc =
      Function.builder()
          .name("get_user_location")
          .description("Retrieves user current location.")
          .parameters(parameters)
          .build();
  
  CreateModelInteraction params =
      CreateModelInteraction.builder()
          .model(Model.of("gemini-3.8-flash"))
          .input(InteractionsInput.of("What is the weather like where I am right now?"))
          .tools(Arrays.asList(customFunc, new GoogleSearch()))
          .build();
  
  Interaction interaction =
      client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
  
  System.out.println(interaction.outputText().orElse(""));
  ```

  {% /tab %}

  {% tab label="Go" %}
  ```go
  package main
  
  import (
      "context"
      "fmt"
      "log"
  
      "google.golang.org/genai"
      "google.golang.org/genai/interactions/models/interactions"
      "google.golang.org/genai/interactions/models/operations"
  )
  
  func main() {
      ctx := context.Background()
      client, err := genai.NewClient(ctx, nil)
      if err != nil {
          log.Fatal(err)
      }
  
      customFunc := interactions.NewTool(interactions.Function{
          Name:        genai.Ptr("get_user_location"),
          Description: genai.Ptr("Retrieves user current location."),
          Parameters: map[string]any{
              "type": "object",
          },
      })
  
      res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
          Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
              Model: interactions.Model("gemini-3.8-flash"),
              Input: interactions.NewInteractionsInput("What is the weather like where I am right now?"),
              Tools: []interactions.Tool{
                  customFunc,
                  interactions.NewTool(interactions.GoogleSearch{}),
              },
          }),
      })
      if err != nil {
          log.Fatal(err)
      }
      if res.Interaction.OutputText != nil {
          fmt.Println(*res.Interaction.OutputText)
      }
  }
  ```

  {% /tab %}

  {% tab label="REST" %}
  ```bash
  # Specifies the API revision to avoid breaking changes when they become default
  curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
  -H "Content-Type: application/json" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Api-Revision: 2026-05-20" \
  -d '{
    "model": "gemini-3.8-flash",
    "input": "What is the northernmost city in the United States? What'\''s the weather like there today?",
    "tools": [
      { "type": "google_search" },
      {
        "type": "function",
        "name": "getWeather",
        "description": "Get the weather in a given location",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "The city and state, e.g. San Francisco, CA"
                }
            },
            "required": ["location"]
        }
      }
    ]
  }'
  ```

  {% /tab %}

{% /tabs %}

## How it works  {% id="how-it-works" %}

Gemini 3 models use *tool context circulation* to enable built-in and custom
tool combinations. Tool context circulation makes it possible to preserve and
expose the context of built-in tools and share it with custom tools in the same
interaction.

### Enable tool combination  {% id="enable" %}

* Include the [`function_declarations`](/docs/function-calling#function-declarations), along
  with the built-in tools you want to use, to trigger the combination behavior.

### API returns steps  {% id="api-returns-steps" %}

In an interaction response, the API returns separate steps for built-in tool
calls and function (custom tool) calls:

*     **Built-in tool steps**: The API manages these automatically, preserving
  context across turns.

*     **Function call steps**: The API returns `function_call` steps for your
  custom functions. You execute the function and provide the result back.


### Critical fields in returned steps  {% id="critical-fields" %}

Certain fields in the returned steps are critical to maintaining tool context
and enabling tool combinations:

* **`id`**: Found on `function_call` and `function_response` steps. A unique
  identifier that maps a call to its response.
* **`signature`**: Found on `thought` steps, as well as all tool call (e.g.,
  `function_call`) and result (e.g., `function_response`) steps for Gemini 3+
  models. This encrypted context enables **tool context circulation** across
  interactions.

**Managing these fields:**

* **Stateful Mode (Recommended)**: When you use `previous_interaction_id`, the
  server automatically handles both `id` and `signature` fields.
* **Stateless Mode**: When managing conversation history manually, you must
  ensure that you pass both the `id` and the `signature` fields back to the
  model in subsequent requests to validate authenticity and maintain context.
  The
  official SDKs handle this automatically if you pass the full response object
  back to history.

### Tool-specific data  {% id="data" %}

Some built-in tools return user-visible data arguments specific to the tool
type.

{% table %}
  * Tool
  * User visible tool call args (if any)
  * User visible tool response (if any)

  ---

  * **google_search**
  * `queries`
  * `search_suggestions`

  ---

  * **google_maps**
  * `queries`
  *     `places`

    `google_maps_widget_context_token`


  ---

  * **url_context**
  *     `urls`

    URLs to be browsed

  *     `status`: Browse status

    `retrieved_url`: URLs browsed


  ---

  * **file_search**
  * None
  * None
{% /table %}

## Tokens and pricing  {% id="tokens" %}

Note that built-in tool call parts in requests are counted towards
`prompt_token_count`. Since these intermediate tool steps are now visible and
returned to you, they are part of the conversation history. This is only the
case for *requests*, not *responses*.

The Google Search tool is an exception to this rule. Google Search already
applies its own pricing model at the query level, so tokens are not
double-charged (see the [Pricing](/docs/pricing) page).

Read the [Tokens](/docs/tokens) page for more information.

## Limitations  {% id="limitations" %}

*   Default to `validated` mode (`auto` mode is not supported) when
  tool context circulation is enabled.

*   Built-in tools like `google_search` rely on location and current time
  information, so if your `system_instruction` or
  `function_declaration.description` has conflicting location and time
  information, the tool combination feature might not work well.


## Supported tools  {% id="supported-tools" %}

Standard tool context circulation applies to server-side (built-in) tools.
Code Execution is also a server-side tool, but has its own built-in solution to
context circulation. Computer Use and function calling are client-side tools,
and also have built-in solutions to context circulation.

| Tool | Execution side | Context Circulation Support |
| :--- | :--- | :--- |
| [Google Search](/docs/google-search) | Server-side | Supported |
| [Google Maps](/docs/maps-grounding) | Server-side | Supported |
| [URL Context](/docs/url-context) | Server-side | Supported |
| [File Search](/docs/file-search) | Server-side | Supported |
| [Code Execution](/docs/code-execution) | Server-side | Supported (built in, uses `code_execution` and `code_execution_result` steps) |
| [Computer Use](/docs/computer-use) | Client-side | Supported (built in, uses `function_call` and `function_response` steps) |
| [Custom functions](/docs/function-calling) | Client-side | Supported (built in, uses `function_call` and `function_response` steps) |

## What's next  {% id="whats-next" %}

* Learn more about [Function calling](/docs/function-calling) in the Gemini API.
* Explore the supported tools:  * [Google Search](/docs/google-search)
  * [Google Maps](/docs/maps-grounding)
  * [URL Context](/docs/url-context)
  * [File Search](/docs/file-search)


