Skip to main content
A model alone can’t answer questions about events after its training cutoff, or cite a source. The fix is grounding: retrieve relevant web content at request time and pass it to the model as context. This guide shows the pattern using Novita AI Search for retrieval and the LLM API for synthesis — all behind one API key.

What is RAG?

Retrieval-augmented generation (RAG) is the pattern behind every grounded answer here: instead of relying on what the model memorized during training, you retrieve relevant documents at request time and augment the prompt with them, so the model generates its answer from that fresh, verifiable context. That retrieval step is exactly what AI Search provides. The web becomes your knowledge base, and you don’t have to build or maintain a vector database to get started — a search call returns the passages, and the LLM does the rest. When you later want retrieval over your own private documents, the same three-step shape applies; you just swap web search for a vector store. RAG buys you three things a bare model can’t offer:
  • Freshness — answers reflect content published after the model’s training cutoff.
  • Attribution — every claim can point back to a source URL the user can check.
  • Reduced hallucination — grounding the model in retrieved text keeps it from inventing facts.

How grounding works

A single RAG turn follows three steps:
  1. Search (retrieve) the web for pages relevant to the question.
  2. Extract (augment) the content you need — snippets or full page text — into the prompt.
  3. Synthesize (generate) an answer by passing that content to an LLM, asking it to cite sources.
You can do this with two calls (search + LLM) or even one, since both Exa and Tavily can synthesize an answer for you. Choose based on how much control you need over the final wording and citations.

Let the provider write the answer

The fastest path. Tavily’s Search returns an LLM-generated answer when you set include_answer, and Exa offers a dedicated Answer endpoint. One call, no orchestration.
Use this when you want a good answer with minimal code. Reach for the retrieve-then-synthesize approach below when you need control over the model, tone, output format, or how citations are presented.

Retrieve, then synthesize with an LLM

This gives you full control. Search for sources, then hand the results to the LLM API with instructions to answer using only that context and to cite each claim.
The same flow works with Exa Search — swap the route to /v3/exa/search and read text from each result instead of raw_content.

Tuning retrieval quality

The quality of a grounded answer depends far more on what you retrieve than on the model. A few high-impact knobs:
  • Freshness. For time-sensitive questions, constrain by date. Tavily exposes time_range and start_date/end_date; Exa exposes startPublishedDate/endPublishedDate. This keeps stale pages out of the context.
  • Source trust. Use include_domains/excludeDomains to restrict retrieval to sources you trust (official docs, reputable publishers) and to keep out low-quality sites.
  • Topic hints. Tavily’s topic (news, finance, general) and Exa’s category steer the engine toward the right kind of result.
  • Right-sizing context. Cap extracted text (Tavily chunks_per_source, Exa maxCharacters) so you pass enough signal without blowing the model’s context window or your token budget.

Search vs. extract vs. crawl

Pick the retrieval primitive that matches your need:
  • Search — you have a question and need to discover relevant pages. The default starting point.
  • Extract / Contents — you already know the URLs and want clean text from them. Good for grounding on a fixed set of documents. See Tavily Extract and Exa Contents.
  • Crawl / Map — you want to ingest a whole site or section, following links. Good for building a knowledge base offline. See Tavily Crawl and Tavily Map.
For a fuller agent that searches iteratively and reasons over many sources, see the DeepSearcher integration.

Taking it to production

  • Handle empty results. If search returns nothing relevant, have the model say it can’t answer rather than inventing one. The system prompt above does this.
  • Cache when you can. Identical queries return similar results; caching retrieval cuts cost and latency.
  • Mind rate limits. Retrieval and LLM calls are limited separately — a search request doesn’t draw down your LLM quota. Back off on 429 for either. See LLM rate limits for the LLM side.
  • Keep keys server-side. Your Novita key authenticates every call here — never ship it in client-side code.
Last modified on July 15, 2026