Building News-Aware RAG Agents with the Serply News API

Skip the nightly reindex job. Ground your RAG agent in live Google News results so it can actually answer questions about today.

Profile picture of Serply
Serply
Diagram of a RAG pipeline pulling live news entries into an LLM prompt

Ask a standard RAG agent “what happened with the Fed this week” and you’ll usually get one of two answers: a confident-sounding hallucination, or a correct-but-stale summary pulled from whatever got embedded into the vector store three weeks ago. Neither is what you actually wanted.

The problem isn’t the “generation” half of retrieval-augmented generation. It’s the “retrieval” half. Most RAG stacks assume the corpus is static — you chunk some documents, embed them, stuff them in a vector database, and call it a day. That works great for a company wiki or a product manual. It falls apart the moment someone asks about anything time-sensitive, because your index is only as fresh as your last ingestion job.

For current-events questions, the fix isn’t a better embedding model or a smarter chunking strategy. It’s swapping the retrieval step entirely: instead of searching a static index, search the live web. This post walks through building that swap using Serply’s News API, so your agent’s “retrieval” step is a real-time Google News query rather than a lookup against last month’s snapshot.

Why a vector index is the wrong tool for “what’s happening now”

Vector databases are built around a batch mental model: ingest, embed, index, serve. Even with an aggressive pipeline, there’s a floor on freshness:

  • Reindex latency. Nightly or hourly batch jobs mean anything that happened in the last cycle simply isn’t in the index yet.
  • Coverage gaps. You can only embed what you scraped, and you can only scrape what you knew to look for. A vector store can’t answer questions about topics it wasn’t built to anticipate.
  • Staleness masquerading as confidence. This is the dangerous one. The agent doesn’t know its data is three weeks old — it just answers as if it’s current, because nothing in the retrieval step flags recency.

None of this is a criticism of vector search as a technique — it’s still the right choice for stable, slow-changing knowledge (docs, policies, historical reference material). It’s just the wrong tool for “did anything change today,” which is precisely the question current-events RAG has to answer.

Live search as the retrieval step

The core idea is simple: RAG doesn’t require a vector database. It requires some retrieval mechanism that returns relevant context, which the LLM then reasons over. A live news search satisfies that requirement — arguably better than a vector index does, for this specific class of question, because there’s no ingestion lag at all. The “index” is Google News itself, updated continuously by people who aren’t you.

Here’s the endpoint that does the retrieval:

GET https://api.serply.io/v1/news/{query}

A few things worth knowing about how this endpoint works, since it’s slightly different from a typical REST API:

  • The query string goes in the URL path, URL-encoded — not as ordinary ?key=value parameters after a ?. So a search for “interest rates” filtered to US English becomes /v1/news/q=interest+rates&ceid=US:en, not /v1/news?q=interest+rates.
  • Authentication is a required X-Api-Key header. See the authentication guide for how to get a key.
  • You can optionally set X-Proxy-Location (geographic proxy region) and X-User-Agent (desktop or mobile) as headers.
  • The ceid parameter (e.g. US:en) controls country and language, and can be combined with q= in the same path-embedded query string.

The response looks like this:

{
  "feed": {
    "title": "\"interest rates\" - Google News",
    "generator": "NFE/5.0",
    "link": "https://news.google.com/...",
    "language": "en-US",
    "publisher": "Google News",
    "updated": "Sun, 16 Aug 2026 14:02:00 GMT",
    "entries": [
      {
        "title": "Fed holds rates steady, signals cautious path ahead",
        "link": "https://example.com/article",
        "summary": "The Federal Reserve left interest rates unchanged on Wednesday...",
        "published": "Sun, 16 Aug 2026 12:30:00 GMT",
        "source": "Example News"
      }
    ]
  },
  "entities": [
    { "title": "Federal Reserve", "links": ["https://example.com/topic/fed"] }
  ]
}

feed.entries is the part that matters for retrieval — a list of recent articles with a title, link, short summary, publish timestamp, and source outlet.

