# Hallucinations

Course: [Large Language Models](https://www.devtutorials.ai/learn/llm) · Section: Using LLMs
Source: https://www.devtutorials.ai/learn/llm/using-llms/hallucinations

> Why LLMs make up facts that sound right, how to spot low-confidence tokens, and how to reduce hallucinations with given context, permission to say I don't know, and checks.

Ask a small model "Who wrote the book *The Silent Orchard*?" There is no such book. But the model might still reply with a name, a year, and a short summary, all written in a calm and confident way.

That is called a **hallucination**: text that sounds right but is not true. This lesson will show you why this happens, how to notice it, and how to make it less likely.

**The main idea:** a model picks words that look likely, not facts that have been checked. When it does not know, it still writes the most likely-sounding answer.

## A Real-World Example

Picture a student taking an exam who did not study one topic.

The question asks for a date. The student does not know it. Leaving it blank feels bad, so they write down a date that "sounds about right". They write it neatly and with confidence. The teacher cannot tell from the writing that it was just a guess.

A language model works in a very similar way.

- **The exam question** is your prompt.
- **Not knowing the answer** means the training text has no strong pattern for this question.
- **Writing a date that sounds right** means the model picks the most likely tokens.
- **Neat handwriting** is the model's smooth, confident style.

**In simple words:** a hallucination is a confident guess written as if it were a fact.

## What You Will Learn

In this lesson, you will learn:

1. What a hallucination is.
2. Why LLMs hallucinate.
3. Which questions are most likely to cause one.
4. How to spot unsure tokens in a reply.
5. How to reduce hallucinations.
6. How to check answers before you trust them.

In the AI sandbox, open **Settings** and tick **Show token chances in chat replies**. Then each token in a reply is coloured by how sure the model was. It is one of the best ways to see a guess as it happens.

## Why Models Hallucinate

You already know the reasons from earlier lessons.

- **It predicts text, not truth.** The model picks the next token that fits the pattern. A wrong fact that fits the pattern looks just as good to it.
- **It must always write something.** Every step gives some token the highest chance. There is no built-in "I don't know" step.
- **It has no live lookup.** A plain model cannot check a fact. It only has patterns from training.
- **Its knowledge has a cutoff.** Anything after the cutoff is unknown.
- **Small models know less.** A 0.5B model has far fewer patterns than a large one.

## Which Questions Cause Hallucinations?

Some questions are much riskier than others.

| Risky question | Why |
|---|---|
| Rare facts, like a small town's population | Few examples in the training text |
| Exact numbers, dates, and quotes | Many similar numbers look equally likely |
| Things that do not exist, like a made-up book | The model fills in a likely-looking answer |
| References, links, and citations | Real-looking titles and URLs are easy to invent |
| Recent events | They happened after the knowledge cutoff |

Common, well-known facts are much safer, because the model saw them many times.

## Spotting Unsure Tokens

A hallucination often shows up as tokens with **low confidence**: the model picked them, but many other tokens were almost as likely. You can flag these tokens.

```js runnable title="Flag tokens the model was unsure about"
const reply = [
  { token: "The", chance: 0.91 },
  { token: " book", chance: 0.88 },
  { token: " was", chance: 0.95 },
  { token: " written", chance: 0.83 },
  { token: " by", chance: 0.97 },
  { token: " Laura", chance: 0.09 },
  { token: " Fenwick", chance: 0.05 },
  { token: " in", chance: 0.71 },
  { token: " 1987", chance: 0.12 },
];

const flagged = reply.filter((t) => t.chance < 0.3).map((t) => t.token.trim());
console.log("Unsure tokens:", flagged.join(", "));
```

Expected output:

```text
Unsure tokens: Laura, Fenwick, 1987
```

The grammar words are all sure. The **name** and the **year**, the actual facts, are the unsure ones. These example chances show the usual pattern: the model is sure about how to say it, and unsure about what to say.

**In simple words:** low chances on the key facts are a warning sign.

### A Confidence Score for the Whole Reply

You can turn the chances into one number for the whole reply, such as the chance of the weakest key token.

```js runnable title="The weakest token decides"
function weakest(reply) {
  return reply.reduce((min, t) => (t.chance < min.chance ? t : min));
}

const known = [
  { token: " Paris", chance: 0.86 },
  { token: " is", chance: 0.97 },
  { token: " the", chance: 0.98 },
  { token: " capital", chance: 0.93 },
];
const guessed = [
  { token: " Laura", chance: 0.09 },
  { token: " Fenwick", chance: 0.05 },
  { token: " wrote", chance: 0.6 },
];

console.log("Known fact, weakest token:", weakest(known).token.trim(), weakest(known).chance);
console.log("Guess, weakest token:     ", weakest(guessed).token.trim(), weakest(guessed).chance);
```

Expected output:

```text
Known fact, weakest token: Paris 0.86
Guess, weakest token:      Fenwick 0.05
```

A low score does not prove an answer is wrong, and a high score does not prove it is right. A model can be confidently wrong about a common mistake. But a low score tells you where to look first.

Confidence is a hint, not a test of truth. Models can give a high chance to a popular wrong answer, and a low chance to a correct rare one. Never use token chances as the only check for important facts.

## Reducing Hallucinations

### 1. Give the Model the Facts

The most powerful fix is to put the facts **into the prompt**. When the answer is in the text the model reads, it can copy it instead of guessing. This is called **grounding**. It is also the main idea behind **RAG**, retrieval augmented generation, which you will meet in a later course.

```js runnable title="Answer only from the given facts"
const facts = {
  "release date": "The new grid control ships on 12 March.",
  "price": "The license costs 995 dollars per developer.",
};

function answer(question) {
  for (const topic in facts) {
    if (question.toLowerCase().includes(topic)) return facts[topic];
  }
  return "I don't know. That is not in the documents I was given.";
}

console.log(answer("What is the release date?"));
console.log(answer("What is the price?"));
console.log(answer("Who is the lead developer?"));
```

Expected output:

```text
The new grid control ships on 12 March.
The license costs 995 dollars per developer.
I don't know. That is not in the documents I was given.
```

This code is a simple stand-in for what a well-instructed model does: answer from the given text, and say "I don't know" when the answer is not there.

### 2. Allow "I Don't Know"

Tell the model, in the system message, that "I don't know" is a good answer. Without that, it tends to answer every question.

```js runnable title="A system message that allows I don't know"
const messages = [
  {
    role: "system",
    content: "Answer only from the facts below. If the answer is not in the facts, say: I don't know.\n\nFacts: The office opens at 9 am.",
  },
  { role: "user", content: "When does the office close?" },
];

console.log(messages[0].content);
console.log("---");
console.log("Question:", messages[1].content);
console.log("A good reply: I don't know.");
```

Expected output:

```text
Answer only from the facts below. If the answer is not in the facts, say: I don't know.

Facts: The office opens at 9 am.
---
Question: When does the office close?
A good reply: I don't know.
```

### 3. Use a Low Temperature for Facts

High temperature makes unlikely tokens more likely, and that includes made-up names and numbers. For facts, use a temperature of 0 to 0.3.

### 4. Check the Answer

Check important claims against a trusted source, or with code. Even a simple check catches many errors.

```js runnable title="Check numbers in a reply against the source"
const source = "The report lists 3 offices: Chennai, Berlin, and Austin.";
const reply = "The company has 4 offices, in Chennai, Berlin, Austin, and Tokyo.";

const sourceNumbers = source.match(/\d+/g) ?? [];
const replyNumbers = reply.match(/\d+/g) ?? [];
const unsupported = replyNumbers.filter((n) => !sourceNumbers.includes(n));

console.log("Numbers in the reply that are not in the source:", unsupported.join(", ") || "none");
```

Expected output:

```text
Numbers in the reply that are not in the source: 4
```

The reply says 4 offices, but the source only supports 3. A one-line check found the hallucination.

**Easy Way to Remember:** **give facts, allow "I don't know", keep the temperature low, and check the result.**

## Try It in the AI Sandbox

Ask the model about something that does not exist. Then ask about a common fact, and compare the token colours.

Then try these in the **Chat** tab:

- Ask the same question with a system message that allows "I don't know". Does it help this small model?
- Paste a short paragraph with the answer into your message, and ask again.
- Try a bigger model from the model picker, and compare.

## Common mistakes

| Mistake | Wrong idea | Correct idea | What goes wrong |
|---|---|---|---|
| Trusting a confident tone | "It sounds sure, so it is true." | The tone is always confident. It shows style, not truth. | Made-up facts end up in your work. |
| Asking for links and sources | "It gave a reference, so it checked." | Models can invent real-looking titles and URLs. | You cite sources that do not exist. |
| No facts in the prompt | "The model will know the answer." | Without the facts, it guesses from patterns. | Rare or recent details are invented. |
| No way to say "I don't know" | "It will tell me if it is unsure." | Without permission, it answers everything. | Guesses look like answers. |
| High temperature for facts | "A little creativity helps." | It makes unlikely names and numbers more likely. | More invented details. |
| Using chances as proof | "High chance means correct." | A model can be confidently wrong. | Popular wrong answers pass your check. |

## Exercises

Each exercise ends with a value on the last line. Press **Check** to compare it with the expected answer.

## What to Remember

- A **hallucination** is a confident answer that is not true.
- Models pick **likely** words, not **checked** facts, and they always write something.
- Risky questions: **rare facts, exact numbers, made-up things, citations, recent events**.
- **Low token chances** on key facts are a warning sign, but not proof.
- **Grounding**, putting the facts in the prompt, is the strongest fix.
- Allow **"I don't know"**, use a **low temperature**, and **check** important claims.

Next: **JSON Validation**, how to get structured data from a model and check that it is valid.
