Build / AI /

Retrieval-Augmented Generation

Architect end-to-end RAG pipelines connecting embedding generation, vector retrieval, prompt grounding, and citation generation.

TL;DR

  1. Transform user inquiries into mathematical vectors via embeddings.create() calls.
  2. Retrieve top matching passages using vector database query() operations.
  3. Ground model completions with retrieved excerpts using XML <context> delimiters.

End-to-End Pipeline Architecture

    RAG Pipeline Orchestrator

    Coordinate 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 Builder

    Enforce 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 Gate

    Discard 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 Injection

    Format 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 Parser

    Extract 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 Context

    Detect when no relevant documents pass similarity threshold.

    if (filteredDocs.length === 0) {
      return {
        answer: 'No relevant documentation found.',
        sources: [],
      };
    }

Pipeline Latency Optimization

    Parallel Embedding & Filter Lookup

    Resolve 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 Delivery

    Stream 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 Check

    Check vector cache for previously answered identical inquiries.

    const cached = await checkSemanticCache(qVec, 0.95);
    if (cached) return cached.answer;

Evaluation & Hallucination Guardrails

    Faithfulness Consistency Validator

    Verify 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 Guard

    Block 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 Escaping

    Sanitize raw input strings to prevent prompt injection breakouts.

    function escapeContextXml(text: string) {
      return text
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;');
    }

Tips

  1. Wrap retrieved knowledge chunks in structured XML <context> tags to prevent the LLM from confusing reference facts with prompt instructions.
  2. Return explicit sourceId identifiers alongside answers to provide verifiable citations and eliminate user hallucination concerns across production systems.

Warnings

  1. Never inject unverified retrieved text directly into system messages without escaping potential prompt injection sequences with xmlEscape() functions.
  2. Avoid overwhelming prompt context with low-similarity retrieval chunks that dilute model reasoning and inflate bills above your target tokenBudget.

In Practice

FAQ