Realizar a pesquisa de similaridade vetorial com a Vertex AI

Conheça a pesquisa de semelhança vetorial do Firebase Data Connect, a implementação da pesquisa semântica do Firebase que se integra à Google Vertex AI.

O recurso é baseado em embeddings vetoriais, que são matrizes de números de ponto flutuante que representam o significado semântico do texto ou da mídia. Ao executar uma pesquisa de vizinho mais próximo usando um embedding de vetor de entrada, você pode encontrar todo conteúdo semanticamente semelhante. O Data Connect usa a extensão pgvector do PostgreSQL para esse recurso.

Essa pesquisa semântica poderosa pode impulsionar casos de uso como mecanismos de recomendação e mecanismos de pesquisa. Ele também é um componente importante na geração de recuperação aprimorada em fluxos de IA generativa. A documentação da Vertex AI é um ótimo lugar para aprender mais.

Você pode usar o suporte integrado do Data Connect para gerar embeddings de vetor automaticamente usando a API Embeddings da Vertex AI ou gerá-los manualmente.

Pré-requisitos

  • Configure o Data Connect para seu projeto.

  • Ative as APIs da Vertex AI.

Configuração

Você pode escolher entre um fluxo de desenvolvimento local (se você for um desenvolvedor da Web, Kotlin Android ou iOS) ou um fluxo IDX (para desenvolvedores da Web). É possível usar um banco de dados local ou seu projeto Data Connect de produção e a instância do Cloud SQL para PostgreSQL para desenvolvimento.

Estas instruções pressupõem que você criou o projeto Data Connect seguindo o guia de início rápido.

Integrar com o PostgreSQL local

  1. Configure uma instância local do PostgreSQL.
  2. Conceda a si mesmo o papel do IAM de usuário da Vertex AI.
  3. Configure o Application Default Credentials do Google Cloud no seu ambiente.
  4. Instale a extensão pgvector na sua instância local do PostgreSQL.
  5. Ative a extensão usando CREATE EXTENSION vector de acordo com as instruções do repositório pgvector.

Integrar com o IDX

  1. Configure seu espaço de trabalho do IDX usando o modelo do Data Connect.
  2. Conceda a si mesmo o papel de IAM de usuário da Vertex AI.
  3. Ative a extensão usando CREATE EXTENSION vector de acordo com as instruções do repositório pgvector.

Projetar seu esquema

Para realizar a pesquisa de vetor, adicione um novo campo do tipo Vector no esquema. Por exemplo, se você quiser fazer uma pesquisa semântica usando descrições de filmes, adicione um campo para armazenar os embeddings vetoriais associados à descrição do filme. Nesse esquema, descriptionEmbedding é adicionado para armazenar embeddings de vetor para o campo description.

type Movie @table {
 id: ID! @col(name: "movie_id") @default(id: ID! @col(name: "movie_id") @default(expr: "uuidV4()")
 title: String!
 description: String
 descriptionEmbedding: Vector! @col(size:768)
 // ...
}

Gerar e extrair embeddings

O Data Connect oferece suporte integrado a embeddings de vetor com o valor do servidor _embed. Isso direciona Data Connect para gerar embeddings de vetor chamando internamente as APIs de embedding da Vertex AI. O valor do servidor _embed pode ser usado em mutações e consultas.

Mutações

Gerar e armazenar um embedding com Data Connect

No app de pesquisa vetorial, é recomendável solicitar que os embeddings sejam gerados assim que você adicionar registros ao banco de dados. Uma mutação createMovie adiciona um registro de filme à tabela Movie e também transmite uma descrição do filme com um model de incorporação especificado.

mutation createMovie($movieData: Movie_Data! @pick(fields: ["title", "genre", "description"])) {
  movie_insert(data: {
    ...movieData,
    descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: $movieData.description}
  })
}

Em alguns casos, talvez você queira atualizar a descrição e a incorporação do filme.

mutation updateDescription($id: String!, $description: String!) {
  movie_update(id: $id, data: {
    description: $description,
    descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: $description}
  })
}

Para chamar a última mutação de um cliente:

import { updateMovieDescriptionWithEmbed } from 'lib/dataconnect-sdk/';

await updateMovieDescriptionWithEmbed({ id: movieId, description: description});

// Use the response

Consultas

Extraia embeddings de vetor usando uma consulta como esta. O descriptionEmbedding retornado pela consulta é uma matriz de números flutuantes, que normalmente não é legível por humanos. Portanto, os SDKs gerados por Data Connect não têm suporte para devolução direta.

É possível usar os embeddings de vetor retornados para fazer pesquisas de similaridade, conforme descrito na próxima seção.

query getMovieDescription($id: String!) @auth(is: PUBLIC) {
 movie(id: $id)
   id
   description
   descriptionEmbedding
}

Realizar pesquisa de similaridade

Agora podemos realizar a pesquisa de similaridade.

