Once you have the best chunks, the prompt gives them to the model with ids and tells it how to use them: answer only from these sources, cite the source of each claim, and say so when the answer isn't there.
Answer the question using only the sources below. After each sentence, cite the
source it came from, like [2]. If the sources don't contain the answer, say "I can't
find that in the documents" and stop.
<source id="1" title="Billing policy, section 4">Late fees are 1.5% a month on the
unpaid balance, starting 30 days after the due date.</source>
<source id="2" title="Billing FAQ">Invoices can be paid by bank transfer or card.</source>
Question: When do late fees start?
Citations do two jobs. People can check the answer against the source, and your code can check it too. A cited id must be one of the sources you sent. If you ask for a short quote with each citation, check the quote really appears in that source; if it doesn't, the model is paraphrasing loosely or making things up.
sources = {"1": "Late fees are 1.5% a month on the unpaid balance, starting 30 days after the due date."}
answer = {"text": "Late fees start 30 days after the due date.", "source": "1", "quote": "starting 30 days after the due date"}
print(answer["source"] in sources)
print(answer["quote"] in sources[answer["source"]])
Prints
True
True
"I can't find that" is a good answer when it's true. Reward it in your evals. A system that always answers will sometimes answer from the model's memory instead of your documents, and that's where confident wrong answers come from.
Show sources in the interface (title, section, a link) so people can click through. That also makes a wrong answer much easier to report and fix.
Practice
The sources don't mention international shipping, and a user asks about it. What should the system say?
More info
Quick reference
Grounding
Answering from the sources supplied, not from memory.