Building with Gemini 3
Implementing Real-Time Search Grounding in 2026
1. Introduction
By 2026, artificial intelligence models can generate fluent, human-like responses. However, the real challenge for production-grade systems is no longer generation quality — it is data accuracy, freshness, and verifiability.
For use cases such as:
extracting hospital contact details
validating public directories
enriching CRM systems
traditional AI approaches frequently fail due to:
outdated data
hallucinated contact information
lack of source verification
This article demonstrates how Gemini 3 Real-Time Search Grounding can be used to extract verified hospital details across Africa, export the results to Excel, and maintain audit-ready outputs.
2. What Is Real-Time Search Grounding?
Real-time search grounding allows Gemini 3 to:
search the web at request time
retrieve live, authoritative sources
constrain its response strictly to retrieved data
Unlike traditional RAG (Retrieval-Augmented Generation), this approach:
does not require a vector database
avoids stale document repositories
minimizes hallucination for public data
This makes it particularly suitable for dynamic, real-world datasets such as hospital directories.
3. Use Case Overview
Objective
Extract verified contact information for 20 hospitals across Africa, including:
Hospital Name
Email Address
Contact Number
Physical Address
Country
Output Format
Structured JSON (from Gemini 3)
Exported Excel file for validation and reporting
4. Solution Architecture
The implementation follows a simple and reliable pipeline:
User Prompt
↓
Gemini 3 with Live Google Search
↓
Grounded & Verified Reasoning
↓
Structured JSON Output
↓
Excel Export
This architecture ensures that:
all data is sourced live
unverifiable fields are returned as null
no assumptions or fabricated values are introduced
6. Environment Requirements
Create a file named requirements.txt:
google-genai
pandas
openpyxl
These libraries handle:
Gemini 3 API interaction
structured data processing
Excel file generation
7. Implementation Code
from google import genai
from google.genai import types
import pandas as pd
from typing import List, Dict
import json
import re
import time
# Configure API key
API_KEY = "your_api_key_here"
client = genai.Client(api_key=API_KEY)
def extract_hospital_details(query: str, location: str = None, count: int = 20) -> List[Dict]:
"""
Extract hospital details using Gemini with grounding.
Args:
query: Search query for hospitals
location: Optional location to search in
count: Number of hospitals to request (default 20 per call)
Returns:
List of dictionaries containing hospital details
"""
# Define the modern Google Search tool
google_search_tool = types.Tool(
google_search=types.GoogleSearch()
)
# Build the prompt with explicit JSON format request
if location:
prompt = f"""Find {count} hospitals in {location}. For each hospital, extract and provide:
1. Name
2. Complete address
3. Contact/Phone number
4. Email address
Return as many hospitals as possible (up to {count}) as a JSON array where each object has these exact keys: "name", "address", "contact", "email".
Format: [{{"name": "...", "address": "...", "contact": "...", "email": "..."}}, ...]"""
else:
prompt = f"""Find {count} hospitals based on: {query}. For each hospital, extract and provide:
1. Name
2. Complete address
3. Contact/Phone number
4. Email address
Return as many hospitals as possible (up to {count}) as a JSON array where each object has these exact keys: "name", "address", "contact", "email".
Format: [{{"name": "...", "address": "...", "contact": "...", "email": "..."}}, ...]"""
try:
# Generate content with grounding using the new API
response = client.models.generate_content(
model='gemini-3-flash-preview',
contents=prompt,
config=types.GenerateContentConfig(
tools=[google_search_tool],
temperature=0.7
)
)
# Parse the response - try to extract JSON first
hospitals = []
response_text = response.text
# Try to extract JSON from response
try:
# Look for JSON array in the response
start_idx = response_text.find('[')
end_idx = response_text.rfind(']') + 1
if start_idx != -1 and end_idx > start_idx:
json_str = response_text[start_idx:end_idx]
hospitals = json.loads(json_str)
# Rename keys to match Excel columns
for hospital in hospitals:
hospital['Name'] = hospital.pop('name', '')
hospital['Address'] = hospital.pop('address', '')
hospital['Contact'] = hospital.pop('contact', '')
hospital['Email'] = hospital.pop('email', '')
else:
# Try to find JSON objects
json_pattern = r'\{[^{}]*"name"[^{}]*\}'
matches = re.findall(json_pattern, response_text, re.DOTALL)
if matches:
hospitals = [json.loads(match) for match in matches]
for hospital in hospitals:
hospital['Name'] = hospital.pop('name', '')
hospital['Address'] = hospital.pop('address', '')
hospital['Contact'] = hospital.pop('contact', '')
hospital['Email'] = hospital.pop('email', '')
except json.JSONDecodeError:
# Fallback: parse text format
lines = response_text.split('\n')
current_hospital = {}
for line in lines:
line = line.strip()
if not line:
if current_hospital and len(current_hospital) > 0:
hospitals.append(current_hospital)
current_hospital = {}
continue
# Try to parse different formats
if 'name' in line.lower() and ':' in line:
name = line.split(':', 1)[1].strip()
current_hospital['Name'] = name
elif 'address' in line.lower() and ':' in line:
address = line.split(':', 1)[1].strip()
current_hospital['Address'] = address
elif ('contact' in line.lower() or 'phone' in line.lower() or 'tel' in line.lower()) and ':' in line:
contact = line.split(':', 1)[1].strip()
current_hospital['Contact'] = contact
elif 'email' in line.lower() and ':' in line:
email = line.split(':', 1)[1].strip()
current_hospital['Email'] = email
if current_hospital and len(current_hospital) > 0:
hospitals.append(current_hospital)
return hospitals
except Exception as e:
print(f"Error extracting hospital details: {str(e)}")
return []
def save_to_excel(hospitals: List[Dict], filename: str = 'hospitals.xlsx'):
"""
Save hospital details to Excel file.
Args:
hospitals: List of hospital dictionaries
filename: Output Excel filename
"""
if not hospitals:
print("No hospital data to save.")
return
# Ensure all dictionaries have the same keys
columns = ['Name', 'Address', 'Contact', 'Email']
for hospital in hospitals:
for col in columns:
if col not in hospital:
hospital[col] = ''
# Create DataFrame
df = pd.DataFrame(hospitals, columns=columns)
# Save to Excel
df.to_excel(filename, index=False, engine='openpyxl')
print(f"Saved {len(hospitals)} hospital records to {filename}")
def remove_duplicates(hospitals: List[Dict]) -> List[Dict]:
"""
Remove duplicate hospitals based on name and address.
Args:
hospitals: List of hospital dictionaries
Returns:
List of unique hospitals
"""
seen = set()
unique_hospitals = []
for hospital in hospitals:
# Create a unique key from name and address
name = str(hospital.get('Name', '')).strip().lower()
address = str(hospital.get('Address', '')).strip().lower()
key = (name, address)
if key not in seen and name: # Only add if name exists
seen.add(key)
unique_hospitals.append(hospital)
return unique_hospitals
def main():
"""
Main function to extract hospital details and save to Excel.
"""
target_count = 20
location = "Africa"
all_hospitals = []
# List of African countries/regions to search for comprehensive coverage
african_regions = [
"Africa",
"South Africa hospitals",
"Nigeria hospitals",
"Kenya hospitals",
"Egypt hospitals",
"Ghana hospitals",
"Morocco hospitals",
"Ethiopia hospitals",
"Tanzania hospitals",
"Uganda hospitals",
"Algeria hospitals",
"Sudan hospitals",
"Mozambique hospitals",
"Angola hospitals",
"Ivory Coast hospitals",
"Madagascar hospitals",
"Cameroon hospitals",
"Niger hospitals",
"Burkina Faso hospitals",
"Mali hospitals",
"Malawi hospitals",
"Zambia hospitals",
"Senegal hospitals",
"Chad hospitals"
]
print(f"Searching for {target_count} hospitals in {location}...")
print("Collecting data from multiple regions...\n")
hospitals_per_call = 20
call_count = 0
max_calls = 3 # Limit for collecting 20 hospitals
# Try to get hospitals from different regions
for region in african_regions:
if len(all_hospitals) >= target_count:
break
if call_count >= max_calls:
print(f"\nReached maximum API calls limit ({max_calls}). Continuing with collected data...")
break
print(f"Searching in: {region}... (Collected: {len(all_hospitals)}/{target_count})")
try:
hospitals = extract_hospital_details("hospitals", region, hospitals_per_call)
if hospitals:
# Remove duplicates before adding
unique_new = []
existing_names = {str(h.get('Name', '')).strip().lower() for h in all_hospitals}
for h in hospitals:
name = str(h.get('Name', '')).strip().lower()
if name and name not in existing_names:
unique_new.append(h)
existing_names.add(name)
all_hospitals.extend(unique_new)
print(f" Found {len(unique_new)} new hospitals (Total: {len(all_hospitals)})")
call_count += 1
# Small delay to avoid rate limiting
time.sleep(1)
except Exception as e:
print(f" Error searching {region}: {str(e)}")
continue
# Remove any remaining duplicates
all_hospitals = remove_duplicates(all_hospitals)
# Limit to target count
if len(all_hospitals) > target_count:
all_hospitals = all_hospitals[:target_count]
if all_hospitals:
print(f"\nTotal unique hospitals found: {len(all_hospitals)}")
save_to_excel(all_hospitals, '20_africa_hospitals.xlsx')
else:
print("No hospitals found or extraction failed.")
if name == "__main__":
main()
8. Sample Output (Excel)
9. Key Benefits of This Approach
High accuracy for public contact data
Live verification at query time
Reduced hallucination risk
Audit-friendly structured output
No dependency on stored documents or embeddings
10. When to Use Real-Time Search Grounding
Recommended For:
Public directory validation
Compliance and audit workflows
CRM enrichment
Research and data verification
Not Ideal For:
Fully offline systems
Static internal documentation
Latency-critical applications
11. Conclusion
In modern AI systems, trust and verifiability matter more than raw generation ability.
Gemini 3’s real-time search grounding provides a practical, production-ready solution for extracting accurate, up-to-date public information without relying on pre-collected datasets.
This implementation demonstrates how grounded AI can be applied directly to real-world business problems — with outputs that stakeholders can verify, validate, and trust.