An AI hallucination is when a language model gives you an answer that reads as certain and is simply wrong: a person who never existed, a date that never happened, a citation to a paper nobody wrote. Knowing why it happens is what lets you use these tools without shipping their mistakes.
What a hallucination looks like
The dangerous part is not that the answer is wrong. It is that the wrong answer looks exactly like a right one: same fluent sentences, same confident tone, often with neat formatting and a source attached. Nothing in the text warns you.
For developers, hallucinations tend to show up in a few familiar shapes:
- Invented facts: a made-up name, date, version or statistic.
- Invented sources: a citation, URL or paper title that looks real but leads nowhere, or leads somewhere that says something else.
- Invented code: a function, parameter or config option that doesn't exist in the library you asked about, or a package name that was never published.
- Unfaithful summaries: a summary of a document that adds a detail the document never mentioned.
The last two matter most day to day, because they slip into real work. A fake citation in a chat is embarrassing; a fake method in a pull request breaks the build, or worse, gets past review.
Why it happens: prediction, not lookup
A large language model (LLM) is trained to do one thing: given some text, predict what comes next. It works in tokens, which are words or pieces of words. To write an answer, it predicts a likely next token, adds it to the text, then predicts the next one from the longer text, and repeats until it stops.
Nowhere in that loop is there a step that checks whether the sentence is true. The model is not looking facts up in a database. It is producing the continuation that best fits the patterns it learned from its training data. When the question is one it has seen answered many times, the likeliest continuation is usually the correct one, which is why LLMs are so useful most of the time.
Here is the idea as a toy. The odds are made up, but the shape is how generation works:
import random
# Made-up odds for the next word after:
# "The Zeta compiler was invented by"
odds = {
"Dr.": 0.46,
"Professor": 0.31,
"a": 0.15,
"nobody": 0.08,
}
words = list(odds)
weights = list(odds.values())
print(random.choices(words, weights)[0])Suppose the Zeta compiler doesn't exist. A sentence like 'X was invented by' is almost always followed by a name in the text the model learned from, so a name is the likely continuation, and after 'Dr.' a plausible surname is likely too. Each step is a reasonable guess. The whole answer is fiction.
When the gaps open up
Prediction works well until the model has to fill a gap. Three situations make that much more likely.
The prompt is vague
'How do I add retries?' could mean a dozen libraries in a dozen languages. The model picks one reading and commits to it, and it may blend details from several libraries into one answer that matches none of them.
The facts aren't in front of it
The model only 'knows' what is in its training data and in the prompt. Your company's internal API, a private repository, or a library version released after the model was trained are all invisible to it. Ask about them without providing them and it will produce something that fits the general pattern.
The answer was never learned
Obscure topics, rare names and exact numbers are the weak spots. A fact seen once in training is far less reliable than one seen thousands of times, and a fact that was never there at all can only be guessed.
Why it doesn't just say 'I don't know'
LLMs are trained to be useful, and a complete, confident answer usually looks more useful than a refusal. Much of the text they learn from answers questions rather than declining them, and later training rewards helpful responses.
There is also a scoring problem. If a model is graded only on how many answers it gets right, a guess sometimes scores and 'I don't know' never does, much like a multiple-choice exam with no penalty for wrong answers. Over time, that pushes models towards guessing. Newer models are better at admitting uncertainty, but none of them do it reliably, so the habit of checking stays with you.
A worked example: a method that isn't there
Say you ask an assistant how to retry failed requests with Python's requests library, and it suggests this:
import requests
resp = requests.get(
"https://example.com",
retries=3,
)It reads naturally, and plenty of HTTP clients do take a retry option. But requests.get has no retries argument, so this fails at runtime with a TypeError about an unexpected keyword argument. The model blended a common pattern from other libraries into this one.
The real approach, from the requests and urllib3 documentation, is to mount an adapter with a retry policy on a session:
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
retry = Retry(total=3, backoff_factor=0.5)
session = requests.Session()
session.mount(
"https://",
HTTPAdapter(max_retries=retry),
)
resp = session.get("https://example.com")Here the mistake was caught quickly because the code crashed. A hallucinated fact in documentation or a report has no crash to warn you.
How to reduce hallucinations
You can't switch hallucinations off, but you can make them rarer and catch the ones that get through.
Verify what matters
Treat names, dates, statistics and sources as claims to check, not facts. For code, that means running it, reading the official docs for any function you don't recognise, and checking that a suggested package really exists on its registry before you install it. A package name a model invents is also a name someone else could publish, so an unchecked install is a security risk as well as a bug.
Give it reference material
The model has less room to invent when the facts are in the prompt. Paste in the relevant documentation, the file you're asking about, or the error message in full. This is called grounding the answer. Systems that do it automatically, fetching relevant documents and adding them to the prompt before the model answers, use retrieval-augmented generation (RAG).
Prompt better
Be specific about the language, library and version. Set boundaries on what it may use. And give it explicit permission to be unsure, because it will rarely volunteer that on its own:
Answer using only the documentation below.
If the answer is not in it, say "Not in the docs".
Quote the line you relied on.
<docs>
(paste the relevant page here)
</docs>Asking for a quote helps twice over: the model sticks closer to the text, and you can check the quote against the source in seconds.
Common mistakes
- Asking the model if it is sure. It will often confirm its own answer with the same confidence. Check against a source instead.
- Trusting a citation because it is there. Open it. It may not exist, or may not say what the answer claims.
- Reading detail as accuracy. A long, precise-sounding answer is no more likely to be true than a short one.
- Assuming grounding makes it perfect. A model given the right document can still misread it or add to it. Grounding lowers the risk; it doesn't remove it.
- Treating low temperature as a cure. Lowering the randomness setting makes answers more repeatable, not more true.
Hallucinations aren't lies
A lie needs an intent to deceive, and a model has none. A hallucination is a prediction mistake by a system built to predict text, not to tell the truth. That framing is useful: the fix isn't to argue with the model, it's to give it better input and check its output.
Key takeaways
- An AI hallucination is a confident, fluent answer that the model made up.
- LLMs predict the next likely token; nothing in that process checks the facts.
- Vague prompts, missing context and facts the model never learned make hallucinations more likely.
- Verify names, dates, stats, sources and code before you rely on them.
- Ground the model in real documentation and let it say when it doesn't know.