Mobile App Development

Retrieval-Augmented Generation

Retrieval Augmented Generation – Generative AI Tool

AI tools like ChatGPT, Claude, and Gemini are amazing – they can write emails, answer questions, and even help with coding. But there’s one big problem: AI can sometimes invent details—it’s like guessing instead of knowing. This is called a hallucination. That’s why a new approach called RAG (Retrieval-Augmented Generation) is becoming popular. It helps AI give more accurate and reliable answers by connecting it to real data. What is RAG? RAG works in two simple steps: Your Attractive Heading Think of it like an open-book exam. Instead of guessing from memory, the AI “opens the book” and finds the right answer. Why is RAG Important? Where RAG is Used Today The Challenges RAG is powerful but not perfect. If the documents it examines are incorrect or unclear, the AI can still provide an inaccurate answer. It also needs a good setup and management. Future of RAG In the coming years, RAG will get even better: 👉 In simple words: If AI is the brain, RAG is the memory that makes sure it remembers the right things. Tiny RAG App (Node + SQLite) — Step‑by‑Step It shows you: A minimal, end‑to‑end Retrieval‑Augmented Generation (RAG) example using TypeScript, OpenAI embeddings + chat, and SQLite (via better-sqlite3). Goal: Ingest a small folder of .txt/.md files, embed & store chunks in SQLite, then answer questions grounded in those files with citations. 1) Prereqs mkdir tiny-rag && cd tiny-rag npm init -y npm i openai better-sqlite3 dotenv npm i -D typescript ts-node @types/node npx tsc –init –rootDir src –outDir dist –esModuleInterop –resolveJsonModule –module commonjs –target es2020 mkdir -p src data Create .env in project root: OPENAI_API_KEY=YOUR_KEY_HERE EMBED_MODEL=text-embedding-3-small CHAT_MODEL=gpt-4o-mini Add scripts to package.json: {   “scripts”: {     “ingest”: “ts-node src/ingest.ts”,     “ask”: “ts-node src/ask.ts”   } } 2) Data: drop a couple of files in ./data data/faq.txt Product X supports offline mode. Sync runs automatically every 15 minutes or when the user taps “Sync Now”. Logs are saved in logs/sync.log. data/policies.md # Leave Policy (2024) Employees can take 18 days of paid leave per calendar year. Unused leave does not carry over. For emergencies, contact HR at hr@example.com. Feel free to replace with your own docs. 3) src/db.ts — tiny SQLite helper import Database from ‘better-sqlite3’; const db = new Database(‘rag.sqlite’); db.exec(`   PRAGMA journal_mode = WAL;   CREATE TABLE IF NOT EXISTS documents (     id INTEGER PRIMARY KEY,     path TEXT UNIQUE,     content TEXT   );   CREATE TABLE IF NOT EXISTS chunks (     id INTEGER PRIMARY KEY,     doc_id INTEGER NOT NULL,     idx INTEGER NOT NULL,     text TEXT NOT NULL,     embedding BLOB NOT NULL,     FOREIGN KEY(doc_id) REFERENCES documents(id)   );   CREATE INDEX IF NOT EXISTS idx_chunks_doc ON chunks(doc_id); `); export default db; 4) src/util.ts — chunking & cosine export function chunkText(text: string, chunkSize = 800, overlap = 150): { idx: number; text: string; start: number; end: number }[] {   const clean = text.replace(/\r/g, ”);   const chunks: { idx: number; text: string; start: number; end: number }[] = [];   let i = 0, idx = 0;   while (i < clean.length) {     const end = Math.min(i + chunkSize, clean.length);     const slice = clean.slice(i, end);     chunks.push({ idx, text: slice, start: i, end });     idx++;     i = end – overlap;     if (i < 0) i = 0;   }   return chunks; } export function toBlob(vec: number[] | Float32Array): Buffer {   const f32 = vec instanceof Float32Array ? vec : Float32Array.from(vec);   return Buffer.from(f32.buffer); } export function fromBlob(buf: Buffer): Float32Array {   return new Float32Array(buf.buffer, buf.byteOffset, buf.byteLength / 4); } export function cosineSim(a: Float32Array, b: Float32Array): number {   let dot = 0, na = 0, nb = 0;   for (let i = 0; i < a.length; i++) { dot += a[i]*b[i]; na += a[i]*a[i]; nb += b[i]*b[i]; }   return dot / (Math.sqrt(na) * Math.sqrt(nb) + 1e-8); } 5) src/openai.ts — client import ‘dotenv/config’; import OpenAI from ‘openai’; export const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY }); export const EMBED_MODEL = process.env.EMBED_MODEL || ‘text-embedding-3-small’; export const CHAT_MODEL = process.env.CHAT_MODEL || ‘gpt-4o-mini’; 6) src/ingest.ts — read files → chunks → embeddings → SQLite import fs from ‘fs’; import path from ‘path’; import db from ‘./db’; import { openai, EMBED_MODEL } from ‘./openai’; import { chunkText, toBlob } from ‘./util’; const DATA_DIR = path.resolve(‘data’); async function embed(texts: string[]): Promise<number[][]> {   const res = await openai. embeddings.create({     model: EMBED_MODEL,     input: texts   });   return res.data.map(d => d.embedding as number[]); } function* iterFiles(dir: string): Generator<string> {   for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {     const p = path.join(dir, entry.name);     if (entry.isDirectory()) yield* iterFiles(p);     else if (p.endsWith(‘.txt’) || p.endsWith(‘.md’)) yield p;   } } (async () => {   if (!fs.existsSync(DATA_DIR)) throw new Error(`Missing data dir: ${DATA_DIR}`);   const upsertDoc = db.prepare(‘INSERT INTO documents(path, content) VALUES (?, ?) ON CONFLICT(path) DO UPDATE SET content=excluded.content RETURNING id’);   const delChunks = db.prepare(‘DELETE FROM chunks WHERE doc_id = ?’);   const insertChunk = db.prepare(‘INSERT INTO chunks (doc_id, idx, text, embedding) VALUES (?, ?, ?, ?)’);   for (const file of iterFiles(DATA_DIR)) {     const content = fs.readFileSync(file, ‘utf8’);     const { id: docId } = upsertDoc.get(file, content) as { id: number };     delChunks.run(docId);     const chunks = chunkText(content, 800, 150);     const embeddings = await embed(chunks.map(c => c.text));     const tx = db.transaction(() => {       for (let i = 0; i < chunks.length; i++) {         const c = chunks[i];         const e = embeddings[i];         insertChunk.run(docId, c.idx, c.text, toBlob(e));       }     });     tx();     console.log(`Ingested ${file} → ${chunks.length} chunks`);   }   console.log(‘Done.’); })(); 7) src/ask.ts — retrieve top‑K → answer with citations import db from ‘./db’; import { openai, CHAT_MODEL, EMBED_MODEL } from ‘./openai’; import { cosineSim, fromBlob } from ‘./util’; async function embedQuery(q: string): Promise<Float32Array> {   const r = await openai.embeddings.create({ model: EMBED_MODEL, input: q });   return Float32Array.from(r.data[0].embedding as number[]); } function retrieveTopK(qVec: Float32Array, k = 5) {   const rows = db.prepare(`     SELECT chunks.id, chunks.idx, chunks.text, chunks.embedding, documents.path AS path     FROM chunks JOIN documents ON chunks.doc_id = documents.id   `).all();   const scored = rows.map(r => ({     path: r.path as string,     idx: r.idx as number,     text: r.text as string,     score: cosineSim(qVec, fromBlob(r.embedding as Buffer))   }));   scored.sort((a,b) => b.score – a.score);   return scored.slice(0, k); } function buildContext(chunks: { path: string; idx: number; text: string }[]):

