Grounding chatbots with live data

Stop your assistant from confidently making things up.

For

Customer support tools, internal copilots, branded AI assistants — anywhere a chatbot answers questions where being wrong damages the brand.

The pain

Without a real retrieval layer.

Without grounding, an LLM will hallucinate an answer that sounds right and ships your user to a broken page. With shallow grounding, the bot says "I don't have current info" and frustrates users. Real-time retrieval is the difference between "trustworthy assistant" and "expensive mistake generator."

With SiftQ

One call, the right shape.

A SiftQ call before generation gives your chatbot fresh, scored, citation-ready context. Pair it with a strict prompt ("answer only from the sources") and your assistant becomes verifiable.

Recommended config

Start with this shape.

scopewebpage (or news for time-sensitive domains)
size5
optionsconciseSnippet=true · Fast mode (default)
Working code

Paste, run, ship.

TypeScript — Streaming grounded chatbot
import Anthropic from "@anthropic-ai/sdk";

const claude = new Anthropic();

async function search(q: string) {
  const r = await fetch("https://api.siftq.com/v1/search", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.SIFTQ_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ q, scope: "webpage", size: "5", conciseSnippet: true }),
  });
  const { webpages = [] } = await r.json();
  return webpages;
}

export async function answer(userMessage: string) {
  const hits = await search(userMessage);
  const sources = hits
    .map((h: any, i: number) => `[${i + 1}] ${h.title}\n${h.snippet}\nSource: ${h.link}`)
    .join("\n\n");

  return claude.messages.stream({
    model: "claude-sonnet-4-6",
    max_tokens: 1024,
    system:
      "Answer ONLY from the SOURCES. Cite as [N]. If sources don't contain the answer, say so.",
    messages: [
      { role: "user", content: `SOURCES:\n${sources}\n\nQUESTION: ${userMessage}` },
    ],
  });
}
Why SiftQ for this
FAQ

Likely questions.

Do I need to retrieve on every message, or only on factual questions?

Only on factual / lookup turns. Use a small classifier (3-line prompt) or a heuristic (does the message contain a "?" + factual keywords?) to skip retrieval for chit-chat.

How do I prevent the bot from making up answers when retrieval fails?

Strict system prompt that lists the source-cited answer as the only allowed format, plus an explicit "If you cannot answer from the sources, say I don't know." instruction. Then verify by removing all sources at test time — the bot should refuse, not invent.

How do I show citations to the user?

Most teams render inline `[1]` `[2]` markers as clickable links to the source URL. Some add a "Sources" footer with full link list. Either works; consistency matters more than format.

Keep reading
Use case
Web search for RAG applications
Ground your LLM in the live web — not a stale training cutoff.
Use case
Search for autonomous research agents
Give your agent a primitive it can call dozens of times per task.
Glossary
Web grounding
Forcing an LLM's answer to cite fresh, retrievable web sources rather than hallucinating from training data.
Glossary
Citation
A link or reference back to the source from which an LLM-generated claim was derived.
Glossary
RAG (Retrieval-Augmented Generation)
A pattern where an LLM is given relevant retrieved context at inference time rather than relying solely on its training data.

Try it on your
real workload.

The free tier covers most prototypes. No credit card.