1. Grounding with Google Search
Grounding connects Gemini’s responses to real-time information from Google Search, eliminating hallucination for factual queries. When enabled, the model can retrieve current data — news, stock prices, weather, sports scores — and cite its sources.
1.1 Basic Setup
from google import genai
from google.genai import types
client = genai.Client()
# Enable Google Search grounding
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="What were the top 3 news stories today?",
config=types.GenerateContentConfig(
tools=[types.Tool(google_search=types.GoogleSearch())]
)
)
print(response.text)
1.2 Grounding Metadata & Citations
Search-grounded responses include rich metadata — source URLs, titles, and grounding chunks that map specific claims to their sources:
from google import genai
from google.genai import types
client = genai.Client()
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="What is the current population of Tokyo and when was the last census?",
config=types.GenerateContentConfig(
tools=[types.Tool(google_search=types.GoogleSearch())]
)
)
print("Answer:", response.text)
print("\n--- Grounding Metadata ---")
# Access grounding metadata from the candidate
candidate = response.candidates[0]
if candidate.grounding_metadata:
gm = candidate.grounding_metadata
# Search entry point (rendered search widget)
if gm.search_entry_point:
print(f"\nSearch query: {gm.search_entry_point.rendered_content[:100]}...")
# Grounding chunks — individual source citations
if gm.grounding_chunks:
print(f"\nSources ({len(gm.grounding_chunks)}):")
for i, chunk in enumerate(gm.grounding_chunks):
if chunk.web:
print(f" [{i+1}] {chunk.web.title}")
print(f" {chunk.web.uri}")
# Grounding supports — maps text segments to sources
if gm.grounding_supports:
print(f"\nSupported claims ({len(gm.grounding_supports)}):")
for support in gm.grounding_supports[:3]:
print(f" Segment: \"{support.segment.text[:80]}...\"")
print(f" Sources: {support.grounding_chunk_indices}")
print(f" Confidence: {support.confidence_scores}")
1.3 Rendering in UI
For production applications, render grounding metadata as inline citations or footnotes:
from google import genai
from google.genai import types
client = genai.Client()
def format_grounded_response(response) -> str:
"""Format a grounded response with inline citations."""
candidate = response.candidates[0]
text = response.text
if not candidate.grounding_metadata or not candidate.grounding_metadata.grounding_chunks:
return text
# Build citation list
sources = []
for chunk in candidate.grounding_metadata.grounding_chunks:
if chunk.web:
sources.append({"title": chunk.web.title, "url": chunk.web.uri})
# Append footnotes
if sources:
text += "\n\n---\nSources:\n"
for i, source in enumerate(sources, 1):
text += f"[{i}] {source['title']} — {source['url']}\n"
return text
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="What are the latest developments in quantum computing?",
config=types.GenerateContentConfig(
tools=[types.Tool(google_search=types.GoogleSearch())]
)
)
formatted = format_grounded_response(response)
print(formatted)
2. Grounding with Google Maps
The Google Maps tool provides location-aware responses with real business data, directions, and place information.
2.1 Configuration
from google import genai
from google.genai import types
client = genai.Client()
# Enable Google Maps grounding
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="Find the best-rated Italian restaurants near Times Square, New York.",
config=types.GenerateContentConfig(
tools=[types.Tool(google_maps=types.GoogleMaps())]
)
)
print(response.text)
2.2 Location-Aware Responses
Maps grounding excels at queries involving places, distances, business hours, and local recommendations:
from google import genai
from google.genai import types
client = genai.Client()
# Complex location query — combines Maps data with reasoning
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="I'm at the British Museum in London. What are 3 good lunch spots "
"within a 10-minute walk that are open right now and have vegetarian options?",
config=types.GenerateContentConfig(
tools=[types.Tool(google_maps=types.GoogleMaps())]
)
)
print(response.text)
# Access maps-specific grounding data
candidate = response.candidates[0]
if candidate.grounding_metadata and candidate.grounding_metadata.grounding_chunks:
print("\n--- Places Referenced ---")
for chunk in candidate.grounding_metadata.grounding_chunks:
if chunk.web:
print(f" • {chunk.web.title}: {chunk.web.uri}")
Real-Time Sports Commentary
A sports analytics company streams live game video to Gemini’s Live API, which provides instant tactical analysis, identifies key plays, and generates commentary. The system processes video frames in real-time, correlating visual events with statistical data from their database.
3. URL Context Tool
The URL Context tool lets the model fetch and read specific web pages, enabling it to answer questions about particular URLs you provide or that it discovers during reasoning.
3.1 Fetching Web Pages
from google import genai
from google.genai import types
client = genai.Client()
# Let the model read and analyze a specific URL
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="Summarize the key points from this page: "
"https://ai.google.dev/gemini-api/docs/thinking",
config=types.GenerateContentConfig(
tools=[types.Tool(url_context=types.UrlContext())]
)
)
print(response.text)
You can also combine URL context with Google Search to let the model both search for relevant pages and read their full content:
from google import genai
from google.genai import types
client = genai.Client()
# Combine URL context with Search — model searches, finds pages, reads them
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="Find the official Gemini API pricing page and tell me the exact "
"cost per million tokens for Gemini 3.5 Flash input and output.",
config=types.GenerateContentConfig(
tools=[
types.Tool(google_search=types.GoogleSearch()),
types.Tool(url_context=types.UrlContext())
]
)
)
print(response.text)
3.2 URL Context Metadata
Responses using URL context include metadata about which pages were fetched and how they contributed to the answer:
from google import genai
from google.genai import types
client = genai.Client()
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="Read https://docs.python.org/3/library/asyncio.html and explain "
"the difference between asyncio.gather() and asyncio.wait().",
config=types.GenerateContentConfig(
tools=[types.Tool(url_context=types.UrlContext())]
)
)
print("Answer:", response.text[:500])
# Check URL context metadata
candidate = response.candidates[0]
if candidate.grounding_metadata:
gm = candidate.grounding_metadata
# URL context metadata shows which URLs were fetched
if hasattr(gm, 'url_context_metadata') and gm.url_context_metadata:
print("\n--- URLs Fetched ---")
for url_meta in gm.url_context_metadata:
print(f" URL: {url_meta.url}")
print(f" Status: {url_meta.status}")
4. Code Execution Sandbox
The Code Execution tool gives the model a sandboxed Python environment where it can write and run code. This is invaluable for calculations, data transformations, and generating visualizations.
from google import genai
from google.genai import types
client = genai.Client()
# Enable code execution — model writes AND runs Python code
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="Calculate the first 20 Fibonacci numbers and find which ones are prime.",
config=types.GenerateContentConfig(
tools=[types.Tool(code_execution=types.ToolCodeExecution())]
)
)
print(response.text)
The model can also use code execution for data processing tasks that require precision:
from google import genai
from google.genai import types
client = genai.Client()
# Complex calculation that benefits from actual code execution
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="I have quarterly revenue data: Q1=$2.3M, Q2=$2.8M, Q3=$3.1M, Q4=$3.6M. "
"Calculate the quarter-over-quarter growth rates, the compound annual growth rate, "
"and project Q1 next year assuming the trend continues.",
config=types.GenerateContentConfig(
tools=[types.Tool(code_execution=types.ToolCodeExecution())]
)
)
print(response.text)
# Inspect executable code parts in the response
for part in response.candidates[0].content.parts:
if part.executable_code:
print("\n--- Generated Code ---")
print(part.executable_code.code)
if part.code_execution_result:
print("\n--- Execution Output ---")
print(part.code_execution_result.output)
from google import genai
from google.genai import types
client = genai.Client()
# Chart generation — the model creates matplotlib charts in the sandbox
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="Create a visualization comparing the Big-O complexities: "
"O(1), O(log n), O(n), O(n log n), O(n²) for n from 1 to 100. "
"Use matplotlib with a clean, professional style.",
config=types.GenerateContentConfig(
tools=[types.Tool(code_execution=types.ToolCodeExecution())]
)
)
# The response may include generated image data
for part in response.candidates[0].content.parts:
if part.executable_code:
print("Code generated:")
print(part.executable_code.code[:300])
if part.inline_data:
print(f"\nImage generated: {part.inline_data.mime_type}, "
f"{len(part.inline_data.data)} bytes")
if part.text:
print(f"\nExplanation: {part.text[:200]}...")
5. Combining Multiple Built-in Tools
The most powerful pattern combines multiple built-in tools in a single request. The model decides which tools to use based on the query:
from google import genai
from google.genai import types
client = genai.Client()
# All built-in tools enabled — model picks what it needs
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="What was Apple's stock price at close yesterday? "
"Calculate the P/E ratio if their earnings per share is $6.42. "
"Also find their next earnings date.",
config=types.GenerateContentConfig(
tools=[
types.Tool(google_search=types.GoogleSearch()),
types.Tool(code_execution=types.ToolCodeExecution())
]
)
)
print(response.text)
# The model used Search to get the stock price and earnings date,
# then Code Execution to calculate the P/E ratio precisely
from google import genai
from google.genai import types
client = genai.Client()
# Search + URL Context + Code Execution — comprehensive research assistant
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="Find the latest World Bank GDP data for the G7 countries, "
"then create a bar chart comparing them and calculate the "
"percentage each contributes to the G7 total.",
config=types.GenerateContentConfig(
tools=[
types.Tool(google_search=types.GoogleSearch()),
types.Tool(url_context=types.UrlContext()),
types.Tool(code_execution=types.ToolCodeExecution())
]
)
)
print(response.text)
from google import genai
from google.genai import types
client = genai.Client()
# Combine built-in tools with custom functions
def get_company_internal_data(ticker: str) -> dict:
"""Get internal company metrics not available publicly."""
internal_data = {
"AAPL": {"internal_score": 92, "team_size": 164000, "patents_filed_2025": 2340},
"GOOGL": {"internal_score": 88, "team_size": 182000, "patents_filed_2025": 3100},
}
return internal_data.get(ticker, {"error": "Company not found"})
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="Compare Apple and Google: get their current stock prices from the web, "
"then pull our internal metrics for both, and create a comparison table.",
config=types.GenerateContentConfig(
tools=[
types.Tool(google_search=types.GoogleSearch()),
types.Tool(code_execution=types.ToolCodeExecution()),
get_company_internal_data
]
)
)
# Model orchestrates: Search → Custom Function → Code Execution
for part in response.candidates[0].content.parts:
if part.function_call:
print(f"Custom tool called: {part.function_call.name}")
if part.text:
print(part.text[:300])
Next in the Gemini SDK Track
In Part 8: File Search & RAG, we’ll upload documents via the Files API, build retrieval-augmented generation pipelines with Gemini’s 1M+ token context, implement semantic search over uploaded corpora, and combine file-based grounding with other tools for comprehensive document Q&A.