Citations
Show which sources an answer came from so users can verify it.
A big advantage of RAG is that you know exactly which passages fed the answer. Surfacing them as citations builds trust and lets users check the source.
How to add citations
- Attach an id or title to each retrieved chunk.
- Ask the model to reference the source id it used for each claim.
- Render the sources as links next to the answer.
Citations also make debugging easier: if an answer is wrong, you can see whether the retrieval or the generation was at fault.
Example
{
"answer": "Refunds are available within 14 days of purchase [1].",
"sources": [
{"id": 1, "title": "Refund Policy", "url": "/docs/refunds"}
]
}When to use it
- A legal research tool appends the source document name and paragraph number to every AI-generated answer so lawyers can verify citations.
- A medical Q&A platform requires the model to cite which clinical guideline passage supported each claim, enabling clinicians to check the evidence.
- A customer-facing helpbot links to the specific help-article section it used, so users can read the full context behind a short AI answer.
More examples
Ask model to include source names
Prefixes each source with its ID and asks the model to cite which ID supports its answer.
from openai import OpenAI
client = OpenAI()
sources = [
{'id': 'faq-returns', 'text': 'Refunds are accepted within 30 days of purchase.'},
{'id': 'faq-shipping', 'text': 'Standard shipping takes 5-7 business days.'},
]
context = '\n'.join(f'[{s["id"]}] {s["text"]}' for s in sources)
r = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content':
f'{context}\n\n'
'Answer: Can I return something after 3 weeks? '
'Cite the source ID in brackets after your answer.'
}]
)
print(r.choices[0].message.content)Return structured JSON with citations
Returns answer and cited source IDs as structured JSON so downstream code can render source links.
import json
from openai import OpenAI
client = OpenAI()
context = '[doc-1] Subscription auto-renews monthly. [doc-2] Cancel any time from account settings.'
r = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content':
f'{context}\n\n'
'Answer the question and return JSON with keys: answer (string) and sources (list of doc ids).\n'
'Question: How do I stop being billed?'
}],
response_format={'type': 'json_object'}
)
result = json.loads(r.choices[0].message.content)
print('Answer:', result['answer'])
print('Sources:', result['sources'])Filter hallucinated citations post-generation
Filters the model's cited IDs against the set of documents that were actually provided, catching hallucinated citations.
import json
from openai import OpenAI
client = OpenAI()
VALID_IDS = {'doc-1', 'doc-2', 'doc-3'}
r = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content':
'[doc-1] Refunds in 30 days. [doc-2] Contact [email protected].\n\n'
'Answer and return JSON: {"answer": "...", "sources": ["doc-x", ...]}\n'
'Question: How do I get a refund?'
}],
response_format={'type': 'json_object'}
)
result = json.loads(r.choices[0].message.content)
verified_sources = [s for s in result.get('sources', []) if s in VALID_IDS]
result['sources'] = verified_sources
print(result)
Discussion