All posts
In-product AI··6 min read

Your AI assistant is not hallucinating, your own pages disagree

The widget on our own site claimed Command+K supports BYOK, a capability we removed after a pricing audit. It was not a hallucination. Eight customer-facing pages mentioned BYOK and exactly one said we do not support it, so retrieval returned the majority and the model answered with the version that sells. Here is how to tell a real hallucination apart from a contradiction you published, why one correct FAQ page cannot fix it, and the test we added so the next retirement cannot ship half-done.

⌘
Orhan
Founder

Our product tester asked the widget on our own site a procurement question: can I bring my own LLM keys? The widget answered that Command+K supports BYOK, for teams who need it for compliance reasons. That is false. We removed BYOK after a pricing audit, and our docs say so in plain words.

My first instinct was the usual one. The model made something up, so tighten the prompt and add a rule telling it not to invent capabilities. That instinct would have wasted the day, because the model did not invent anything. It read what we published.

Eight pages, one of them telling the truth

Our site indexes itself, so the assistant on commandplusk.com answers from our own published pages. That meant the question was not "why did the model lie" but "what did the model retrieve". So instead of opening the one docs page that owns the topic, we grepped every customer-facing file for the term.

Eight files mentioned BYOK. Exactly one of them said we do not support it, and it was the FAQ entry on /docs/monetize/overview that we had been quoting to ourselves as proof the docs were correct. Here is what the other seven said:

  • A blog FAQ answered "Can I keep my own models?" with "Yes. BYOK or use the managed gateway." An outright false product claim, in our own voice, in a block that also emits FAQPage structured data.
  • The meta description of /product/monetize promised "bring your own AI keys", which is the snippet a search engine shows before anyone reads a word of the page.
  • An internal cross-link labelled "Bring your own model keys" pointed at a docs page that documents managed prepaid inference and nothing else. The label promised the capability and the destination quietly did not deliver it.
  • Four monetization essays discussed BYOK as a reasonable idea for SaaS teams, with nothing in the text marking it as advice about the reader's product rather than a description of ours.

Why retrieval picks the sales answer

Those four essays are the interesting part, because none of them is wrong. They are vendor-neutral advice, and they were accurate when written. The damage happens at ingest. A chunk reading "BYOK gives procurement teams control over model spend" lands in the same vector space as a chunk describing what Command+K does, and the chunk carries no marker saying which of the two it is. The page title that would have told you, the section heading that framed it as advice, the nav breadcrumb that said "blog": none of that travels with 400 tokens of prose.

So the retriever did its job. It found seven chunks about BYOK, six of them positive, and one buried negation phrased as a question-and-answer pair about something we had removed. The model then did the thing models do when sources disagree. It answered with the version that sounds like a product that wants to be bought.

One correct page does not outrank seven wrong ones

Page authority is a search-engine concept. A vector retriever has no notion of which of your pages is canonical. If the truth lives on one page and the contradiction lives on seven, you have published a 7-to-1 vote against yourself and the assistant will report the result.

The fix was not deleting the feature

We had already deleted BYOK months earlier. That was never the problem. Two things fixed the wrong answer:

  1. Correct the outright false claims. The blog FAQ answer, the meta description, and the cross-link label were each stating something untrue, and each needed editing rather than hedging.
  2. Make the negation travel with the term. Every page that still raises BYOK now carries one plain sentence saying Command+K itself does not support it. We also added the acronym to the what-is page, so a lookup for the bare term resolves to the true answer instead of to an essay.

The second one is the part that is easy to skip and the part that actually changes retrieval behaviour. One sentence per page is cheap. It also means the next person who greps for the term finds the current answer attached to it everywhere, instead of having to know which page is authoritative.

A test, because this will happen again

Retiring a capability is not a one-time event in a product that is still moving. So the fix includes a test that walks the customer-facing pages and asserts two rules: any page mentioning the retired term must contain the explicit disclosure, and no cross-link label may promise it. It failed with 8 offending files the day we wrote it, and we confirmed it fails again when the old text is put back.

One file, extended per retirement, rather than a new test each time. The cheap version of this for any team: a grep in CI over the directories that hold customer-facing copy, with an allowlist of files permitted to mention the term.

How to tell the two failures apart

A genuine hallucination and a faithfully-retrieved contradiction look identical in the chat transcript, and the fixes point in opposite directions. One wants a better prompt, the other wants an edit to your own site. The test that separates them takes a minute:

  • Read what the assistant retrieved, not just what it said. If it cites sources, open them. If it does not, query your own vector store with the user's question and look at the chunks that come back.
  • Grep your entire customer-facing surface for the claim's keyword, not the one page you believe owns it. Count how many hits contradict you. That number is your diagnosis.

If the claim is in your own corpus, prompt engineering will not save you. You will add a rule saying "do not invent features", the retriever will keep handing over six positive chunks, and you will have built a model that argues with its own evidence.

What this costs if you ignore it

The widget answer was the visible symptom, and it was the least expensive one. The same contradiction was already being served to Google and to AI crawlers as FAQPage structured data, which is the machine-readable version of a claim we would have had to walk back on a sales call. Our own house rule now reads: no change to customer-visible behaviour merges without the matching knowledge base change in the same pull request. The widget is the fastest reader of your documentation you will ever have, and it is not a kind one.

FAQ

Why does my AI assistant claim features my product does not have?
Before blaming the model, check whether you published the claim yourself. If your assistant retrieves from your own site, a marketing essay giving generic advice to builders gets embedded next to your official docs, and nothing in the chunk marks it as advice rather than a description of your product. Given one page that says no and seven that say yes, retrieval returns the majority and the model answers with the one that sells.
Is one correct FAQ page enough to fix a wrong answer?
No. Retrieval works on chunks, not on page authority. A single FAQ entry saying 'BYOK is not supported' competes with every other chunk that mentions BYOK positively, and the retriever may never select it. The negation has to travel with the term: one plain sentence on every page that raises the capability.
Should marketing blog posts be in the assistant's knowledge base at all?
Usually yes, because that is where buyers' questions are answered. The failure is not inclusion, it is ambiguity. An essay about what SaaS teams should consider reads identically to a statement about what your product does once it is a 400-token chunk. Mark advice as advice in the prose itself, since the retriever strips your page layout and your headings do not travel with the chunk.
How do I catch this in CI instead of in front of a customer?
Write a test that walks your customer-facing pages for the retired term and asserts two rules: any page mentioning it carries the explicit disclosure, and no internal link label promises it. Ours failed with 8 offending files on the day we wrote it, and it fails again when the old text is restored. Extend that one test for the next retirement instead of writing a new file each time.
Does this affect Google and AI crawlers too, not just my widget?
Yes, and the structured data makes it worse. Our false claim lived in a blog FAQ block that also emits FAQPage JSON-LD, so the wrong answer was served to crawlers as our official position on the question. Fixing the prose without fixing the structured data leaves the machine-readable copy of the lie in place.

Keep reading

Go deeper