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