Criando Busca de Semelhança Vetorial

Neste artigo, você aprenderá como implementar a busca de semelhança vetorial no PostgreSQL utilizando a extensão pgvector, permitindo que você encontre resultados semanticamente semelhantes com base no significado, em vez de apenas corresponder palavras-chave. Os tópicos que abordaremos incluem a construção de uma busca de semelhança vetorial no PostgreSQL com pgvector, como a busca funciona quando os usuários sabem exatamente o que estão procurando, mas falha quando a intenção é descrita em linguagem natural.

A busca funciona bem quando os usuários sabem exatamente o que estão procurando, mas falha quando a intenção é descrita em linguagem natural. Um usuário que procura por “algo quente e respirável para trekking em alta altitude” obterá resultados pobres de um índice de palavras-chave, pois as palavras nessa consulta raramente alinham com as palavras nos seus dados. É aqui que a busca de semelhança se torna útil. Em vez de corresponder palavras-chave, ela encontra resultados com base no significado, conectando a intenção do usuário a registros relevantes, mesmo quando a redação difere completamente.

Este artigo mostra como implementar a busca de semelhança no PostgreSQL utilizando pgvector. Você aprenderá como configurar a extensão, armazenar embeddings vetoriais no seu banco de dados e executar consultas de semelhança usando SQL puro, sem um banco de dados de vetores separado. Um embedding vetorial é uma lista de números de ponto flutuante que representa o significado de um pedaço de dados, não seus caracteres ou palavras-chave. Os números são produzidos por um modelo de aprendizado de máquina treinado para colocar conteúdo semanticamente semelhante próximo um do outro em um espaço numérico de alta dimensão.

Duas frases que falam sobre o mesmo conceito produzirão embeddings que estão numericamente próximos, mesmo que não compartilhem nenhuma palavra. Considere as seguintes duas frases: um modelo de embedding colocaria seus vetores perto um do outro nesse espaço. Essa proximidade é o que torna a busca de semelhança funcionar: você incorpora a consulta do usuário, encontra os vetores armazenados mais próximos a ele e retorna essas linhas.

A geração de embeddings depende do modelo utilizado. Você pode escolher entre várias opções; as mais comuns para tentar são: o MTEB Leaderboard é uma referência padrão para comparar modelos de embedding. Uma regra se aplica independentemente da sua escolha: a dimensão configurada na sua coluna PostgreSQL deve corresponder exatamente à dimensão que o modelo produz.

Pgvector é uma extensão de código aberto do PostgreSQL que adiciona busca vetorial nativa ao seu banco de dados existente. Em vez de mover seus embeddings para um armazenamento de vetores dedicado, pgvector os mantém ao lado dos dados relacionais, preservando as garantias transacionais do PostgreSQL, a semântica de JOIN, a recuperação em um momento específico e a linguagem de consulta SQL completa.

A extensão adiciona um tipo de dados vetorial para armazenar embeddings, operadores de distância SQL para ordenar os resultados da consulta por semelhança e dois tipos de índice – HNSW e IVFFlat – para acelerar a busca de vizinhos mais próximos em escalas. Ela também suporta tipos de vetores de precisão dupla, binários e esparsos. pgvector suporta PostgreSQL 13 e posterior. O guia de instalação no repositório cobre todas as plataformas em detalhes; os caminhos mais comuns são mostrados abaixo.

No Linux, no Debian e Ubuntu, o pacote APT é a rota mais rápida. Substitua 18 pela sua versão principal do PostgreSQL: para compilar a partir do código-fonte em vez disso, o que funciona em qualquer distribuição Linux, use: no macOS, se você estiver em um Mac, Homebrew é a opção mais simples: os passos de compilação de código-fonte acima funcionam identicamente no macOS com as Ferramentas de Linha de Comando do Xcode instaladas.

Para Windows, Docker e conda-forge, consulte as notas de instalação no repositório. Uma vez instalado, ative a extensão no seu banco de dados de destino. Você só precisa fazer isso uma vez por banco de dados: agora que a extensão está instalada e ativada, podemos começar a usá-la. Vamos construir um catálogo de produtos para uma loja de equipamentos de outdoor. Cada produto tem uma descrição de texto e armazenaremos um embedding dessa descrição para que os usuários possam procurar por significado.

A coluna vector(1536) contém um embedding por linha. Esse número deve corresponder à saída da dimensão do seu modelo; ajuste-o de acordo se você usar um diferente. Para este artigo, usaremos uma tabela de teste menor com vetores tridimensionais para manter os exemplos legíveis: na prática, você chamaria uma API de embedding em cada descrição de produto no momento da inserção e armazenaria o vetor retornado.

Aqui, usamos valores tridimensionais artesanais que melhor explicam o princípio de agrupamento: os itens de calçado compartilham valores semelhantes do primeiro componente, os itens de iluminação se agrupam em torno do segundo e as mochilas compartilham valores semelhantes do terceiro componente. Os embeddings de um modelo se comportam da mesma maneira. Agora podemos procurar produtos semelhantes a um vetor de consulta.

Imagine que um usuário pergunta por “calçado para trilha para terreno difícil”. Seu aplicativo incorpora essa frase e, digamos, recebe [0,80, 0,19, 0,40] de volta do modelo. Aqui está como você encontra os vizinhos mais próximos: a saída: o operador <-> calcula a distância L2 – a distância em linha reta entre dois pontos no espaço vetorial. Valores mais baixos significam mais próximos e, portanto, mais semelhantes.

Os dois itens de calçado classificam-se no topo, o que é o que esperaríamos. A busca de semelhança vetorial no PostgreSQL com pgvector é uma ferramenta poderosa para encontrar