Retrieval-Augmented Generation
Architect end-to-end RAG pipelines connecting embedding generation, vector retrieval, prompt grounding, and citation generation.
TL;DR
- Transform user inquiries into mathematical vectors via
embeddings.create()calls. - Retrieve top matching passages using vector database
query()operations. - Ground model completions with retrieved excerpts using XML
<context>delimiters.
End-to-End Pipeline Architecture
RAG Pipeline OrchestratorCoordinate query embedding, vector lookup, and prompt synthesis.
async function answerWithRAG(
query: string, client: any, db: any
) {
const qVec = await getEmbedding(query, client);
const matches = await db.query({
vector: qVec, topK: 3,
});
const texts = matches.map((m: any) => m.text);
const context = texts.join('\n---\n');
return await generateAnswer(query, context, client);
}Context Grounding Prompt BuilderEnforce strict factual adherence using XML context tags.
function buildRAGPrompt(
query: string, context: string
) {
return [
{
role: 'system',
content: 'Answer ONLY using provided facts.' +
' If absent, state you do not know.\n\n' +
`<context>\n${context}\n</context>`,
},
{ role: 'user', content: query },
];
}Minimum Similarity Score GateDiscard retrieved chunks that fall below relevance threshold.
type Match = { text: string; score: number };
function filterByScore(matches: Match[]) {
const MIN_SCORE = 0.75;
return matches.filter(m => m.score >= MIN_SCORE);
}Source Attribution & Citations
Numbered Source Document InjectionFormat retrieved context passages with numerical citation keys.
type Doc = { id: string; text: string };
function formatCitedContext(docs: Doc[]) {
return docs
.map((d, i) => {
return `[Doc ${i + 1}] (${d.id}):\n${d.text}`;
})
.join('\n\n');
}Citation Extraction ParserExtract bracketed document citations from generated LLM response.
function extractCitations(answer: string) {
const matches = answer.matchAll(/\[Doc (\d+)\]/g);
const list = [...matches];
const ids = list.map(m => parseInt(m[1], 10));
return Array.from(new Set(ids));
}Fallback Handling on Missing ContextDetect when no relevant documents pass similarity threshold.
if (filteredDocs.length === 0) {
return {
answer: 'No relevant documentation found.',
sources: [],
};
}Pipeline Latency Optimization
Parallel Embedding & Filter LookupResolve user authentication and metadata filters concurrently.
const [qVec, userTenant] = await Promise.all([
getEmbedding(query, client),
fetchUserTenantId(userId),
]);
const results = await index.query({
vector: qVec,
filter: { tenant: userTenant },
});Streaming RAG Response DeliveryStream final answer tokens to client as soon as retrieval resolves.
const stream = await client.chat.completions.create({
model: 'gpt-4o',
messages: buildRAGPrompt(query, context),
stream: true,
});
for await (const chunk of stream) {
const txt = chunk.choices[0]?.delta?.content ?? '';
process.stdout.write(txt);
}Semantic Query Cache CheckCheck vector cache for previously answered identical inquiries.
const cached = await checkSemanticCache(qVec, 0.95);
if (cached) return cached.answer;Evaluation & Hallucination Guardrails
Faithfulness Consistency ValidatorVerify that model completion contains no unsupported claims.
async function verifyFaithfulness(
answer: string, context: string, client: any
) {
const p = 'Ungrounded facts in answer?\n' +
`Ctx: ${context}\nAns: ${answer}\nReply YES/NO`;
const res = await client.chat.completions.create({
model: 'gpt-4o-mini',
messages: [{ role: 'user', content: p }],
});
const txt = res.choices[0]?.message?.content?.trim();
return txt === 'NO';
}Empty Context GuardBlock model invocation when knowledge retrieval yields zero records.
function ensureContextNotEmpty(chunks: string[]) {
if (!chunks || chunks.length === 0) {
const err = 'RAG retrieval empty; aborting call';
throw new Error(err);
}
}XML Delimiter EscapingSanitize raw input strings to prevent prompt injection breakouts.
function escapeContextXml(text: string) {
return text
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>');
}Tips
- Wrap retrieved knowledge chunks in structured XML
<context>tags to prevent the LLM from confusing reference facts with prompt instructions. - Return explicit
sourceIdidentifiers alongside answers to provide verifiable citations and eliminate user hallucination concerns across production systems.
Warnings
- Never inject unverified retrieved text directly into system messages without escaping potential prompt injection sequences with
xmlEscape()functions. - Avoid overwhelming prompt context with low-similarity retrieval chunks that dilute model reasoning and inflate bills above your target
tokenBudget.
In Practice
Executes end-to-end RAG: embeds user query, retrieves grounded context, and generates verified answer.
- Generate float vector embedding from user query.
- Retrieve nearest semantic documentation passages.
- Format retrieved context within structured XML tags.
- Invoke model with strict instruction to cite references.
import OpenAI from 'openai';
const client = new OpenAI();
async function rag(query: string, docs: string[]) {
const emb = await client.embeddings.create({
model: 'text-embedding-3-small',
input: query,
});
const ctx = docs.join('\n---\n');
const r = await client.chat.completions.create({
model: 'gpt-4o-mini',
messages: [
{ role: 'system', content: `Context:\n${ctx}` },
{ role: 'user', content: query },
],
});
return r.choices[0]?.message?.content;
}
const docList = ['API listens on 8080.'];
console.log(await rag('Port?', docList));FAQ
Wrapping retrieved text in <context> tags visually isolates reference data from prompt instructions, preventing the model from misinterpreting text inside documents as commands.
For cosine similarity with normalized embeddings, scores below 0.70 typically represent unrelated noise. Setting a minimum gate around 0.75 prevents hallucination.
Implement a strict fallback rule: if no retrieved chunk exceeds the similarity threshold, output a canned refusal statement rather than querying the model.