Realiza una búsqueda de similitud vectorial con Vertex AI

Te damos la bienvenida a la búsqueda de similitud de vectores de Firebase Data Connect, la implementación de Firebase de la búsqueda semántica que se integra con Google Vertex AI.

En el centro de esta función se encuentran las incorporaciones de vectores, que son arreglos de números de punto flotante que representan el significado semántico del texto o los medios. Si ejecutas una búsqueda de vecinos más cercanos con un embedding de vector de entrada, puedes encontrar todo el contenido semánticamente similar. Data Connect usa la extensión pgvector de PostgreSQL para esta capacidad.

Esta potente búsqueda semántica puede impulsar casos de uso, como motores de recomendaciones y motores de búsqueda. También es un componente clave en la generación mejorada por recuperación en los flujos de IA generativa. La documentación de Vertex AI es un excelente lugar para obtener más información.

Puedes confiar en la compatibilidad integrada de Data Connect para generar embeddings de vectores automáticamente con la API de Embeddings de Vertex AI o usar esa API para generarlos de forma manual.

Requisitos previos

  • Configura Data Connect para tu proyecto.

  • Habilita las APIs de Vertex AI.

Configuración

Puedes elegir entre un flujo de desarrollo local (si eres desarrollador web, de Kotlin para Android o de iOS) o un flujo de IDX (para desarrolladores web). Puedes usar una base de datos local o tu proyecto de producción Data Connect y su instancia de Cloud SQL para PostgreSQL para el desarrollo.

En estas instrucciones, se supone que creaste tu proyecto de Data Connect siguiendo la guía de inicio rápido.

Integración con PostgreSQL local

  1. Configura una instancia local de PostgreSQL.
  2. Otórgate el rol de IAM de usuario de Vertex AI.
  3. Configura las credenciales predeterminadas de la aplicación de Google Cloud en tu entorno.
  4. Instala la extensión pgvector en tu instancia local de PostgreSQL.
  5. Habilita la extensión con CREATE EXTENSION vector según las instrucciones del repositorio pgvector.

Integración con IDX

  1. Configura tu espacio de trabajo de IDX con la plantilla de Data Connect.
  2. Otórgate el rol de IAM de usuario de Vertex AI.
  3. Habilita la extensión con CREATE EXTENSION vector según las instrucciones del repositorio pgvector.

Diseña tu esquema

Para realizar una búsqueda vectorial, agrega un campo nuevo de tipo Vector a tu esquema. Por ejemplo, si deseas realizar una búsqueda semántica con descripciones de películas, agrega un campo para contener los embeddings de vectores asociados con la descripción de la película. En este esquema, se agrega descriptionEmbedding para almacenar embeddings de vectores para el 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)
 // ...
}

Genera y recupera embeddings

Data Connect brinda compatibilidad integrada con los embeddings de vectores con el valor del servidor _embed. Esto dirige a Data Connect para que genere embeddings de vectores llamando internamente a las APIs de Embedding de Vertex AI. El valor del servidor _embed se puede usar en mutaciones y consultas.

Mutaciones

Genera y almacena un embedding a través de Data Connect

En tu app de búsqueda de vectores, es probable que desees solicitar que se generen los embeddings en cuanto agregues registros a tu base de datos. Aquí, una mutación createMovie agrega un registro de película a la tabla Movie y también pasa una descripción de la película con una incorporación model especificada.

mutation createMovie($title: String!, $description: String!) {
  movie_insert(data: {
    title: $title,
    description: $description,
    descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: $description}
  })
}

En algunos casos, es posible que desees actualizar la descripción y la incorporación de la película.

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

Para llamar a la última mutación desde un cliente, haz lo siguiente:

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

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

// Use the response

Consultas

Recupera embeddings de vectores con una consulta como la siguiente. Ten en cuenta que el descriptionEmbedding que devuelve la búsqueda es un array de números de punto flotante, que, por lo general, no es legible para los humanos. Por lo tanto, los SDKs generados por Data Connect no admiten su devolución directa.

Puedes usar los embeddings de vectores que se muestran para realizar una búsqueda de similitud, como se describe en la siguiente sección.

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

Realiza una búsqueda de similitud

Ahora podemos realizar la búsqueda de similitud.

Para cada campo Vector, Data Connect genera una función de GraphQL que implementa la búsqueda por similitud. El nombre de esta función generada es ${pluralType}_${vectorFieldName}_similarity. Admite algunos parámetros, como se muestra en los siguientes ejemplos y en la lista de referencia.

