Patrones de búsqueda híbrida de texto completo y de vectores

En esta página, se describe cómo realizar búsquedas híbridas de texto completo y de vectores en Spanner. La búsqueda híbrida combina la precisión de la concordancia de palabras clave (búsqueda de texto completo, FTS) con la recuperación de la concordancia semántica (búsqueda de vectores) para producir resultados de búsqueda muy pertinentes.

Spanner admite los siguientes patrones de búsqueda híbrida, que se dividen en tres categorías principales:

Categoría Descripción Objetivo principal
Fusion Fusion recupera y clasifica documentos de forma independiente con la búsqueda de palabras clave y de vectores, y luego combina (fusiona) los resultados. Logra la máxima recuperación y pertinencia combinando varios indicadores de puntuación.
Filtered Las palabras clave filtran o refinan el espacio de búsqueda. Asegúrate de que la concordancia de palabras clave sea un requisito mientras aprovechas la pertinencia semántica relevancia.
ML reranking Un modelo de aprendizaje automático refina un conjunto inicial de candidatos para obtener una clasificación final más precisa. Logra la mayor precisión posible para un pequeño conjunto final de resultados.

La búsqueda de Fusion implica ejecutar FTS y la búsqueda de vectores de forma independiente en el mismo corpus de datos. Luego, combina los resultados para crear una lista clasificada única, unificada y muy pertinente.

Si bien puedes ejecutar consultas independientes en el cliente, la búsqueda híbrida en Spanner proporciona las siguientes ventajas:

  • Simplifica la lógica de la aplicación mediante la administración de solicitudes paralelas y la combinación de resultados en el servidor.
  • Evita transferir conjuntos de resultados intermedios potencialmente grandes al cliente.

Puedes usar SQL para crear métodos de fusión en Spanner. En esta sección, se proporcionan ejemplos de fusión de clasificación recíproca y fusión de puntuación relativa. Sin embargo, te recomendamos que evalúes diferentes estrategias de fusión para determinar cuál se adapta mejor a los requisitos de tu aplicación.

Fusión basada en la clasificación

Usa la fusión basada en la clasificación cuando las puntuaciones de pertinencia de diferentes métodos de recuperación (como las puntuaciones de FTS y las distancias de vectores) sean difíciles de comparar o normalizar porque se miden en diferentes espacios. Este método usa la posición de clasificación de cada documento de cada recuperador para generar una puntuación y una clasificación finales.

La fusión de clasificación recíproca (RRF) es una función de fusión basada en la clasificación. La puntuación de RRF para un documento es la suma de los recíprocos de sus clasificaciones de varios recuperadores y se calcula de la siguiente manera:

\[ score\ (d\epsilon D)\ =\ \sum\limits_{r\epsilon R}^{}(1\ /\ (\ 𝑘\ +\ ran{k}_{r}\ (𝑑)\ )\ )\ \]

Aquí:

  • d es el documento.
  • R es el conjunto de recuperadores (FTS y búsqueda de vectores).
  • k es una constante (a menudo establecida en 60) que se usa para moderar la influencia de los documentos con una clasificación muy alta.
  • w es la clasificación del documento del recuperador r.

Implementa RRF en una consulta de Spanner

Las métricas de vectores (como APPROX_DOT_PRODUCT) y las puntuaciones de búsqueda de texto (como SCORE_NGRAMS) operan en escalas incompatibles. Para resolver este problema, en el siguiente ejemplo, se implementa RRF para normalizar los datos en función de la posición de clasificación en lugar de las puntuaciones sin procesar.

La consulta usa UNNEST(ARRAY(...) WITH OFFSET) para asignar una clasificación a los 100 candidatos principales de cada método. Luego, calcula una puntuación estandarizada con la inversa de esas clasificaciones y agrega los resultados para mostrar las cinco coincidencias principales.

SELECT SUM(1 / (60 + rank)) AS rrf_score, key
FROM (
  (
    SELECT rank, x AS key
    FROM UNNEST(ARRAY(
      SELECT key
      FROM hybrid_search
      WHERE embedding IS NOT NULL
      ORDER BY APPROX_DOT_PRODUCT(@vector, embedding,
        OPTIONS => JSON '{"num_leaves_to_search": 50}') DESC
      LIMIT 100)) AS x WITH OFFSET AS rank
  )
  UNION ALL
  (
    SELECT rank, x AS key
    FROM UNNEST(ARRAY(
      SELECT key
      FROM hybrid_search
      WHERE SEARCH_NGRAMS(text_tokens_ngrams, 'foo')
      ORDER BY SCORE_NGRAMS(text_tokens_ngrams, 'foo') DESC
      LIMIT 100)) AS x WITH OFFSET AS rank
  )
)
GROUP BY key
ORDER BY rrf_score DESC
LIMIT 5;

Fusión basada en la puntuación

La fusión basada en la puntuación es eficaz cuando las puntuaciones de pertinencia de diferentes métodos son comparables o puedes normalizarlas, lo que podría permitir una clasificación más precisa que incorpore el peso de pertinencia real de cada método.

La fusión de puntuación relativa (RSF) es un método basado en la puntuación que normaliza las puntuaciones de diferentes métodos en relación con las puntuaciones más altas y más bajas dentro de cada método, por lo general, con las funciones MIN() y MAX(). La puntuación de RSF de un documento recuperado por un conjunto de recuperadores se calcula de la siguiente manera:

\[ score(d\epsilon D)\ =\ \sum\limits_{r\epsilon R}^{}({w}_{r}*(scor{e}_{r}(d)\ -\ mi{n}_{r})\ /\ (ma{x}_{r\ }-mi{n}_{r})\ ) \]

