Tutorial

July 20, 2026 · 7 min read

Give Your AI Agent Live Web Search: Grounding LLM Answers

Models answer from a world that no longer exists. The fix is the fetch-then-cite pattern: query live web search at answer time, hand the model the results, require citations. About 40 lines of code, demonstrated end to end.

Adam Ben-Ayoun

Author

Adam Ben-Ayoun

CTO · OpenWeb Ninja

Web Search · LLM · RAG · AI Agents · Python

Key Takeaways

  • Grounding beats fine-tuning for freshness: give the model fresh evidence at answer time instead of teaching it facts that will expire.

  • The whole pattern is: search, build a numbered-sources prompt, instruct the model to answer only from those sources and cite [n].

  • Search with a rewritten keyword query, not the raw conversational message; retrieval quality follows query quality.

  • Constrain citations to links you supplied and validate them; that is what makes citations trustworthy instead of decorative.

  • Snippets tell you where to read, not everything to read; fetch the winning pages when depth matters.

  • A search call took about 2 seconds in our tests; 300 grounded answers a day runs about $22.50 a month of search on the Pro plan.

Grounding LLM answers with live web search

The problem is the training cutoff

Ask a model anything that happened after its training cutoff and it does one of two things: admits it does not know, or answers confidently from a world that no longer exists. Neither is acceptable in a product. The fix is neither fine-tuning nor a bigger model; it is giving the model fresh evidence at answer time.

Several of our highest-volume Real-Time Web Search API customers are AI products and agencies doing exactly this: their agents call a SERP API at question time, read the top results, and answer with citations. The whole pattern fits in one small file.

1. Question

Take the user’s question.

2. Search

Query live web search for it. One GET request.

3. Context

Hand the model the top N results: title, snippet, URL.

4. Cite

Instruct it to answer only from that context and cite sources.

The fetch-then-cite pattern

Two functions: one fetches organic results, one turns them into a grounded prompt with numbered sources.

Python

# grounded_search.py
import requests

API_KEY = "YOUR_API_KEY"

def search(q, num=10, gl="us", hl="en"):
    r = requests.get(
        "https://api.openwebninja.com/realtime-web-search/search",
        headers={"x-api-key": API_KEY},
        params={"q": q, "num": num, "gl": gl, "hl": hl},
        timeout=60,
    )
    r.raise_for_status()
    return r.json()["data"]["organic_results"]

def grounded_prompt(question, results):
    sources = "\n".join(
        f"[{r['rank']}] {r['title']}\n    {r['url']}\n    {r['snippet']}"
        for r in results
    )
    return f"""Answer the question using ONLY the sources below.
Cite sources inline as [n]. If the sources do not contain the answer, say so.

Sources:
{sources}

Question: {question}
Answer:"""

if __name__ == "__main__":
    question = "What changed in EU AI Act enforcement in 2026?"
    print(grounded_prompt(question, search(question)))

Response (truncated, real capture)

Each organic result is small and citation-ready:

{
  "status": "OK",
  "data": {
    "organic_results": [
      {
        "rank": 1,
        "title": "AI Act | Shaping Europe's digital future - European Union",
        "url": "https://digital-strategy.ec.europa.eu/en/policies/regulatory-framework-ai",
        "domain": "digital-strategy.ec.europa.eu",
        "snippet": "The AI Act entered into force on 1 August 2024, and will be fully applicable 2 years later on 2 August 2026, with some exceptions: prohibited AI practices and ..."
      },
      {
        "rank": 2,
        "title": "AI Act Update: EU Resolves to Change Rules and Extend ...",
        "url": "https://www.lw.com/en/insights/ai-act-update-eu-resolves-to-change-rules-and-extend-deadlines",
        "domain": "www.lw.com",
        "snippet": "EU lawmakers have agreed to reduce overlap of rules, introduce new prohibitions, and extend deadlines for high-risk AI systems."
      }
    ],
    "has_ai_overviews": false
  }
}

Feeding it to a model

The prompt is model-agnostic; pipe it into whatever you run. We used the Claude Code CLI, which makes the whole demo two commands:

python3 grounded_search.py > prompt.txt
claude -p "$(cat prompt.txt)"

Answer (excerpt)

Several significant changes hit EU AI Act enforcement in 2026, driven largely
by an EU decision to amend the original timeline:

**Timeline restructuring (the "Omnibus" amendments).** EU lawmakers agreed to
reduce overlap of rules, introduce new prohibitions, and extend deadlines for
high-risk AI systems [2]. ... high-risk deadlines moved to 2027 while GPAI and
transparency rules still take effect August 2 [4] ...

**The 2 August 2026 milestone.** Under the original schedule, the Act - which
entered into force on 1 August 2024 - was to become fully applicable on
2 August 2026, with some exceptions [1]. ...

In short: 2026 was supposed to be the year the Act became fully applicable,
but the EU rewrote the timeline [2][4][6][10].

Every claim carries a bracketed citation that maps to a URL from the live search. Without the sources, the model can only answer from its training-data picture of the AI Act, and post-cutoff questions like this are exactly where that picture cannot be trusted. Closing that gap is the whole argument for grounding. If you call a model by API instead of the CLI, grounded_prompt() returns the string to drop into your messages array unchanged.

Design notes from production use

Query rewriting

Search with the model’s reformulated query, not the raw user message; conversational phrasing retrieves worse than keyword phrasing. A cheap first LLM call ("rewrite this as a search query") pays for itself.

Freshness controls

The tbs parameter supports time-bounded search; restrict to the last week or month when the question implies recency.

Answer-first sources

The people-also-ask endpoint and AI Overviews fetching (fetch_ai_overviews=true) can short-circuit simple questions before you spend LLM tokens.

When to skip search

Classify first; not every message needs retrieval, and each skipped call saves latency and quota.

Limitations

Snippets are not full pages. For deep reading, follow the winning links and fetch their content; the SERP tells you where to read, not everything to read. When a page blocks plain requests, the Web Unblocker API fetches it for you.

What it costs

A search call took about 2 seconds in our tests, well inside an agent loop's budget. At $25/month for 10,000 requests (Pro), an assistant answering 300 grounded questions a day runs about $22.50 of search. Pay As You Go is $0.005 per request with no monthly fee, and the free plan covers a prototype. The same pipeline also works with the Google AI Mode API if you would rather ground answers in Google's AI Mode responses than in classic search results.

FAQ

Most common questions and answers

Is this workflow considered RAG?

How do I avoid hallucinated citations?

Does this work with any LLM?

Can agents ground answers per country and language?

About the author

Adam Ben-Ayoun

Adam Ben-Ayoun

CTO @ OpenWeb Ninja

Adam leads engineering at OpenWeb Ninja, building the APIs and infrastructure that make public web data accessible to developers and AI agents.

Connect on LinkedIn

Ground your agent's answers

The Real-Time Web Search API returns live organic results in about 2 seconds, with AI Overviews and People Also Ask on tap. The free plan needs no credit card.

APIs by Category

Didn't find the API you are looking for? Request an API

© 2026 OpenWeb Ninja. All rights reserved.

G2 LogoTrustpilot LogoGitHub