Configurando o Supabase para RAG
Para utilizar a funcionalidade de Retrieval-Augmented Generation (RAG), seu projeto no Supabase precisa ser configurado. Execute os scripts SQL abaixo no seu SQL Editor para preparar seu banco de dados.
1Habilitar a extensão pgvector
A extensão pgvector
é essencial para trabalhar com embeddings e realizar buscas por similaridade.
-- Habilita a extensão para cálculos vetoriais
create extension if not exists vector;
2Criar a tabela de documentos
Esta tabela irá armazenar o conteúdo dos seus documentos, metadados e os vetores de embedding.
-- Cria a tabela para armazenar os documentos e seus embeddings
create table if not exists documents (
id bigint primary key generated always as identity,
filename text,
content text,
metadata jsonb,
fts tsvector generated always as (to_tsvector('english', content)) stored,
embedding vector(1536)
);
3Criar índices para otimização
Índices são cruciais para garantir que as buscas na tabela `documents` sejam rápidas e eficientes.
-- Cria um índice GIN para busca full-text
create index if not exists idx_documents_fts on documents using gin(fts);
-- Cria um índice HNSW para busca vetorial por similaridade
create index if not exists idx_documents_embedding on documents using hnsw (embedding vector_ip_ops);
4Criar a função de busca híbrida
Esta função combina a busca por palavra-chave (full-text) com a busca por similaridade semântica (vetorial) para retornar os resultados mais relevantes.
-- Cria a função que combina busca semântica e full-text
create or replace function hybrid_search(
query_text text,
query_embedding vector(1536),
match_count int,
full_text_weight float = 1,
semantic_weight float = 1,
rrf_k int = 50
)
returns setof documents
language sql
as $$
with full_text as (
select
id,
row_number() over(order by ts_rank_cd(fts, websearch_to_tsquery(query_text)) desc) as rank_ix
from
documents
where
fts @@ websearch_to_tsquery(query_text)
order by rank_ix
limit least(match_count, 30) * 2
),
semantic as (
select
id,
row_number() over (order by embedding <#> query_embedding) as rank_ix
from
documents
order by rank_ix
limit least(match_count, 30) * 2
)
select
documents.*
from
full_text
full outer join semantic
on full_text.id = semantic.id
join documents
on coalesce(full_text.id, semantic.id) = documents.id
order by
coalesce(1.0 / (rrf_k + full_text.rank_ix), 0.0) * full_text_weight +
coalesce(1.0 / (rrf_k + semantic.rank_ix), 0.0) * semantic_weight
desc
limit
least(match_count, 30)
$$;