Skip to main content

Supabase Easy RAG

License: MIT Python 3.10+ PostgreSQL 16+ pgvector HNSW CI Postgres Live Cloud Supabase Validated

A production-ready, ultra-fast Hybrid RAG engine built natively on PostgreSQL & Supabase. Combines dense vector search (HNSW) and sparse BM25 full-text search with Reciprocal Rank Fusion (RRF), parent-context expansion, and database-native multi-tenant RLS isolation.


🚀 Quick Start

1. Installation

pip install supabase-easy-rag

2. Apply Database Migrations

supabase db push

Option B: Via SQL Editor or CLI Export

easy-rag init-sql --output ./migrations --dimensions 1536

Apply 01_schema.sql and 02_functions.sql in the Supabase SQL Editor.

3. Configure Environment Variables (.env)

SUPABASE_URL="https://your-project.supabase.co"
SUPABASE_SERVICE_ROLE_KEY="your-service-role-key"
SUPABASE_ANON_KEY="your-anon-key"

# Embedding Provider (OpenAI or Azure OpenAI)
OPENAI_API_KEY="sk-..."

4. 30-Second Python Example

from supabase_easy_rag import EasyRagClient

# Pass the end-user JWT for automatic RLS tenant isolation
client = EasyRagClient(user_jwt="eyJhbGci...")

# 1. Sync markdown knowledge base in parallel (SHA-256 incremental)
client.sync_directory("./docs", max_workers=8)

# 2. Search with Hybrid RRF & Parent-Context Expansion
results = client.search_hybrid(
    query="PostgreSQL connection pooling guidelines",
    match_count=5,
    candidate_count=50,
    rrf_k=60,
    expand_context="section",  # "section" or "document"
)

for item in results:
    print(f"[{item.final_score:.4f}] {item.document_title} > {item.section_title}")
    print(item.effective_text[:200] + "...\n")

📊 Evaluation & Latency Benchmarks

Empirical evaluation against the Google Research TyDi QA multilingual gold-standard benchmark (5,077 natural queries, 4,488 authentic Wikipedia articles across 11 typologically diverse languages) and direct execution on PostgreSQL 16 + pgvector:

1. Retrieval Accuracy & Quality (TyDi QA Global Benchmark)

Benchmark Metric Score Description
Document Hit Rate @ 1 (Top-1) 88.46% Ground-truth document ranked #1 (Strict Document Match)
Document Hit Rate @ 3 (Top-3) 91.61% Ground-truth document in Top-3 chunks
Document Hit Rate @ 5 (Top-5) 92.34% Ground-truth document in Top-5 chunks
Document Hit Rate @ 10 (Top-10) 92.75% Ground-truth document in Top-10 chunks
Document MRR (Mean Reciprocal Rank) 0.9012 Average reciprocal rank on document retrieval
Answer Span Recall @ 5 91.90% Exact fact-answer span contained in Top-5 chunks

2. Execution Latency & Ingestion Throughput

Component Metric Value Details
Hybrid SQL Query Latency Mean 21.34 ms Single round-trip SQL (pgvector HNSW + FTS GIN + RRF fusion)
p50 21.42 ms Zero client-side post-processing
p95 22.09 ms Predictable tail latency on PostgreSQL 16
Ingestion & Verification Throughput 651.5 docs/sec 4,488 documents verified via SHA-256 in 6.89s (16 workers)

3. Multilingual Breakdown Across 11 Languages

Language Queries Doc Hit @ 1 Doc Hit @ 5 Doc MRR Answer Recall @ 5
Russian 828 91.5% 93.8% 0.926 93.2%
Finnish 920 90.0% 93.0% 0.913 92.9%
Arabic 964 89.2% 92.8% 0.908 92.0%
Telugu 668 89.1% 92.8% 0.906 93.1%
Indonesian 499 89.4% 91.8% 0.903 91.6%
Swahili 475 87.4% 92.6% 0.895 91.6%
English 278 87.1% 89.9% 0.883 91.0%
Japanese 139 82.0% 89.2% 0.854 88.5%
Bengali 111 76.6% 91.9% 0.834 90.1%
Korean 194 75.8% 85.0% 0.795 83.0%

⚙️ Engineering & Security Highlights

  • ☁️ Live Cloud Supabase Tested: Validated against live Supabase Cloud (PostgreSQL 17.6 in eu-north-1). See CLOUD_EVAL_REPORT.md.
  • 🐘 PostgreSQL 16 + pgvector CI: GitHub Actions integration tests against live pgvector/pgvector:pg16 containers with real HNSW index scans, GIN full-text index scans, and database triggers.
  • 🔒 Strict RLS Tenant Isolation: Zero cross-tenant data leakage across vector, FTS, and hybrid retrieval with PostgreSQL auth.uid().
  • 🎯 Filtered ANN Recall Preservation: Candidate oversampling (candidate_count) and iterative scan (hnsw.iterative_scan = 'relaxed_order') prevent candidate starvation under metadata/tenant filters.
  • 📖 Parent-Context Expansion: Searches granular 400-token chunks for precision, returns full parent sections for LLM context.
  • 🌍 Multilingual FTS & Fallbacks: Native dictionary stemming and fallback support across 11 languages (English, Russian, Arabic, Finnish, and more).

