HugoCurio.

Why website chatbots hallucinate (and why "I don't know" is the fix)

September 1, 2026

Nearly every "chat with your website" bot has the same failure mode: ask it something your site doesn't cover, and instead of saying so, it invents a confident, plausible, wrong answer. For a marketing gimmick that's annoying. For a bot answering questions about your pricing, your returns policy, or your medical FAQ, it's a liability.

The thing worth internalizing: this is almost never a model problem. It's a retrieval-and-refusal problem. A bigger model won't save you.

The model is built to be fluent, not honest. An LLM's job, absent other instructions, is to produce a plausible continuation -- and plausible and true are different things. Handed a question with no relevant context, it will happily generate something that reads like an answer, because that's what it was trained to do. There's no built-in "I don't have this" reflex. You have to engineer one.

Retrieval is the real bottleneck. Most of these tools are RAG: embed your pages, retrieve the nearest chunks, stuff them in the prompt, generate. Hallucination usually starts before the model writes a word -- the relevant passage never got retrieved (the visitor phrased it differently than your page did, or chunking split the answer from its context), or nothing relevant exists but the system generates anyway. Whatever lands in the context window, the model treats as ground truth. Give it noise and it grounds a confident answer in noise.

Scraping poisons the corpus. Rendered HTML is mostly not your content -- it's nav, footers, cookie banners, "related posts," ad slots. Scrape it and all of that gets chunked and embedded, so a query retrieves your footer and the "answer" is grounded in boilerplate. Ingesting structured content instead (a REST API, uploaded docs) and stripping the chrome is unglamorous and matters more than the model choice.

Chunking quietly destroys meaning. Fixed-size chunks split a definition from its qualifier, a table from its header, a question from its answer. The retrieved chunk is "relevant" and incomplete, so the model fills the gap with a guess. Splitting on semantic boundaries (headings, sections) and keeping the heading with its body helps more than people expect.

Your model already "knows" things about your topic. Ask a bot on a plumbing site a general plumbing question its pages don't cover, and it answers from parametric memory -- presenting general internet knowledge as if it came from your site. The visitor can't tell. For anything factual, policy, or price-related, that's the dangerous case, and it needs an explicit rule: answer only from what was retrieved, not from what you already know.

Confidence is uncalibrated. The model uses the same self-assured tone whether it's quoting your docs or inventing. A wrong answer looks exactly as trustworthy as a right one.

What actually reduces it -- none of it a bigger model:

  • Make refusal first-class. If retrieval is empty or below a relevance floor, say "I don't have that" and point to a human. The willingness to decline isn't a bug to paper over; it's the whole value of a factual assistant.
  • Require citations, as a forcing function. Make the model cite the source chunk for every claim. It can't cite what it didn't retrieve, which makes fabrication harder -- and lets the user verify. If it can't cite it, it shouldn't say it.
  • Clean the corpus, chunk on structure. Retrieval quality is downstream of corpus quality.
  • Wall off parametric knowledge and verify the output. Answer only from retrieved content for the site's domain, and check the reply against the sources deterministically -- a guard that doesn't rely on the model's own judgment.

The mindset shift underneath all of it: a grounded assistant should be useful-and-boring, not impressive-and-wrong. Users trust the bot that says "I don't know" far more than the one that's confidently incorrect -- and the confident one eventually says something that earns you a chargeback.

The uncomfortable version: most "hallucination" in these products is a design choice. Somewhere a prompt says "be helpful," retrieval has no floor, and there's no refusal path -- so the bot guesses. It's fixable, and the fix is discipline, not scale.

(Disclosure: I build one of these, Curio. This is the discipline it enforces -- grounding, required citations, and refusal on empty retrieval. I wrote this because the pattern is everywhere and worth naming.)

← All posts