Answers from your own documents
A model doesn't know your course notes or company wiki — and when it doesn't know, it may invent something. RAG fixes both: split documents into chunks, retrieve the chunks most similar to the question, put them in the prompt as numbered sources, and require citations you can check.
The pipeline
function chunk(text, { size, overlap = 0 }) {
if (overlap >= size) throw new Error("Overlap must be smaller than size");
const words = text.split(/\s+/).filter(Boolean);
const chunks = [];
for (let start = 0; start < words.length; start += size - overlap) {
chunks.push(words.slice(start, start + size).join(" "));
if (start + size >= words.length) break; // the last chunk reached the end
}
return chunks;
}
function buildPrompt(question, sources) {
const numbered = sources.map((s, i) => `[${i + 1}] ${s}`).join("\n");
return `Answer using only the sources below. Cite them like [1]. If they don't contain the answer, say "I don't know".\n\n${numbered}\n\nQuestion: ${question}`;
}
function checkCitations(answer, sourceCount) {
const cited = [...new Set([...answer.matchAll(/\[(\d+)\]/g)].map((m) => Number(m[1])))].sort((a, b) => a - b);
const invalid = cited.filter((n) => n < 1 || n > sourceCount); // made-up sources
return { cited, invalid, grounded: cited.length > 0 && invalid.length === 0 };
}