DOCUMENTAÇÃO

Busca vetorial

Todo projeto do Espobase inclui pgvector. Guarde embeddings ao lado dos seus dados, indexe-os e encontre as linhas mais parecidas: para busca semântica, recomendações ou respostas a perguntas sobre o seu próprio conteúdo.

← Toda a documentação

Como funciona

  • Um embedding é uma lista de números que descreve o significado de um texto ou de uma imagem. Seu app o obtém do provedor de IA dele (por exemplo, text-embedding-3-small da OpenAI, 1536 números). O Espobase guarda e pesquisa embeddings; ele não os cria.
  • Uma coluna vector(1536) guarda um embedding por linha. Significados parecidos têm uma distância pequena, então as linhas mais próximas são os melhores resultados.
  • O pgvector já vem configurado em todo projeto: nenhuma extensão para instalar, nenhuma configuração. Ele funciona no Editor SQL, no Editor de tabelas (tipo de coluna vector) e no construtor com IA.

1. Crie uma tabela

No Editor SQL do seu projeto:

create table documents (
  id bigint generated always as identity primary key,
  content text not null,
  embedding vector(1536) not null
);

-- Fast similarity search (cosine distance)
create index on documents using hnsw (embedding vector_cosine_ops);

-- Who may read: row level security is on for every table
create policy "Anyone can read documents" on documents
  for select using (true);

Ou peça ao construtor com IA, por exemplo: “uma tabela documents com um embedding para busca semântica”. Ele propõe a coluna vector e o índice de similaridade para você revisar.

2. Adicione uma função de busca

Uma busca por similaridade é uma pequena função SQL. Você a cria uma vez; seu app a chama pela API REST.

create function match_documents(query_embedding vector(1536), match_count int)
returns table (id bigint, content text, similarity float)
language sql stable
as $$
  select id, content, 1 - (embedding <=> query_embedding) as similarity
  from documents
  order by embedding <=> query_embedding
  limit match_count
$$;

A função é executada como o usuário que a chama, então a segurança em nível de linha se aplica: um usuário conectado só encontra as linhas que as políticas dele permitem.

3. Guarde e busque a partir do seu app

import { createClient } from "@espobase/client";

const espobase = createClient(PROJECT_URL, PUBLISHABLE_KEY);

// Store: your app gets the embedding from its AI provider (1536 numbers).
await espobase.from("documents").insert({
  content: "How to reset your password",
  embedding: JSON.stringify(embedding),
});

// Search: the 5 most similar documents to the user's question.
const { data } = await espobase.rpc("match_documents", {
  query_embedding: JSON.stringify(questionEmbedding),
  match_count: 5,
});

Os vetores trafegam como texto, por exemplo [0.12,-0.03,…]. Usando a API REST diretamente, chame POST /rest/v1/rpc/match_documents com o mesmo corpo JSON.

Bom saber

  • Distâncias: <=> cosseno, <-> euclidiana (L2), <#> produto interno negativo. Use a classe de operadores do índice que corresponde às suas consultas (vector_cosine_ops, vector_l2_ops, vector_ip_ops).
  • Os índices HNSW suportam até 2.000 dimensões.
  • Criar um índice sobre muitas linhas existentes leva algum tempo. Crie o índice primeiro ou crie índices grandes por uma conexão direta com o banco de dados.
  • Os embeddings contam para o armazenamento de banco de dados do seu plano (1536 dimensões ≈ 6 KB por linha).