GEMINI LABJP
ROBOTICS — The ER 1.6 preview that shut down on August 31 does have a successor. Gemini Robotics ER 2 is in public preview, in both standard and streaming variantsVIDEO — ER 2 judges success and failure from live video rather than still snapshots, which is what lets it catch spills, slips, and misalignments while a task is still runningDEADLINE — Next up is September 30, when gemini-omni-flash-preview is retired. The target is gemini-omni-1.1-flash, GA since August 27, and there are now under four weeks leftAPIKEY — Every remaining standard API key, restricted ones included, stops working during September. The replacement is an auth key bound to a Google Cloud service accountPRICE — Gemini 3.7 Flash keeps its introductory $0.75/$3.75 per 1M through December 31, then moves to $1.50/$7.50 on January 1, 2027. Any estimate crossing the year needs both figuresAUDIO — Gemini 3.5 Transcribe handles language detection across 85+ languages, speaker diarization, word-level timestamps, and custom vocabulary biasing of up to 1,000 termsROBOTICS — The ER 1.6 preview that shut down on August 31 does have a successor. Gemini Robotics ER 2 is in public preview, in both standard and streaming variantsVIDEO — ER 2 judges success and failure from live video rather than still snapshots, which is what lets it catch spills, slips, and misalignments while a task is still runningDEADLINE — Next up is September 30, when gemini-omni-flash-preview is retired. The target is gemini-omni-1.1-flash, GA since August 27, and there are now under four weeks leftAPIKEY — Every remaining standard API key, restricted ones included, stops working during September. The replacement is an auth key bound to a Google Cloud service accountPRICE — Gemini 3.7 Flash keeps its introductory $0.75/$3.75 per 1M through December 31, then moves to $1.50/$7.50 on January 1, 2027. Any estimate crossing the year needs both figuresAUDIO — Gemini 3.5 Transcribe handles language detection across 85+ languages, speaker diarization, word-level timestamps, and custom vocabulary biasing of up to 1,000 terms
Articles/Dev Tools
Dev Tools/2026-03-11Intermediate

Gemini External Tool Integration — Grounding and Function Calling in Practice

How to connect Gemini to external services and your own data, covering both the in-app integrations and the API tools parameter: Google Search grounding, the full Function Calling round-trip, and the latency and cost trade-offs to plan for.

Gemini83Function Calling17IntegrationGrounding4Tools

I asked for the latest, and got a confident, stale answer

While drafting an app announcement with Gemini, I asked it to "account for the recent release status," but it answered based on how things stood months earlier. That makes sense: a model answers from what it learned up to its training cutoff.

The way past that wall — "doesn't know the latest" and "can't see my data" — is external tool integration. Gemini offers two paths: the integrations you toggle in the app, and the tools parameter you call from the API. Knowing both lets you pick the right one for the job.

In-app integrations

In the Gemini app (web and mobile), you can toggle connections to Google services from the settings screen. They are designed to fire automatically only when a question calls for them.

Google Search

Activates for news, current events, and real-time figures, folding search results into the answer.

  • "What's the weather in Tokyo today?"
  • "Summarize recent AI news in three lines"
  • "When was company X's latest earnings report?"

Google Maps

Searches places, directions, and store or hotel details.

  • "How do I get from Shibuya Station to Tokyo Tower?"
  • "Highly-rated Italian restaurants nearby"

YouTube

Searches videos and suggests related content.

  • "Find Python machine learning tutorial videos"

Google Flights & Hotels

Searches and compares flights and accommodations.

  • "Cheapest flights from Tokyo to Paris next month"

Each integration toggles independently. Turning off the ones you don't need avoids unintended external calls.

From the API: search grounding

To do the same thing from code, you use the tools parameter. Start with search grounding: the model runs a Google Search only when it judges one is needed, then builds the answer on top of those results.

from google import genai
from google.genai import types
 
client = genai.Client(api_key="YOUR_API_KEY")
 
response = client.models.generate_content(
    model="gemini-3.5-flash",
    contents="What's the current weather in Tokyo? Cite your sources.",
    config=types.GenerateContentConfig(
        tools=[types.Tool(google_search=types.GoogleSearch())],
    ),
)
 
print(response.text)
 
# Pull out the grounding sources
meta = response.candidates[0].grounding_metadata
if meta and meta.grounding_chunks:
    for chunk in meta.grounding_chunks:
        print("Source:", chunk.web.uri)
else:
    print("(No search was used for this request)")

The model searches only when it decides outside information is required. A weather question returns grounding_chunks; a question answerable from general knowledge skips search and leaves grounding_metadata empty. Always branch for the no-grounding case — that is the trick to keeping this stable in production. Code that never assumes grounding exists won't crash on the quieter requests.

From the API: the Function Calling round-trip

Search grounding is executed for you on Google's side. To reach your own database or internal API, you use Function Calling. Here is the step most introductions skip: once the model says it wants to call a function, who actually runs it? Your code does.

The flow has five stages: (1) declare the function, (2) the model requests a call, (3) you execute the function, (4) you return the result to the model, (5) the model produces the final answer.