💻 Python SDK Usage

1. Hybrid Search with Parent-Context Expansion

from supabase_easy_rag import EasyRagClient

# Pass the end-user JWT for automatic RLS tenant isolation
client = EasyRagClient(user_jwt="eyJhbGci...")

# Search by dense chunk, expand to full parent section for LLM context
results = client.search_hybrid(
    query="PostgreSQL connection pooling guidelines",
    match_count=5,
    candidate_count=50,
    rrf_k=60,
    expand_context="section",  # "section" or "document"
)

for item in results:
    print(f"[{item.final_score:.4f}] {item.document_title} > {item.section_title}")
    print(item.effective_text[:200] + "...")

2. High-Throughput Parallel Directory Ingestion

# Sync a directory of Markdown documents with 8 parallel workers
sync_stats = client.sync_directory(
    directory_path="./knowledgebase_docs",
    batch_size=30,
    max_workers=8,
    enable_chunking=True,
    chunk_size=800,
    chunk_overlap=100,
)

print(f"Synced {sync_stats['total_files']} files in parallel.")

3. Asynchronous Client (FastAPI / Async Runtimes)

from supabase_easy_rag import AsyncEasyRagClient

async_client = AsyncEasyRagClient()

results = await async_client.search_hybrid(
    query="Distributed consensus election timeouts",
    match_count=3,
    expand_context="section",
)

🧪 Local Docker & CI Testing

Run the full integration test suite against a local PostgreSQL container with pgvector:

# 1. Start local Postgres container with pgvector and run all 59 tests:
./scripts/run_local_postgres_tests.sh

# Or run via docker-compose manually:
docker compose -f docker-compose.test.yml up -d
POSTGRES_URL="postgresql://postgres:postgres@localhost:5432/postgres" python -m unittest discover tests -v

# Run local Postgres retrieval evaluation:
POSTGRES_URL="postgresql://postgres:postgres@localhost:5432/postgres" python eval/local_postgres_eval.py

🛠️ CLI Commands

# Export migration files
easy-rag init-sql --dimensions 1536 --output ./migrations

# Sync directory of documents
easy-rag sync ./docs --workers 8

# Execute test query with diagnostics
easy-rag query "What is distributed erasure coding?" --mode hybrid --count 5

# Manage backend API access tokens
easy-rag create-token "Production Ingestion Worker"
easy-rag list-tokens

⚙️ Architecture & Implementation Details

  • Two-Stage Hybrid Fusion: Independent candidate pools are retrieved via indexed scans (HNSW for vector distance, GIN for full-text match) and fused using Reciprocal Rank Fusion: $$RRF_Score = \frac{w_v}{k + rank_v} + \frac{w_t}{k + rank_t}$$ This avoids arbitrary score normalization issues between cosine similarities and BM25/FTS weights.
  • Iterative Graph Traversal: Employs hnsw.iterative_scan = 'relaxed_order' and dynamic p_ef_search to prevent candidate starvation when applying strict metadata or tenant filters.
  • Weighted Lexical Search: Uses PostgreSQL native setweight() indexing where document titles receive Weight A ($1.0$), section headings receive Weight B ($0.4$), and chunk text receives Weight D ($0.1$).
  • Multi-Tenant Security: Enforces database-level isolation via Supabase Auth (auth.uid()) using non-recursive Row-Level Security (RLS) policies on documents and chunks.

📄 License

Distributed under the MIT License. See LICENSE for details.

Metadata

Release files for supabase-easy-rag 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for supabase-easy-rag 0.3.0
File Size Uploaded
supabase_easy_rag-0.3.0.tar.gz 137.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for supabase-easy-rag 0.3.0
File Interpreter ABI Platform
supabase_easy_rag-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 180.1 kB

Release files / supabase_easy_rag-0.3.0.tar.gz

Download URL supabase_easy_rag-0.3.0.tar.gz
Size 137.5 kB
Tags Source
SHA-256 checksum
How to use checksums
042f8f4a0dcecf1d42cf6dc38ab836843034ff4a7ea89a0f984eba37f5b2f23f
BLAKE2b-256 checksum
How to use checksums
c1cb8dd817374aa341364ed0dfacd5981206d3caa98d5c520cdbb5b80558f4a8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.11 {"installer":{"name":"uv","version":"0.10.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / supabase_easy_rag-0.3.0-py3-none-any.whl

Download URL supabase_easy_rag-0.3.0-py3-none-any.whl
Size 42.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9b2a77a9430b1485b2d7e5c47c653a85147f484784217b5bd7efa70b4f50186e
BLAKE2b-256 checksum
How to use checksums
6faa7b8cb189d4545f4f7acbfbe426bedd5155055584488e8160960652e51224
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.11 {"installer":{"name":"uv","version":"0.10.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

0.5.0

2 release files

0.4.0

2 release files

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page