Answer With Citations, or Say You Can't
Answer a question from a set of documents, cite the documents you used, and say plainly when they do not cover it.
Implement answer_with_citations(llm, question, docs) returning {"answer": str, "citations": [int, ...], "supported": bool}.
Number the documents from 0 and ask the model for JSON: the answer, the indices it relied on, and whether the documents support the answer. Then enforce what the model cannot be trusted to:
- Citations must be valid indices. The model will cite document 9 of 4. Drop anything out of range.
- Supported requires a citation. If the model says
supported: trueand cites nothing, set it false and make the answer say the documents do not cover it. - When it is not supported, say so. "I can't answer that from these documents" is a correct output.
The catch: asked for the CEO's home address, a model given documents about refunds and parking will often invent one. With nothing to cite, the citation rule stops it being marked supported.
Tests use a real model: a refund question must cite the refund document and contain the number; an off-topic question must come back unsupported with no citations.