{"id":50991699,"url":"https://github.com/bluntbrain/rag-supabase-ts","last_synced_at":"2026-06-20T04:04:49.845Z","repository":{"id":334555793,"uuid":"1141830778","full_name":"bluntbrain/rag-supabase-ts","owner":"bluntbrain","description":"A Retrieval-Augmented Generation (RAG) system built with TypeScript, Supabase vector storage, and OpenAI.","archived":false,"fork":false,"pushed_at":"2026-01-25T14:17:06.000Z","size":1058,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-26T06:44:19.699Z","etag":null,"topics":["embeddings","rag"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bluntbrain.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-25T14:04:49.000Z","updated_at":"2026-01-25T14:17:09.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/bluntbrain/rag-supabase-ts","commit_stats":null,"previous_names":["bluntbrain/rag-supabase-ts"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/bluntbrain/rag-supabase-ts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluntbrain%2Frag-supabase-ts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluntbrain%2Frag-supabase-ts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluntbrain%2Frag-supabase-ts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluntbrain%2Frag-supabase-ts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bluntbrain","download_url":"https://codeload.github.com/bluntbrain/rag-supabase-ts/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluntbrain%2Frag-supabase-ts/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34556499,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-20T02:00:06.407Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["embeddings","rag"],"created_at":"2026-06-20T04:04:49.368Z","updated_at":"2026-06-20T04:04:49.837Z","avatar_url":"https://github.com/bluntbrain.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RAG System with Supabase and OpenAI\n\n![Demo](demo1.png)\n![Demo](demo2.png)\n\nA Retrieval-Augmented Generation (RAG) system built with TypeScript, Supabase vector storage, and OpenAI.\n\n## What is RAG?\n\nRAG (Retrieval-Augmented Generation) is a technique that enhances LLM responses by providing relevant context from a knowledge base. Instead of relying solely on the model's training data, RAG retrieves relevant documents and includes them in the prompt.\n\n```\nUser Query --\u003e Vector Search --\u003e Retrieve Relevant Docs --\u003e Add to Prompt --\u003e LLM Response\n```\n\n### Why RAG?\n\n- **Reduces hallucinations** - Model answers based on provided context, not guesses\n- **Up-to-date information** - Knowledge base can be updated without retraining\n- **Domain-specific answers** - Use your own documents as the source of truth\n- **Verifiable sources** - Responses can cite which documents were used\n\n## Core Concepts\n\n### 1. Embeddings\n\nEmbeddings convert text into numerical vectors (arrays of numbers) that capture semantic meaning. Similar texts have similar vectors.\n\n```\n\"The cat sat on the mat\" --\u003e [0.12, -0.34, 0.56, ...]  (1536 dimensions)\n\"A feline rested on the rug\" --\u003e [0.11, -0.33, 0.55, ...]  (similar vector)\n```\n\nThis project uses OpenAI's `text-embedding-3-small` model (1536 dimensions).\n\n### 2. Vector Database\n\nSupabase with pgvector extension stores embeddings and performs similarity search using cosine distance. When you query, it finds documents with vectors closest to your query's vector.\n\n```sql\n-- Cosine similarity: 1 - (distance between vectors)\n1 - (documents.embedding \u003c=\u003e query_embedding) as similarity\n```\n\n### 3. Chunking\n\nLarge documents are split into smaller chunks before embedding. This improves:\n\n- **Retrieval precision** - Find specific relevant sections\n- **Context efficiency** - Don't waste tokens on irrelevant content\n- **Embedding quality** - Models have token limits\n\n```\nLarge Document --\u003e [Chunk 1] [Chunk 2] [Chunk 3] ...\n                      |          |          |\n                   Embed      Embed      Embed\n                      |          |          |\n                   Store      Store      Store\n```\n\nThis project uses overlapping chunks (default: 500 chars with 50 char overlap) to preserve context at boundaries.\n\n### 4. Similarity Search\n\nWhen a user asks a question:\n\n1. Convert question to embedding\n2. Find top N documents with closest embeddings (cosine similarity)\n3. Return documents above similarity threshold\n\n### 5. Prompt Construction\n\nRetrieved documents are combined into a prompt that instructs the LLM to only answer based on the provided context:\n\n```\nSystem: Answer based ONLY on the provided context...\n\nContext:\n---\n[Retrieved Document 1]\n---\n[Retrieved Document 2]\n---\n\nQuestion: User's question here\nAnswer:\n```\n\n## Tech Stack\n\n| Component  | Technology                       |\n| ---------- | -------------------------------- |\n| Language   | TypeScript                       |\n| Embeddings | OpenAI text-embedding-3-small    |\n| LLM        | GPT-4o                           |\n| Vector DB  | Supabase (PostgreSQL + pgvector) |\n| Runtime    | Node.js                          |\n\n## Project Structure\n\n```\nsrc/\n  config/\n    index.ts        # OpenAI and Supabase client initialization\n    constants.ts    # Configuration (chunk size, model names, etc.)\n  services/\n    ingestion.ts    # Document chunking, embedding, and storage\n    retrieval.ts    # Vector similarity search\n  types/\n    index.ts        # TypeScript interfaces\n  utils/\n    prompt.ts       # Prompt construction and text splitting\n  index.ts          # Main entry point\ndocs/               # Knowledge base documents (add your .txt files here)\nsql/\n  schema.sql        # Supabase function for similarity search\n```\n\n## Setup\n\n### 1. Prerequisites\n\n- Node.js 18+\n- Supabase project with pgvector enabled\n- OpenAI API key\n\n### 2. Supabase Setup\n\nCreate the documents table in Supabase SQL editor:\n\n```sql\n-- Enable pgvector extension\ncreate extension if not exists vector;\n\n-- Create documents table\ncreate table documents (\n  id bigserial primary key,\n  content text,\n  embedding vector(1536),\n  metadata jsonb\n);\n\n-- Create index for faster similarity search\ncreate index on documents using ivfflat (embedding vector_cosine_ops)\n  with (lists = 100);\n```\n\nThen run the function from `sql/schema.sql` to create `match_documents`.\n\n### 3. Environment Variables\n\n```bash\ncp .env.example .env\n```\n\nEdit `.env`:\n\n```\nOPENAI_API_KEY=sk-...\nSUPABASE_URL=https://your-project.supabase.co\nSUPABASE_SERVICE_ROLE_KEY=eyJ...\n```\n\n### 4. Install and Build\n\n```bash\nnpm install\nnpm run build\n```\n\n## Usage\n\n### Ingest Documents\n\nAdd your text files to the `docs/` folder, then:\n\n```bash\nnpm run ingest\n```\n\nOr uncomment line 38 in `src/index.ts` to ingest before querying.\n\n### Query the Knowledge Base\n\n```bash\nnpm start\n```\n\nEdit the query in `src/index.ts` or import and use `queryRag()`:\n\n```typescript\nimport { queryRag } from \"./index.js\";\n\nconst result = await queryRag(\"What happened in 1843?\");\nconsole.log(result.answer);\nconsole.log(result.sources);\n```\n\n## Configuration\n\nEdit `src/config/constants.ts`:\n\n| Constant                 | Default                | Description                     |\n| ------------------------ | ---------------------- | ------------------------------- |\n| `CHUNK_SIZE`             | 500                    | Max characters per chunk        |\n| `CHUNK_OVERLAP`          | 50                     | Overlap between chunks          |\n| `SIMILARITY_MATCH_COUNT` | 5                      | Number of documents to retrieve |\n| `ANSWERING_MODEL`        | gpt-4o                 | LLM for generating answers      |\n| `EMBEDDING_MODEL_NAME`   | text-embedding-3-small | Model for embeddings            |\n\n## How It Works\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                     INGESTION PIPELINE                       │\n├─────────────────────────────────────────────────────────────┤\n│  docs/*.txt --\u003e Chunk Text --\u003e Create Embeddings --\u003e Store  │\n│                    |               |                   |     │\n│              500 chars        OpenAI API          Supabase   │\n│              50 overlap       1536-dim vector     pgvector   │\n└─────────────────────────────────────────────────────────────┘\n\n┌─────────────────────────────────────────────────────────────┐\n│                      QUERY PIPELINE                          │\n├─────────────────────────────────────────────────────────────┤\n│  User Query --\u003e Embed Query --\u003e Vector Search --\u003e Build     │\n│                     |               |            Prompt      │\n│                OpenAI API      Supabase RPC        |         │\n│                                match_documents     |         │\n│                                     |              v         │\n│                              Top 5 docs -----\u003e Send to GPT   │\n│                              by similarity         |         │\n│                                                    v         │\n│                                               Answer with    │\n│                                               sources        │\n└─────────────────────────────────────────────────────────────┘\n```\n\n## Scripts\n\n| Command             | Description                 |\n| ------------------- | --------------------------- |\n| `npm run build`     | Compile TypeScript          |\n| `npm start`         | Run the compiled app        |\n| `npm run dev`       | Build and run               |\n| `npm run ingest`    | Ingest documents from docs/ |\n| `npm run typecheck` | Type check without emitting |\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbluntbrain%2Frag-supabase-ts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbluntbrain%2Frag-supabase-ts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbluntbrain%2Frag-supabase-ts/lists"}