An open API service indexing awesome lists of open source software.

https://github.com/bluntbrain/rag-supabase-ts

A Retrieval-Augmented Generation (RAG) system built with TypeScript, Supabase vector storage, and OpenAI.
https://github.com/bluntbrain/rag-supabase-ts

embeddings rag

Last synced: about 1 month ago
JSON representation

A Retrieval-Augmented Generation (RAG) system built with TypeScript, Supabase vector storage, and OpenAI.

Awesome Lists containing this project

README

          

# RAG System with Supabase and OpenAI

![Demo](demo1.png)
![Demo](demo2.png)

A Retrieval-Augmented Generation (RAG) system built with TypeScript, Supabase vector storage, and OpenAI.

## What is RAG?

RAG (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.

```
User Query --> Vector Search --> Retrieve Relevant Docs --> Add to Prompt --> LLM Response
```

### Why RAG?

- **Reduces hallucinations** - Model answers based on provided context, not guesses
- **Up-to-date information** - Knowledge base can be updated without retraining
- **Domain-specific answers** - Use your own documents as the source of truth
- **Verifiable sources** - Responses can cite which documents were used

## Core Concepts

### 1. Embeddings

Embeddings convert text into numerical vectors (arrays of numbers) that capture semantic meaning. Similar texts have similar vectors.

```
"The cat sat on the mat" --> [0.12, -0.34, 0.56, ...] (1536 dimensions)
"A feline rested on the rug" --> [0.11, -0.33, 0.55, ...] (similar vector)
```

This project uses OpenAI's `text-embedding-3-small` model (1536 dimensions).

### 2. Vector Database

Supabase 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.

```sql
-- Cosine similarity: 1 - (distance between vectors)
1 - (documents.embedding <=> query_embedding) as similarity
```

### 3. Chunking

Large documents are split into smaller chunks before embedding. This improves:

- **Retrieval precision** - Find specific relevant sections
- **Context efficiency** - Don't waste tokens on irrelevant content
- **Embedding quality** - Models have token limits

```
Large Document --> [Chunk 1] [Chunk 2] [Chunk 3] ...
| | |
Embed Embed Embed
| | |
Store Store Store
```

This project uses overlapping chunks (default: 500 chars with 50 char overlap) to preserve context at boundaries.

### 4. Similarity Search

When a user asks a question:

1. Convert question to embedding
2. Find top N documents with closest embeddings (cosine similarity)
3. Return documents above similarity threshold

### 5. Prompt Construction

Retrieved documents are combined into a prompt that instructs the LLM to only answer based on the provided context:

```
System: Answer based ONLY on the provided context...

Context:
---
[Retrieved Document 1]
---
[Retrieved Document 2]
---

Question: User's question here
Answer:
```

## Tech Stack

| Component | Technology |
| ---------- | -------------------------------- |
| Language | TypeScript |
| Embeddings | OpenAI text-embedding-3-small |
| LLM | GPT-4o |
| Vector DB | Supabase (PostgreSQL + pgvector) |
| Runtime | Node.js |

## Project Structure

```
src/
config/
index.ts # OpenAI and Supabase client initialization
constants.ts # Configuration (chunk size, model names, etc.)
services/
ingestion.ts # Document chunking, embedding, and storage
retrieval.ts # Vector similarity search
types/
index.ts # TypeScript interfaces
utils/
prompt.ts # Prompt construction and text splitting
index.ts # Main entry point
docs/ # Knowledge base documents (add your .txt files here)
sql/
schema.sql # Supabase function for similarity search
```

## Setup

### 1. Prerequisites

- Node.js 18+
- Supabase project with pgvector enabled
- OpenAI API key

### 2. Supabase Setup

Create the documents table in Supabase SQL editor:

```sql
-- Enable pgvector extension
create extension if not exists vector;

-- Create documents table
create table documents (
id bigserial primary key,
content text,
embedding vector(1536),
metadata jsonb
);

-- Create index for faster similarity search
create index on documents using ivfflat (embedding vector_cosine_ops)
with (lists = 100);
```

Then run the function from `sql/schema.sql` to create `match_documents`.

### 3. Environment Variables

```bash
cp .env.example .env
```

Edit `.env`:

```
OPENAI_API_KEY=sk-...
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_ROLE_KEY=eyJ...
```

### 4. Install and Build

```bash
npm install
npm run build
```

## Usage

### Ingest Documents

Add your text files to the `docs/` folder, then:

```bash
npm run ingest
```

Or uncomment line 38 in `src/index.ts` to ingest before querying.

### Query the Knowledge Base

```bash
npm start
```

Edit the query in `src/index.ts` or import and use `queryRag()`:

```typescript
import { queryRag } from "./index.js";

const result = await queryRag("What happened in 1843?");
console.log(result.answer);
console.log(result.sources);
```

## Configuration

Edit `src/config/constants.ts`:

| Constant | Default | Description |
| ------------------------ | ---------------------- | ------------------------------- |
| `CHUNK_SIZE` | 500 | Max characters per chunk |
| `CHUNK_OVERLAP` | 50 | Overlap between chunks |
| `SIMILARITY_MATCH_COUNT` | 5 | Number of documents to retrieve |
| `ANSWERING_MODEL` | gpt-4o | LLM for generating answers |
| `EMBEDDING_MODEL_NAME` | text-embedding-3-small | Model for embeddings |

## How It Works

```
┌─────────────────────────────────────────────────────────────┐
│ INGESTION PIPELINE │
├─────────────────────────────────────────────────────────────┤
│ docs/*.txt --> Chunk Text --> Create Embeddings --> Store │
│ | | | │
│ 500 chars OpenAI API Supabase │
│ 50 overlap 1536-dim vector pgvector │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ QUERY PIPELINE │
├─────────────────────────────────────────────────────────────┤
│ User Query --> Embed Query --> Vector Search --> Build │
│ | | Prompt │
│ OpenAI API Supabase RPC | │
│ match_documents | │
│ | v │
│ Top 5 docs -----> Send to GPT │
│ by similarity | │
│ v │
│ Answer with │
│ sources │
└─────────────────────────────────────────────────────────────┘
```

## Scripts

| Command | Description |
| ------------------- | --------------------------- |
| `npm run build` | Compile TypeScript |
| `npm start` | Run the compiled app |
| `npm run dev` | Build and run |
| `npm run ingest` | Ingest documents from docs/ |
| `npm run typecheck` | Type check without emitting |

## License

MIT