RAG with Live Web Data: When to Skip the Vector Store
You can skip the vector store for any question whose answer changes faster than you can re-index it: prices, rankings, news, availability. Instead of retrieving from an index, the agent makes one API call per question and passes the results to the model as context. A Google Search lookup through Perceptlayer costs 1 credit per successful call. Keep the vector store for stable, private or high-volume material.
What does RAG with live web data actually change?
Retrieval-augmented generation, as described in the original 2020 paper from Lewis et al., pairs a language model with a retriever that fetches relevant passages at question time. The retriever is usually a vector index you built earlier. With live web data, the retriever is an API call made at the moment of the question, so the "index" is the web itself.
The generation step doesn't change. You still put retrieved text into the prompt and ask the model to answer from it. What changes is where the text comes from and when it was collected. A vector store holds what you ingested last week. A live call returns what the source showed at the time of the call, which is the only freshness promise the data carries.
That difference moves cost and failure modes, not just freshness. An index costs you storage, an embedding job and a refresh schedule. A live call costs credits per question and depends on the network at answer time.
Which questions belong in the index, and which need a fresh call?
Sort questions by how long the answer stays true and who owns the source. If the answer is stable, private or yours, index it. If it lives on a public website and changes daily, fetch it per query. Most agents need both, and the router between them is a few lines of logic, not a framework.
| Question type | Example | Where it belongs | Why |
|---|---|---|---|
| Your own documents | "What does our refund policy say?" | Vector store | Private, stable, and not on the public web |
| Slow-changing reference | "How does OAuth device flow work?" | Vector store or model memory | Answer rarely changes, so the ingest cost pays off |
| Rankings and search results | "Who ranks for this query today?" | Live call | The answer is the current result page |
| Prices and availability | "Is this product in stock?" | Live call | Stale within hours, sometimes minutes |
| News and events | "What happened to this company this week?" | Live call | An index is out of date by the time it's built |
| Long-tail public questions | "Best restaurants in Berlin right now" | Live call | Too many possible questions to pre-index |
The last row matters most for cost. You can't embed the whole web in advance, so open-ended public questions either hit a live source or get a stale guess.
How does a per-query live lookup work?
A per-query lookup is one authenticated HTTP request whose response goes straight into the prompt. For general web questions, GET /v1/google-search/search takes a required query and returns organic results, related questions and local results as JSON. It costs 1 credit on success, and the key goes in the X-API-Key header.
Here is the request, run against a recorded example:
curl "https://api.perceptlayer.com/v1/google-search/search?query=best+restaurants+in+Berlin&hl=en&safe=off" \
-H "X-API-Key: $API_KEY"
A trimmed excerpt of the recorded response:
{
"search_information": {
"query_displayed": "best restaurants in Berlin",
"organic_results_count": 6
},
"organic_results": [
{
"position": 2,
"title": "Restaurants - Berlin",
"link": "https://guide.michelin.com/us/en/berlin-region/berlin/restaurants",
"snippet": "Berlin and surroundings: 1-48 of 79 restaurants · POTS · Rutz · GOLVET · …",
"source": "MICHELIN Guide"
}
],
…
}
Each organic result has a title, a link, a snippet and a source. That's enough for a model to answer and cite where the claim came from. The search endpoint also takes hl and gl for language and country, location for a place, and page for further results. The Google Search API page lists all seven endpoints, and the Google Search API JSON guide walks through the response fields.
The retriever in Python
The retriever is a function that takes the user's question and returns a context block with sources. Keep it small, read the credit headers, and let HTTP errors raise.
import os
import requests
SEARCH_URL = "https://api.perceptlayer.com/v1/google-search/search"
def live_context(question: str, max_results: int = 5) -> str:
resp = requests.get(
SEARCH_URL,
params={"query": question, "hl": "en"},
headers={"X-API-Key": os.environ["API_KEY"]},
timeout=30,
)
resp.raise_for_status()
used = resp.headers.get("X-Credits-Used")
remaining = resp.headers.get("X-Credits-Remaining")
print(f"credits used: {used}, remaining: {remaining}")
lines = []
for item in resp.json().get("organic_results", [])[:max_results]:
lines.append(f"- {item['title']} ({item['link']}): {item['snippet']}")
return "\n".join(lines)
prompt = (
"Answer using only the search results below. "
"Cite the link for each claim.\n\n"
+ live_context("best restaurants in Berlin")
+ "\n\nQuestion: Which restaurants in Berlin are worth booking?"
)
Send prompt to your model of choice. The model sees titles, links and snippets, so it can name its sources. The snippets are short, so for questions that need a full page's text you'd add a second step that reads the linked pages.
What does a live lookup cost per question?
Each successful call costs 1 credit, so cost scales linearly with questions that reach the live path, and only those. 10,000 live lookups use 10,000 credits. A router that sends only the volatile questions to the API cuts that figure without touching answer quality.
| Live lookups per month | Credits | Smallest pack that covers it |
|---|---|---|
| 1,000 | 1,000 | Free monthly credits |
| 10,000 | 10,000 | Starter (10,000 credits) |
| 100,000 | 100,000 | Growth (200,000 credits) |
The arithmetic is 10,000 calls × 1 credit = 10,000 credits, which is exactly the Starter pack's 10,000. Every account gets 1,000 free credits a month after verifying an email, no card needed, so the first 1,000 lookups cost nothing. The pricing page shows what each pack costs. Purchased credits last 12 months, and the service is prepaid: when the balance runs out, calls return insufficient_credits (402) and nothing more is debited.
Compare that with the index path, where the costs are different in kind: an embedding job per refresh, storage for the vectors, and the engineering time to keep the pipeline running. Neither side is free. The live path is a variable cost that tracks usage, which suits an agent whose traffic is hard to predict. For capping that spend, see AI agent API cost control.
What is the honest downside of skipping the index?
Latency is the main one. A live lookup adds a network round trip to a source on the public web before the model can start generating, while a vector query against a nearby index is typically a local operation. We don't publish a latency figure for these endpoints, so measure the p50 and p95 in your own environment, from where your agent runs, before deciding.
Other limits are worth knowing before you build:
- Rate limits. Rate-limited (429) and temporarily unavailable (503) responses carry a
Retry-Afterheader with the seconds to wait. Back off by that amount. - Timeouts can still bill. Requests have no idempotency key, so a request whose reply was lost may have succeeded and been charged. Retry web API calls without paying twice covers the pattern.
- No ranking over your own data. A search call can't rank your internal documents. That's the index's job.
- Repeated questions. If many users ask the same thing within minutes, a short-lived cache removes the repeat charges. The response caching guide shows TTLs and the credit savings.
Data is returned as found at the time of the call. It's collected from publicly available sources, so treat it as evidence for the model to cite, not as ground truth.
Where does a vector store still win?
A vector store wins whenever the corpus is yours, stable and queried often. Internal docs, support history, contracts and code don't exist on the public web, so no search call can find them. Semantic search over a fixed corpus is also cheap per query once the index exists, and the latency is predictable.
It also wins on volume with repetition. If you answer the same 500 questions a million times, paying per call is the wrong shape and an index, or a cache in front of the live call, is the right one. And it wins when you need control over exactly which passages the model may see, such as for compliance review.
The practical pattern is hybrid. Index what you own, call live for what the web owns, and let a small router pick per question. If your agent uses the Model Context Protocol, the Perceptlayer MCP server exposes search_endpoints, get_endpoint and call_endpoint as tools, so the model can decide when to make the live call itself. The MCP vs function calling comparison explains when each wiring fits.
To try the live path, get a free API key and run the search call above in the playground on the Google Search API page before you write any retriever code.
APIs in this post
Frequently asked questions
Can I use live web data and a vector store together?
Yes, and most production agents should. Route each question: private or stable material goes to the index, volatile public facts go to a live call. Both results land in the same prompt as labelled context blocks. The router can be a rule or a model decision, such as an MCP tool the model chooses to call.
How many credits does one live lookup use?
One successful call to the Google Search endpoints costs 1 credit. Failed calls cost nothing and return X-Credits-Used: 0. Every successful response also carries X-Credits-Used and X-Credits-Remaining, so you can log the balance after each call. See credits in the docs for the full rules.
What happens when a live call fails?
You get an HTTP status and a JSON body with error.code, error.message and error.request_id. Codes include rate_limited (429), source_error (502) and temporarily_unavailable (503). Failures aren't billed. Wait for the Retry-After seconds on 429 and 503 before retrying. The errors section lists every code.
Is live retrieval slower than a vector store?
Usually, yes. A live call crosses the network to a public source, while a vector query against a nearby index is typically faster. There's no published latency figure for these endpoints, so time it from where your agent runs. If the extra delay is too much, cache repeated questions or reserve live calls for queries that need them.
Does this replace a scraper I maintain?
For public search results, it can, because the endpoint returns JSON fields instead of HTML you have to parse and keep in step with page changes. See what maintaining a scraper involves for the trade-offs, including cases where owning the scraper still makes sense.