Grounding enables Gemini to generate responses anchored in specific, verifiable information from external data sources. This reduces hallucinations and provides up-to-date, factual responses with citations.
from google import genaifrom google.genai.types import Tool, GoogleSearch, GenerateContentConfigclient = genai.Client(vertexai=True, project=PROJECT_ID, location=LOCATION)google_search_tool = Tool(google_search=GoogleSearch())response = client.models.generate_content( model="gemini-3-flash-preview", contents="Who won the 2024 UEFA European Championship?", config=GenerateContentConfig( tools=[google_search_tool] ))print(response.text)
from google.genai.types import GenerateContentResponsefrom IPython.display import Markdown, displaydef print_grounding_data(response: GenerateContentResponse) -> None: """Print response with grounding citations in Markdown.""" candidate = response.candidates[0] if response.candidates else None metadata = getattr(candidate, "grounding_metadata", None) if not metadata: display(Markdown(response.text)) return ENCODING = "utf-8" text_bytes = response.text.encode(ENCODING) parts = [] last = 0 # Insert citation markers for support in metadata.grounding_supports or []: end = support.segment.end_index parts.append(text_bytes[last:end].decode(ENCODING)) parts.append(" " + "".join(f"[{i + 1}]" for i in support.grounding_chunk_indices)) last = end parts.append(text_bytes[last:].decode(ENCODING)) parts.append("\n\n----\n## Sources\n") # List sources if chunks := metadata.grounding_chunks: for i, chunk in enumerate(chunks, 1): if ctx := chunk.web: uri = ctx.uri.replace(" ", "%20") parts.append(f"{i}. [{ctx.title}]({uri})\n") display(Markdown("".join(parts)))# Use the helperresponse = client.models.generate_content( model="gemini-3-flash-preview", contents="What happened at the 2024 Olympics?", config=GenerateContentConfig(tools=[google_search_tool]))print_grounding_data(response)
from google.genai.types import Partresponse = client.models.generate_content( model="gemini-3-flash-preview", contents=[ Part.from_uri( file_uri="gs://path/to/paris.jpg", mime_type="image/jpeg" ), "What is the current temperature at this location?" ], config=GenerateContentConfig( tools=[google_search_tool] ))print_grounding_data(response)
from google.genai.types import ( Tool, GoogleMaps, ToolConfig, RetrievalConfig, LatLng)google_maps_tool = Tool(google_maps=GoogleMaps())response = client.models.generate_content( model="gemini-3-flash-preview", contents="Recommend some good vegetarian restaurants in Las Vegas.", config=GenerateContentConfig( system_instruction="You are a helpful assistant with access to map data.", tools=[google_maps_tool], tool_config=ToolConfig( retrieval_config=RetrievalConfig( lat_lng=LatLng( latitude=36.1699, longitude=-115.1398 ) ) ) ))print_grounding_data(response)
for chunk in response.candidates[0].grounding_metadata.grounding_chunks: if chunk.maps: print(f"Place: {chunk.maps.title}") print(f"Place ID: {chunk.maps.place_id}") print(f"Address: {chunk.maps.text}")
# Example: Internal HR documentsresponse = client.models.generate_content( model="gemini-3-flash-preview", contents="How do I book business travel?", config=GenerateContentConfig( tools=[vertex_ai_search_tool] ))print(response.text)# View source documentsfor chunk in response.candidates[0].grounding_metadata.grounding_chunks: if chunk.retrieved_context: print(f"Document: {chunk.retrieved_context.title}") print(f"URI: {chunk.retrieved_context.uri}")
chat = client.chats.create( model="gemini-3-flash-preview", config=GenerateContentConfig( tools=[Tool(google_search=GoogleSearch())] ))# First questionresponse = chat.send_message("What are managed datasets in Vertex AI?")print_grounding_data(response)# Follow-up with contextresponse = chat.send_message("What types of data can I use?")print_grounding_data(response)
chat = client.chats.create( model="gemini-3-flash-preview", config=GenerateContentConfig( tools=[vertex_ai_search_tool] ))response = chat.send_message("How do I request time off?")print_grounding_data(response)response = chat.send_message("What's the approval process?")print_grounding_data(response)
response = client.models.generate_content( model="gemini-3-flash-preview", contents="Compare public AI research with our internal guidelines", config=GenerateContentConfig( tools=[ Tool(google_search=GoogleSearch()), vertex_ai_search_tool ] ))
When using Google Search grounding in production, you must display the Search Entry Point to comply with Google Search terms of service. See documentation.
candidate = response.candidates[0]metadata = candidate.grounding_metadata# Check if response is groundedif metadata and metadata.grounding_chunks: print(f"Found {len(metadata.grounding_chunks)} sources") # Check support for each statement for support in metadata.grounding_supports: confidence = support.confidence_scores[0] if support.confidence_scores else 0 if confidence > 0.8: print(f"High confidence: {support.segment.text[:100]}...")else: print("Warning: Response not grounded in sources")