Para cada campo Vector, o Data Connect gera uma função GraphQL que implementa a pesquisa de similaridade. O nome dessa função gerada é ${pluralType}_${vectorFieldName}_similarity. Ele oferece suporte a alguns parâmetros, conforme mostrado nos exemplos a seguir e na lista de referência.

É possível definir uma função do GraphQL que invoca a pesquisa de similaridade. Como mencionado acima, o valor do servidor _embed direciona Data Connect para gerar os embeddings de vetor usando as APIs Embedding da Vertex AI. Nesse caso, para criar embeddings para a string de pesquisa usada na comparação com os embeddings de descrição de filmes.

Neste exemplo, a pesquisa de similaridade vai retornar até cinco filmes com a descrição mais próxima semanticamente da consulta de entrada. O conjunto de resultados é classificado na ordem crescente da distância, da mais próxima à mais distante.

query searchMovieDescriptionUsingL2Similarity ($query: String!) @auth(level: PUBLIC) {
    movies_descriptionEmbedding_similarity(
      compare_embed: {model: "textembedding-gecko@003", text: $query},
      method: L2,
      within: 2,
      where: {content: {ne: "No info available for this movie."}}, limit: 5)
      {
        id
        title
        description
      }
  }

Chamar a consulta de semelhança

Para chamar uma pesquisa de similaridade no código do cliente:

import { searchMovieDescriptionUsingL2similarity} from 'lib/dataconnect-sdk';

const response = await searchMovieDescriptionUsingL2similarity({ query });

// Use the response

Usar incorporações personalizadas

O Data Connect também permite trabalhar com incorporações diretamente como Vectors, em vez de usar o valor do servidor _embed para gerá-las.

Armazenar um embedding personalizado

Usando a API Vertex Embeddings, especifique um modelo correspondente e solicite os resultados de embedding da dimensão correta.

Em seguida, converta a matriz de números flutuantes retornada em um Vector para transmitir à operação de atualização para armazenamento.

mutation updateDescription($id: String!, $description: String!, $descriptionEmbedding: Vector!) {
  movie_update(id: $id, data: {
    // title, genre...
    description: $description,
    descriptionEmbedding: $descriptionEmbedding
  })
}

Realizar pesquisa de similaridade usando embeddings personalizados

Realize a mesma operação para extrair embeddings de termos de pesquisa e transmiti-los a Vectors.

Em seguida, chame a consulta _similarity para realizar cada pesquisa.

query searchMovieDescriptionUsingL2Similarity($compare: Vector!, $within: Float, $excludesContent: String, $limit: Int) @auth(level: PUBLIC) {
    movies_descriptionEmbedding_similarity(
      compare: $compare,
      method: L2,
      within: $within,
      where: {content: {ne: $excludesContent}}, limit: $limit)
      {
        id
        title
        description
      }
  }

Implantar para a produção

Implantar o esquema e o conector

A última etapa de uma iteração típica de Data Connect é implantar os recursos na produção.

Ao implantar o esquema que contém tipos Vector no CloudSQL usando o comando firebase deploy, a CLI Firebase executa as etapas necessárias para ativar a geração de embeddings com base na Vertex AI na sua instância do CloudSQL.

firebase deploy --only dataconnect

Se você quiser ativar o suporte de incorporação na instância do CloudSQL manualmente ou encontrar um erro na CLI, siga estas instruções.

Sintaxe da pesquisa de vetor

Extensões de esquema

O tipo de dados Vector de Data Connect é mapeado para o tipo vector do PostgreSQL, conforme definido pela extensão pgvector. O tipo vector do pgvector é armazenado como uma matriz de números de ponto flutuante de precisão única no PostgreSQL.

Em Data Connect, o tipo Vector é representado como uma matriz de números JSON. As entradas são convertidas em uma matriz de valores float32. Se a coerção falhar, um erro será gerado.

Use o parâmetro de tamanho da diretiva @col para definir as dimensões do vetor.

type Question @table {
    text: String!
    category: String!
    textEmbedding: Vector! @col(size: 768)
}

size só é aceito para tipos Vector. As operações Vector, como a pesquisa de similaridade, exigem que todas as Vectors tenham o mesmo número de dimensões.

directive @col(
  # … existing args
  """
  Defines a fixed column size for certain scalar types.

  - For Vector, size is required.
  - For all other types, size is currently unsupported and hence supplying it will result in a schema error.
  """
  size: Int
) on FIELD_DEFINITION

Valor do servidor _embed para consultas e mutações

_embed

Esse valor do servidor direciona o serviço Data Connect para gerar e armazenar embeddings usando as APIs de embedding da Vertex AI. Esse valor do servidor pode ser usado em consultas e mutações.

Parâmetros para pesquisa de similaridade

method: COSINE|INNER_PRODUCT|L2

A função de distância usada para pesquisar vizinhos próximos. Os algoritmos com suporte atualmente são um subconjunto de algoritmos de pesquisa de pgvector.

within: float

Uma restrição na distância em que a pesquisa de vizinho mais próximo é realizada.

where: FDC filter condition

Consulte o guia de esquemas, consultas e mutações.

limit: int

O número de resultados a serem retornados.