Wiring it into a RAG prompt

Instead of embedding query → vector search → top-k chunks, the pipeline becomes: user question → live news search → format entries as context → hand to the LLM. Here’s a minimal Python implementation:

import requests
from datetime import datetime

SERPLY_API_KEY = "YOUR_API_KEY"

def get_recent_news(query, ceid="US:en", limit=5):
    """Fetch recent news entries for `query` as compact RAG context."""
    encoded_query = requests.utils.quote(query)
    url = f"https://api.serply.io/v1/news/q={encoded_query}&ceid={ceid}"
    headers = {"X-Api-Key": SERPLY_API_KEY}

    response = requests.get(url, headers=headers)
    response.raise_for_status()
    data = response.json()

    entries = data.get("feed", {}).get("entries", [])[:limit]

    context_blocks = []
    for entry in entries:
        context_blocks.append(
            f"- [{entry.get('published', 'unknown date')}] "
            f"{entry.get('title', '')} ({entry.get('source', 'unknown source')})\n"
            f"  {entry.get('summary', '')}\n"
            f"  Source: {entry.get('link', '')}"
        )

    return "\n".join(context_blocks)


def answer_with_live_news(question, query_for_news=None):
    """Ground an LLM answer in live news search instead of a static index."""
    search_query = query_for_news or question
    news_context = get_recent_news(search_query)

    prompt = f"""You are a news-aware assistant. Answer the user's question using
only the news context below. If the context doesn't contain enough
information to answer confidently, say so explicitly rather than guessing.

Retrieved news context (as of {datetime.utcnow().isoformat()}Z):
{news_context}

Question: {question}

Answer:"""

    # Pass `prompt` to your LLM of choice here.
    return prompt

That’s the whole pattern. get_recent_news is your retrieval function — it just happens to hit a live search API instead of vector_store.similarity_search(). Everything downstream (prompt assembly, calling the LLM, parsing the answer) stays exactly the same as any other RAG setup. If you’re using a framework like LangChain or LlamaIndex, this slots in as a custom retriever or tool call — the interface (query in, ranked text chunks out) is unchanged, only the implementation swaps from an index lookup to an HTTP call.

When a summary isn’t enough

News entries only give you a short summary — usually a sentence or two, not the full article. Most of the time that’s plenty of context for an LLM to answer a question accurately. But if you need deeper grounding (direct quotes, specific numbers buried three paragraphs in, methodology details), you can follow a result’s link with the Request endpoint to pull the full article as clean markdown:

def get_full_article(article_url):
    response = requests.post(
        "https://api.serply.io/v1/request",
        headers={"X-Api-Key": SERPLY_API_KEY, "Content-Type": "application/json"},
        json={"url": article_url, "response_type": "markdown"},
    )
    return response.text  # plain markdown, not JSON-wrapped

Treat this as a second-pass tool the agent reaches for when the news summary alone doesn’t answer the question — not something you run on every result by default, since fetching and converting full pages is naturally slower than reading a feed summary.

Combining live and static retrieval

None of this means throwing away your vector store. The realistic architecture for most production agents is a router that picks the retrieval source based on the question:

  • Questions about stable knowledge (your product docs, historical facts, internal policy) → vector search.
  • Questions with an implicit “as of now” (prices, breaking news, “did X happen”) → live news search via /v1/news.
  • Questions needing full source text, not just a summary → follow up with /v1/request.

A simple heuristic — keyword triggers like “today,” “this week,” “latest,” “currently,” or a lightweight classifier — is usually enough to route between the two without over-engineering it.

Wrapping up

Freshness is a retrieval problem, not a generation problem — no amount of prompt engineering fixes an agent that’s reasoning over three-week-old context. For anything current-events-shaped, point your RAG pipeline at Serply’s News API instead of (or alongside) your vector index, and let Google’s own continuously-updated index do the freshness work for you. Grab an API key at serply.io and try wiring get_recent_news into whatever agent framework you’re already using — the integration is a single HTTP call, not a rewrite.