Reducing Hallucinations with Grounding

Stop the model inventing facts by giving it the source material and making it cite what it used.

A hallucination is the model stating something false with total confidence. You cannot prompt it away entirely — but you can make it rare enough for production by changing where the facts come from.

Ground the answer in retrieved context

Instead of relying on the model's training memory, retrieve the relevant documents (see the RAG lessons) and instruct the model to answer using only the provided context. The model shifts from "recall a fact" to "read and summarise this text" — a task it is far more reliable at.

Give it an escape hatch

The most important sentence in a grounded prompt: "If the answer is not in the context, say you don't know." Without it, a model asked something the documents don't cover will helpfully invent an answer. With it, you get an honest "I don't have that information" — which is almost always the better product behaviour.

Require citations

Ask the model to attach the source id for each claim, and render those as links. Citations do three jobs at once: they build user trust, they let users verify, and they make you able to debug — if an answer is wrong you can see instantly whether retrieval fetched the wrong document or generation misread the right one.

Verify what matters

For high-stakes facts — prices, dates, dosages, legal terms — don't stop at the model. Cross-check the extracted value against the source with code, or against a second independent call.

Example

Example · json
{
  "messages": [
    {
      "role": "system",
      "content": "Answer ONLY from the provided context. If the answer is not in the context, reply exactly: 'I don't have that information.' Cite the source id in [brackets] after each claim."
    },
    {
      "role": "user",
      "content": "CONTEXT:\n[1] Refunds are available within 14 days of purchase.\n[2] Shipping is free on orders over $50.\n\nQUESTION: How long do I have to request a refund?"
    }
  ],
  "expected_answer": "You have 14 days from purchase to request a refund [1]."
}

When to use it

  • A financial assistant retrieves live prices from a market data API and injects them into the prompt, preventing the model from citing stale figures.
  • A medical Q&A tool fetches the relevant clinical guideline section at query time and restricts the model to answering only from that passage.
  • A legal research assistant retrieves cited case law and checks that every statute the model references appears in the retrieved context before displaying the answer.

More examples

Inject retrieved context into system prompt

Injects a retrieved context block into the system prompt and instructs the model to answer only from it.

Example · python
from openai import OpenAI

client = OpenAI()

# Simulate retrieving live context (in production: vector search or API call)
context = (
    'As of 2025-06-01: Python 3.13 was released with a free-threaded mode. '
    'Python 3.14 is in beta with an experimental JIT compiler.'
)

r = client.chat.completions.create(
    model='gpt-4o-mini',
    messages=[
        {'role':'system','content':
            'Answer ONLY using the provided context. '
            'If the answer is not in the context, say "I don\'t know".\n\n'
            f'CONTEXT:\n{context}'},
        {'role':'user','content':'What is new in Python 3.14?'}
    ]
)
print(r.choices[0].message.content)

Ask model to cite retrieved passages

Labels each passage with an ID and asks the model to cite which ID supports its claim, making grounding verifiable.

Example · python
from openai import OpenAI

client = OpenAI()

passages = [
    {'id':'p1','text':'Refunds must be requested within 30 days of purchase.'},
    {'id':'p2','text':'Items must be in original, undamaged packaging to qualify for a return.'},
]
formatted = '\n'.join(f'[{p["id"]}] {p["text"]}' for p in passages)

r = client.chat.completions.create(
    model='gpt-4o-mini',
    messages=[{'role':'user','content':
        f'{formatted}\n\nCan I return an item I bought 3 weeks ago? '
        'Cite the passage ID that supports your answer.'
    }]
)
print(r.choices[0].message.content)

Verify cited passages exist in context

Filters the model's cited IDs against the known valid set to remove any hallucinated passage references.

Example · python
import json, re
from openai import OpenAI

client = OpenAI()

VALID_IDS = {'p1', 'p2', 'p3'}
context = '[p1] Free returns within 14 days. [p2] Exclusions apply to sale items.'

r = client.chat.completions.create(
    model='gpt-4o-mini',
    messages=[{'role':'user','content':
        f'{context}\n\n'
        'Can I return a sale item? Answer and cite passage IDs as JSON: {"answer":"...","sources":["p?",...]}'}
    ],
    response_format={'type':'json_object'}
)
result = json.loads(r.choices[0].message.content)
cited = set(result.get('sources', []))
hallucinated = cited - VALID_IDS
if hallucinated:
    print('Hallucinated citations removed:', hallucinated)
result['sources'] = list(cited & VALID_IDS)
print(result)

Discussion

  • Be the first to comment on this lesson.