Puedes definir una función de GraphQL que invoque la búsqueda por similitud. Como se mencionó anteriormente, el valor del servidor _embed dirige Data Connect para generar los embeddings de vectores con las APIs de Embedding de Vertex AI, en este caso, para crear embeddings para la cadena de búsqueda que se usa para la comparación con los embeddings de la descripción de la película.

En este ejemplo, la búsqueda de similitud devolverá hasta 5 películas cuya descripción sea semánticamente más cercana a la consulta de entrada. El conjunto de resultados se ordena de forma ascendente según la distancia, del más cercano al más lejano.

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

Ajusta la consulta de similitud

Los valores predeterminados para los parámetros de búsqueda, como method y within, funcionan bien para la mayoría de los casos de uso. Sin embargo, si observas que tu búsqueda devuelve resultados demasiado diferentes o que faltan resultados que quieres incluir, intenta ajustar estos parámetros.

Para encontrar un valor adecuado para within, podemos agregar _metadata.distance a los campos seleccionados para ver qué tan lejos está cada resultado del vector de búsqueda. Según los valores de distance que se devuelven, podemos establecer el parámetro within. Solo se incluirán los resultados con una distancia inferior al valor de within:

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

También puedes experimentar con diferentes funciones de distancia configurando el parámetro method.

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

Ten en cuenta que los diferentes métodos devuelven valores muy diferentes para la distancia: si configuraste within, deberás volver a ajustar ese valor después de cambiar method.

Llama a la consulta de similitud

Para llamar a una búsqueda de similitud desde el código del cliente, haz lo siguiente:

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

const response = await searchMovieDescriptionUsingL2similarity({ query });

// Use the response

Usa incorporaciones personalizadas

Data Connect también te permite trabajar con las incorporaciones directamente como Vectors en lugar de usar el valor del servidor _embed para generarlas.

Almacena una incorporación personalizada

Con la API de Vertex Embeddings, especifica un modelo de coincidencia y solicita resultados de incorporación de la dimensión correcta.

Luego, convierte el array de números de punto flotante que se devolvió en un Vector para pasarlo a la operación de actualización para el almacenamiento.

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

Realiza una búsqueda de similitud con embeddings personalizados

Realiza la misma operación para recuperar los embeddings de los términos de búsqueda y convertirlos en Vectors.

Luego, llama a la consulta _similarity para realizar cada búsqueda.

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
      }
  }

Implementar en producción

Implementa tu esquema y conector

El último paso en una iteración típica de Data Connect es implementar tus recursos en producción.

Cuando implementas tu esquema que contiene tipos Vector en Cloud SQL con el comando firebase deploy, la CLI de Firebase toma las medidas necesarias para habilitar la generación de embeddings basada en Vertex AI en tu instancia de Cloud SQL.

firebase deploy --only dataconnect

Si deseas habilitar la compatibilidad con la incorporación en tu instancia de Cloud SQL de forma manual o si encuentras un error de la CLI, sigue estas instrucciones.

Sintaxis de la búsqueda de vectores

Extensiones de esquema

El tipo de datos Vector de Data Connect se asigna al tipo vector de PostgreSQL, según se define en la extensión pgvector. El tipo vector de pgvector se almacena como un array de números de punto flotante de precisión simple en PostgreSQL.

En Data Connect, el tipo Vector se representa como un array de números JSON. Las entradas se coercen en un array de valores float32. Si la coerción falla, se genera un error.

Usa el parámetro de tamaño de la directiva @col para establecer las dimensiones del vector.

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

size solo se admite para los tipos Vector. Las operaciones de Vector, como la búsqueda de similitud, requieren que todos los Vector tengan la misma cantidad de dimensiones.

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 del servidor _embed para consultas y mutaciones

_embed

Este valor del servidor dirige el servicio Data Connect para que genere y almacene incorporaciones con las APIs de Embedding de Vertex AI. Este valor del servidor se puede usar en consultas y mutaciones.

Parámetros para la búsqueda de similitud

method: COSINE|INNER_PRODUCT|L2

Es la función de distancia que se usa para buscar vecinos cercanos. Los algoritmos compatibles actualmente son un subconjunto de los algoritmos de búsqueda de pgvector.

within: float

Es una restricción sobre la distancia dentro de la cual se realiza la búsqueda del vecino más cercano.

where: FDC filter condition

Consulta la guía de esquemas, consultas y mutaciones.

limit: int

Es la cantidad de resultados que se devolverán.