from google import genai
from google.genai import types
 
client = genai.Client(api_key="YOUR_API_KEY")
 
# (1) Declare the function
get_weather = types.FunctionDeclaration(
    name="get_weather",
    description="Return the current weather for a given city",
    parameters={
        "type": "object",
        "properties": {
            "city": {"type": "string", "description": "City name"},
        },
        "required": ["city"],
    },
)
tools = [types.Tool(function_declarations=[get_weather])]
 
# The local implementation that actually runs (normally it hits an API)
def run_get_weather(city: str) -> dict:
    fake_db = {"Tokyo": "Clear, 24C", "Osaka": "Cloudy, 22C"}
    return {"city": city, "weather": fake_db.get(city, "no data")}
 
contents = [
    types.Content(role="user", parts=[types.Part(text="What's the weather in Tokyo?")]),
]
 
# (2) First call to the model
resp = client.models.generate_content(
    model="gemini-3.5-flash",
    contents=contents,
    config=types.GenerateContentConfig(tools=tools),
)
 
part = resp.candidates[0].content.parts[0]
if part.function_call:
    call = part.function_call
    # (3) Run the function on our side
    result = run_get_weather(**dict(call.args))
 
    # (4) Append both the model's call and our result to the history
    contents.append(resp.candidates[0].content)
    contents.append(
        types.Content(
            role="tool",
            parts=[types.Part(
                function_response=types.FunctionResponse(
                    name=call.name, response=result,
                )
            )],
        )
    )
 
    # (5) Get the final answer grounded in the result
    final = client.models.generate_content(
        model="gemini-3.5-flash",
        contents=contents,
        config=types.GenerateContentConfig(tools=tools),
    )
    print(final.text)

The key is step (4): append both the model's call (function_call) and your execution result (function_response) to the history before asking for the final answer. Return only the result, and the model loses track of what was asked and what came back, producing an off-target reply. I once spent half a day on a bug caused by appending just one of the two.

Four things I watch in production

Inserting an external tool adds concerns that plain text generation never had. Here is what I check every time while running these in my own indie projects.

  • Latency: tool calls involve a network round-trip, so responses slow down. On user-facing screens, an interim "searching…" indicator changes the perceived speed dramatically.
  • Cost: grounding searches and multiple round-trips each add charges. Estimating on the free tier before designing your production rate limits keeps things safe.
  • Citations: the source URLs in grounding_chunks are your material for showing readers that an answer is trustworthy. If you display them, account for dead links.
  • Preventing stray calls: pass only the tools you actually need. Declaring too many raises the odds the model picks an unintended function.

Choosing between them in indie development

For drafts where factual freshness matters — app announcements, release notes — I reach for search grounding. When the answer depends on data that lives only on my side, such as internal metrics or inventory, I use Function Calling. Feeding in app revenue figures (an AdMob report, say) for summarization is another job for the latter.

The in-app integrations are best for getting a feel for the behavior by hand. The API tools come into their own once you fold that behavior into automation.

Which model should call the tools

When you build tool integration, the model you pick shapes the outcome too. In my own setup, I lean on gemini-3.5-flash for the lighter round-trips — search grounding or a single Function Calling hop — where speed matters, and only reach for a higher-tier model when I want to chain several tools and have it reason step by step.

Flash models respond quickly and stay cheaper, which suits features that run in sync with a user's action. For work that keeps no one waiting — a nightly batch, say — where you want precision in picking the right tool and assembling its arguments, switching up is worth it. Build on Flash first; if you see wrong-function picks or dropped arguments, move up. That order wastes the least effort.

One more thing: calling the API without naming a model uses the default, and that default can shift with updates. In automation, pin model explicitly so behavior doesn't change out from under you one day.

Your next step

With your own Gemini API key, run the search-grounding snippet above as-is, and try one question that returns grounding_chunks and one that doesn't. Experiencing the empty case first makes the design decisions far easier when you wire up the Function Calling round-trip.

Thank you for reading. I hope it gives you a solid foothold as you start building.

Share

Thank You for Reading

Gemini Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $15 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Dev Tools2026-08-21
How Many Assistant-Dependent Lines Are Still in Your App?
On September 4th, Google Assistant on Android begins its replacement by Gemini. Here is how to grep your own project for every entry point an assistant can open, and how to turn that list into utterances you can actually test on a device.
Dev Tools2026-06-24
Folding a Local Gemma 4 into Daily Work — Practical Notes on the Ollama API and Response Speed
Taking a local Gemma 4 you can now run interactively and folding it into real work: how to hit Ollama's local API from a script, tricks to improve perceived response speed, and a two-tier fallback that automatically routes to the cloud Gemini API — code included.
Dev Tools2026-06-24
Running Gemma 4 Locally on Windows — A Hands-On LLM in Two Commands with Ollama
How to run Google's lightweight open model Gemma 4 locally on a Windows laptop. With Ollama, you go from install to running in effectively two commands. Plus how to split work between the cloud Gemini API and a local Gemma.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →