Supabase Vector intègre l’extension PostgreSQL pgvector pour stocker et interroger des embeddings vectoriels. C’est la solution idéale pour construire des moteurs de recherche sémantique, des chatbots RAG (Retrieval-Augmented Generation) et des systèmes de recommandation.
Pour les fondations, consultez notre guide complet Supabase. Pour structurer votre table de documents, voir créer et structurer sa base de données Supabase. Pour les fonctions de recherche, voir SQL, triggers et fonctions Supabase. Pour déployer vos Edge Functions d’indexation, voir Edge Functions Supabase. Pour la connexion IA via MCP, voir Supabase MCP.
Qu’est-ce qu’un Embedding Vectoriel ?
Un embedding est une représentation numérique d’un texte, image ou autre donnée sous forme de vecteur (tableau de flottants). Des textes sémantiquement proches ont des vecteurs proches dans l’espace vectoriel.
"Supabase est une alternative à Firebase"
→ [0.23, -0.45, 0.67, 0.12, ...] (1536 dimensions pour OpenAI)
"Supabase remplace Firebase"
→ [0.24, -0.43, 0.65, 0.13, ...] (très proche !)
"La recette de la tarte aux pommes"
→ [-0.56, 0.89, -0.23, 0.45, ...] (très différent)
Activer pgvector dans Supabase
-- Activer l'extension pgvector
CREATE EXTENSION IF NOT EXISTS vector;
-- Créer une table avec colonne vectorielle
CREATE TABLE documents (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
content TEXT NOT NULL,
metadata JSONB,
embedding vector(1536), -- 1536 dimensions pour OpenAI text-embedding-ada-002
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Index HNSW (recommandé : plus rapide pour la recherche)
CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
Générer des Embeddings avec OpenAI
import OpenAI from 'openai'
import { createClient } from '@supabase/supabase-js'
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY })
const supabase = createClient(URL, SERVICE_ROLE_KEY)
async function generateEmbedding(text: string): Promise<number[]> {
const response = await openai.embeddings.create({
model: 'text-embedding-ada-002',
input: text.replace(/\n/g, ' ')
})
return response.data[0].embedding
}
// Indexer un document
async function indexDocument(content: string, metadata = {}) {
const embedding = await generateEmbedding(content)
const { data, error } = await supabase
.from('documents')
.insert({ content, metadata, embedding })
.select()
return { data, error }
}
Recherche Sémantique
-- Fonction SQL de recherche vectorielle
CREATE OR REPLACE FUNCTION match_documents(
query_embedding vector(1536),
match_threshold float DEFAULT 0.7,
match_count int DEFAULT 10
)
RETURNS TABLE (
id UUID,
content TEXT,
metadata JSONB,
similarity float
)
LANGUAGE sql STABLE
AS $$
SELECT
id,
content,
metadata,
1 - (embedding <=> query_embedding) AS similarity
FROM documents
WHERE 1 - (embedding <=> query_embedding) > match_threshold
ORDER BY embedding <=> query_embedding
LIMIT match_count;
$$;
// Côté JavaScript
async function semanticSearch(query: string, threshold = 0.7, limit = 10) {
const queryEmbedding = await generateEmbedding(query)
const { data, error } = await supabase.rpc('match_documents', {
query_embedding: queryEmbedding,
match_threshold: threshold,
match_count: limit
})
return { data, error }
}
RAG : Chatbot avec Contexte
async function ragChat(question: string) {
// 1. Trouver les documents pertinents
const { data: relevantDocs } = await semanticSearch(question, 0.75, 5)
// 2. Construire le contexte
const context = relevantDocs
?.map(doc => doc.content)
.join('\n\n---\n\n')
// 3. Envoyer au LLM avec le contexte
const response = await openai.chat.completions.create({
model: 'gpt-4o-mini',
messages: [
{
role: 'system',
content: `Tu es un assistant. Réponds en te basant UNIQUEMENT sur le contexte.
Contexte:
${context}`
},
{ role: 'user', content: question }
],
temperature: 0.2
})
return {
answer: response.choices[0].message.content,
sources: relevantDocs?.map(d => d.metadata)
}
}
Supabase AI + vecs (Python)
pip install vecs openai
import vecs
vx = vecs.create_client("postgresql://postgres:password@db.[ref].supabase.co:5432/postgres")
docs = vx.get_or_create_collection(name="documents", dimension=1536)
docs.upsert(
records=[
("doc-1", [0.1, 0.2, ...], {"title": "Introduction"}),
("doc-2", [0.3, 0.4, ...], {"title": "Guide avancé"}),
]
)
docs.create_index()
results = docs.query(
data=[0.15, 0.25, ...],
limit=5,
include_metadata=True
)
👉 Articles du guide Supabase
Cet article fait partie du Guide Complet Supabase 2026. Retrouvez les autres articles :
- ✅ Supabase : Le Guide Complet 2026
- ✅ Supabase vs Firebase : Comparatif Complet 2026
- ✅ Installer Supabase en Local avec Docker
- ✅ Supabase Pricing : Quel Plan Choisir en 2026
- ✅ Architecture Supabase : Postgres, GoTrue, Realtime et Storage
- ✅ Créer et Structurer sa Base de Données Supabase
- ✅ Supabase RLS : Sécuriser ses Données avec Row Level Security
- ✅ Supabase SQL : Triggers, Fonctions et Procédures Stockées
- ✅ Supabase Migrations : Gérer l’Évolution de son Schéma
- ✅ Supabase Auth : Email, OAuth et Magic Links
- ✅ Supabase Rôles et Permissions
- ✅ Supabase JWT : Comprendre les Tokens
- ✅ Supabase avec Next.js : App Router
- ✅ Supabase avec React : Hooks et Contexte
- ✅ API REST Supabase : Requêtes sans Backend
- ✅ Supabase Edge Functions : Serverless avec Deno
- ✅ Supabase Realtime : Synchronisation en Temps Réel
- ✅ Supabase Storage : Gérer les Fichiers et Images
- 📅 Supabase MCP — à paraître le 04/07
- 📅 Déploiement en production — à paraître le 06/07
- 📅 CLI Supabase — à paraître le 08/07

