Query Fan-Out

Sometimes, despite all the complexity, all you really need is a small script or snippet to call the Gemini API.

For Query Fan-Out, I recommend using Google AI Studio. Just tell it exactly what you want. Here’s a prompt example that will give you a functional app to retrieve query fan out for a specific page:

Given a URL, you will:
Fetch and read the page content (title, headings, body).
Identify the main entity or topic the page is about.
Propose 3–5 focused search queries you would use for grounded search about that entity.
Run grounded search and return all grounding metadata for the top results.
Produce a concise JSON that follows the exact schema below.
Rules
Be precise: one primary entity/topic only.
Keep “related_queries” short (≤10 words each), entity-centric, and non-duplicative.
Grounding metadata must include canonical URIs when possible and avoid duplicates.
If the URL is unreachable or empty, return a graceful error object using the same schema fields you can populate.


You can also experiment in Google Colab or a Jupyter Notebook using Claude Code.

I’ve added another Python excerpt below for reference:

from google import genai
from google.genai.types import Tool, GenerateContentConfig, GoogleSearch, UrlContext, GroundingMetadata

client = genai.Client(api_key="Your_GeMiNi_API_KEY_HERE")
model_id = "gemini-2.5-flash"

tools = [
      {"url_context": {}},
      {"google_search": {}},
  ]

#Your page goes here:
url = "https://www.beulahlondon.com/collections/velvet-dresses"

response = client.models.generate_content(
    model=model_id,
    contents=f"Analyze the content of the webpage at: {url}. Identify the primary product category or topic (generic, without brand names). Then, generate 3-5 semantically related search queries as a numbered list, one query per line. Put the most semantically related query first.",
    config=GenerateContentConfig(
        tools=tools,
    )
)

# Extract semantically related queries from the response
related_queries = []
if response.candidates[0].content.parts:
    response_text = response.candidates[0].content.parts[0].text
    # Parse the response to extract individual queries
    lines = response_text.strip().split('\n')
    for line in lines:
        # Remove numbering and clean up the line
        cleaned_line = line.strip()
        # Remove common list markers (1., 2., -, *, etc.)
        import re
        query = re.sub(r'^[\d\.\-\*\)]+\s*', '', cleaned_line)
        if query and len(query) > 3:  # Filter out empty or very short lines
            related_queries.append(query)

# Display the results
if related_queries:
    print(f"Here is the most semantically related search query: {related_queries[0]}")
    print(f"\nAll {len(related_queries)} semantically related search queries:")
    for i, query in enumerate(related_queries, 1):
        print(f"{i}. {query}")
    
    # Get grounding metadata for each related query
    for idx, query in enumerate(related_queries, 1):
        print(f"\n{'='*60}")
        print(f"Query {idx}: {query}")
        print('='*60)
        
        response_entity = client.models.generate_content(
            model=model_id,
            contents=f"Find information about: {query}",
            config=GenerateContentConfig(
                tools=tools,
            )
        )

        print(f"\nGrounding Metadata:")
        if response_entity.candidates[0].grounding_metadata:
            if hasattr(response_entity.candidates[0].grounding_metadata, 'web_search_queries') and response_entity.candidates[0].grounding_metadata.web_search_queries:
                print("  Web Search Queries:", response_entity.candidates[0].grounding_metadata.web_search_queries)
            if hasattr(response_entity.candidates[0].grounding_metadata, 'grounding_chunks') and response_entity.candidates[0].grounding_metadata.grounding_chunks:
                print(f"  Number of Grounding Chunks: {len(response_entity.candidates[0].grounding_metadata.grounding_chunks)}")
                for i, chunk in enumerate(response_entity.candidates[0].grounding_metadata.grounding_chunks[:3], 1):  # Show first 3
                    if hasattr(chunk, 'web') and chunk.web:
                        print(f"    Chunk {i}: {chunk.web.title}")
                        print(f"            {chunk.web.uri[:100]}...")
            if hasattr(response_entity.candidates[0].grounding_metadata, 'searchEntryPoint') and response_entity.candidates[0].grounding_metadata.searchEntryPoint:
                print("  Search Entry Point:", response_entity.candidates[0].grounding_metadata.searchEntryPoint)
        else:
            print("  No grounding metadata found for this query.")
else:
    print("Could not extract related queries from the response.")


Ultimately, Google Gemini seems to be the only API currently making large-scale LLM search-ground access available; not sure why others haven’t followed suit yet.

Remember to adjust the scripts to your needs.

https://ai.google.dev/gemini-api/docs/google-search

https://cloud.google.com/vertex-ai/generative-ai/docs/grounding/overview

https://blog.google/products/search/google-search-ai-mode-update/

Previous
Previous

Notion Blog with AI Translation

Next
Next

AI Won't Replace You