Retrieval Augmented Generation – Generative AI Tool Read More »

Building Faster with CI/CD: Streamlining Software Delivery

Building Faster with CI/CD: Streamlining Software Delivery

CI/CD stands for Continuous Integration and Continuous Deployment (or Continuous Delivery). In modern software development, delivering products quickly and reliably is crucial. Continuous Integration (CI) and Continuous Deployment (CD) streamline the process by automating code testing and release. This approach helps reduce errors, save time, and maintain consistent quality throughout the development process. Whether you’re working on small applications or large-scale projects, adopting CI/CD can significantly enhance your software delivery process. AWS CI/CD services AWS CodePipeline AWS CodeBuild AWS S3 for storing build artifacts. AWS CodeDeploy App spec File:Appspec.yml: The appspec.yml file is a crucial configuration file used by AWS CodeDeploy to define how the deployment process is performed. This file is required for all deployments in AWS CodeDeploy and specifies various instructions for how the application is to be deployed to the target compute resources (such as Amazon EC2 instances, AWS Lambda, or on-premises servers) Conclusion Implementing Continuous Integration and Continuous Deployment (CI/CD) is a powerful way to modernize your software development process. It helps teams work more efficiently by automating repetitive tasks, identifying errors early, and accelerating releases. With CI/CD, businesses can respond quickly to user needs, deliver updates faster, and maintain consistent code quality across environments. As the demand for faster, more reliable digital solutions grows, adopting CI/CD pipelines is essential for staying competitive in today’s fast-paced tech world. Contact us at: +91 9665797912 Email us: contact@logicalwings.com Website: https://logicalwings.com/

Building Faster with CI/CD: Streamlining Software Delivery Read More »

Scroll to Top