Aquí:

  • d es el documento.
  • R es el conjunto de recuperadores (FTS y búsqueda de vectores).
  • w es el peso asignado a un recuperador específico.

Implementa RSF en una consulta de Spanner

Para implementar RSF, debes normalizar las puntuaciones del vector y FTS a una escala común. En el siguiente ejemplo, se calculan las puntuaciones mínimas y máximas en cláusulas WITH separadas para obtener los factores de normalización. Luego, combina los resultados con un FULL OUTER JOIN y suma las puntuaciones normalizadas de la búsqueda de vecino más cercano aproximado (ANN) (convertida de cosine_distance) y FTS.

WITH ann AS (
  SELECT key, APPROX_COSINE_DISTANCE(@vector, embedding,
    OPTIONS => JSON '{"num_leaves_to_search": 50}') AS cosine_distance,
  FROM hybrid_search
  WHERE embedding IS NOT NULL
  ORDER BY cosine_distance
  LIMIT 100
),
fts AS (
  SELECT key, SCORE_NGRAMS(text_tokens_ngrams, 'Green') AS score,
  FROM hybrid_search
    WHERE SEARCH_NGRAMS(text_tokens_ngrams, 'Green')
    ORDER BY score DESC
    LIMIT 100
),
ann_min AS (
  SELECT MIN(1 - cosine_distance) AS min
  FROM ann
),
ann_max AS (
  SELECT MAX(1 - cosine_distance) AS max
  FROM ann
),
fts_min AS (
  SELECT MIN(score) AS min
  FROM fts
),
fts_max AS (
  SELECT MAX(score) AS max
  FROM fts
)
SELECT IFNULL(ann.key, fts.key),
       IFNULL(((1 - ann.cosine_distance) - ann_min.min) /
               (ann_max.max - ann_min.min), 0) +
       IFNULL((fts.score - fts_min.min) /
               (fts_max.max - fts_min.min), 0) AS score
FROM ann
FULL OUTER JOIN fts
ON ann.key = fts.key
CROSS JOIN ann_min
CROSS JOIN ann_max
CROSS JOIN fts_min
CROSS JOIN fts_max
ORDER BY score DESC
LIMIT 5;

Las búsquedas filtradas usan FTS para crear un filtro que reduce el conjunto de documentos considerados para una búsqueda de vectores de k vecinos más cercanos (KNN). De manera opcional, puedes usar una clasificación previa para limitar el tamaño del conjunto de resultados.

La búsqueda de ejemplo en esta sección realiza los siguientes pasos para reducir el espacio de búsqueda de vectores al subconjunto de datos que coinciden con las palabras clave:

  • Usa SEARCH (text_tokens, 'Green') para encontrar filas en las que la columna text_tokens contenga el texto Green. Las 1,000 filas principales se muestran en un orden de clasificación definido por el índice de búsqueda.
  • Usa una función de vectores, DOT_PRODUCT(@vector, embedding), para calcular la similitud entre el vector de consulta (@vector) y el vector de documento almacenado (embedding). Luego, ordena los resultados y muestra las 10 coincidencias principales finales.
SELECT key
FROM (
  SELECT key, embedding
  FROM hybrid_search
  WHERE SEARCH (text_tokens, 'Green')
  ORDER BY presort
  LIMIT 1000)
ORDER BY DOT_PRODUCT(@vector, embedding) DESC
LIMIT 10;

Reclasificación con AA

La reclasificación basada en AA es un enfoque con mucha carga de procesamiento, pero muy preciso. Aplica un modelo de aprendizaje automático a un pequeño conjunto de candidatos que se redujo con FTS, la búsqueda de vectores o una combinación de ambos. Para obtener más información sobre la integración de Agent Platform con Spanner, consulta la descripción general de la integración de Agent Platform con Spanner.

Puedes integrar la reclasificación con AA usando la función ML.PREDICT de Spanner con un modelo implementado de Gemini Enterprise Agent Platform.

Implementa la reclasificación basada en AA

  1. Implementa un modelo de reclasificación (como de HuggingFace) en un extremo de Agent Platform.
  2. Crea un objeto MODEL de Spanner que apunte al extremo de Agent Platform. Por ejemplo, en el siguiente ejemplo de modelo Reranker:

    • text ARRAY<string(max)> son los documentos.
    • text_pair ARRAY<string(max)> es el texto de la consulta en el ejemplo.
    • score son las puntuaciones de pertinencia asignadas por el modelo de AA para los pares de textos de entrada.
    CREATE MODEL Reranker
    INPUT (text ARRAY<string(max)>, text_pair ARRAY<string(max)>)
    OUTPUT (score FLOAT32)
    REMOTE
    OPTIONS (
    endpoint = '...'
    );
    
  3. Usa una subconsulta para recuperar los candidatos iniciales (como los 100 resultados principales de una búsqueda de ANN) y pasarlos a ML.PREDICT. La función muestra una nueva columna de puntuación para el orden final.

    SELECT key
    FROM ML.PREDICT(
        MODEL Reranker, (
          SELECT key, text, "gift for 8-year-old" AS text_pair
          FROM hybrid_search
          WHERE embedding IS NOT NULL
          ORDER BY APPROX_DOT_PRODUCT(@vector, embedding, options=>JSON '{"num_leaves_to_search": 50}') DESC
          LIMIT 100)
    )
    ORDER BY score DESC
    LIMIT 3;
    

¿Qué sigue?