Nesta página, descrevemos como realizar pesquisas híbridas de texto completo e vetoriais no Spanner. A pesquisa híbrida combina a precisão da correspondência de palavras-chave (pesquisa de texto completo, FTS) com a capacidade de recall da correspondência semântica (pesquisa vetorial) para produzir resultados de pesquisa altamente relevantes.
O Spanner é compatível com os seguintes padrões de pesquisa híbrida, que são divididos em três categorias principais:
| Categoria | Descrição | Objetivo principal |
| Fusion | A fusão recupera e classifica documentos de forma independente usando pesquisa por palavra-chave e vetorial e, em seguida, combina (funde) os resultados. | Alcance o recall e a relevância máximos combinando vários indicadores de pontuação. |
| Filtrado | As palavras-chave filtram ou refinam o espaço de pesquisa. | Verifique se a correspondência de palavras-chave é um requisito ao aproveitar a relevância semântica. |
| Reclassificação de ML | Um modelo de machine learning refina um conjunto inicial de candidatos para um ranking final mais preciso. | Alcançar a maior precisão possível para um pequeno conjunto final de resultados. |
Pesquisa de fusão
A pesquisa por fusão envolve executar a pesquisa de texto completo e a pesquisa vetorial de forma independente no mesmo corpus de dados. Em seguida, ele mescla os resultados para criar uma lista classificada única, unificada e altamente relevante.
Embora seja possível executar consultas independentes no lado do cliente, a pesquisa híbrida no Spanner oferece as seguintes vantagens:
- Simplifica a lógica do aplicativo gerenciando solicitações paralelas e a fusão de resultados no servidor.
- Evita transferir para o cliente conjuntos de resultados intermediários potencialmente grandes.
É possível usar o SQL para criar métodos de fusão no Spanner. Esta seção fornece exemplos de fusão de classificação recíproca e fusão de pontuação relativa. No entanto, recomendamos avaliar diferentes estratégias de fusão para determinar qual atende melhor aos requisitos do seu aplicativo.
Fusão baseada em classificação
Use a fusão baseada em classificação quando for difícil comparar ou normalizar as pontuações de relevância de diferentes métodos de recuperação (como pontuações da pesquisa de texto completo e distâncias vetoriais) porque elas são medidas em espaços diferentes. Esse método usa a posição de classificação de cada documento de cada extrator para gerar uma pontuação e uma classificação finais.
A fusão de classificação recíproca (RRF) é uma função de fusão baseada em classificação. A pontuação de RRF de um documento é a soma dos recíprocos das classificações de vários extratores, calculada da seguinte forma:
\[ score\ (d\epsilon D)\ =\ \sum\limits_{r\epsilon R}^{}(1\ /\ (\ 𝑘\ +\ ran{k}_{r}\ (𝑑)\ )\ )\ \]
Em que:
- d é o documento.
- R é o conjunto de mecanismos de recuperação (FTS e pesquisa vetorial).
- k é uma constante (geralmente definida como 60) usada para moderar a influência de documentos com classificação muito alta.
- w é a classificação do documento do recuperador r.
Implementar o RRF em uma consulta do Spanner
As métricas de vetor (como APPROX_DOT_PRODUCT) e as pontuações de pesquisa de texto (como SCORE_NGRAMS) operam em escalas incompatíveis. Para resolver isso, o exemplo a seguir implementa o RRF para normalizar os dados com base na posição no ranking, e não nas pontuações brutas.
A consulta usa UNNEST(ARRAY(...) WITH OFFSET para atribuir uma classificação aos 100 principais candidatos de cada método. Em seguida, ela calcula uma pontuação padronizada usando o inverso desses rankings e agrega os resultados para retornar as cinco principais correspondências.
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;
Fusão baseada em pontuação
A fusão baseada em pontuação é eficaz quando as pontuações de relevância de diferentes métodos são comparáveis ou podem ser normalizadas, o que pode permitir uma classificação mais precisa que incorpora o peso de relevância real de cada método.
A fusão de pontuação relativa (RSF) é um método baseado em pontuação que normaliza as pontuações de diferentes métodos em relação às pontuações mais altas e mais baixas em cada método, geralmente usando as funções MIN() e MAX(). A pontuação RSF de um documento recuperado por um conjunto de extratores é calculada da seguinte forma:
\[ score(d\epsilon D)\ =\ \sum\limits_{r\epsilon R}^{}({w}_{r}*(scor{e}_{r}(d)\ -\ mi{n}_{r})\ /\ (ma{x}_{r\ }-mi{n}_{r})\ ) \]
Em que:
- d é o documento.
- R é o conjunto de mecanismos de recuperação (FTS e pesquisa vetorial).
- w é o peso atribuído a um extrator específico.
Implementar a RSF em uma consulta do Spanner
Para implementar o RSF, é necessário normalizar as pontuações do vetor e do FTS em uma escala comum. O exemplo a seguir calcula as pontuações mínima e máxima em cláusulas WITH separadas para derivar os fatores de normalização. Em seguida, ele combina os resultados usando um FULL OUTER JOIN, somando as pontuações normalizadas da pesquisa de vizinho aproximado mais próximo (ANN, na sigla em inglês), convertida de cosine_distance, e a 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;
Pesquisa filtrada
As pesquisas filtradas usam a FTS para criar um filtro que reduz o conjunto de documentos considerados para uma pesquisa de vetor de vizinhos k-mais próximos (KNN). Você também pode usar uma pré-ordenação para limitar o tamanho do conjunto de resultados.
Implementar a pesquisa filtrada em uma consulta do Spanner
A pesquisa de exemplo nesta seção segue estas etapas para restringir o espaço de pesquisa vetorial ao subconjunto de dados que corresponde às palavras-chave:
- Usa
SEARCH (text_tokens, 'Green')para encontrar linhas em que a colunatext_tokenscontém o textoGreen. As 1.000 principais linhas são retornadas por uma ordem de classificação definida pelo índice de pesquisa. - Usa uma função de vetor,
DOT_PRODUCT(@vector, embedding), para calcular a similaridade entre o vetor de consulta (@vector) e o vetor de documento armazenado (embedding). Em seguida, ele classifica os resultados e retorna as 10 principais correspondências finais.
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;
Reclassificação por ML
A reclassificação baseada em ML é uma abordagem computacionalmente intensiva, mas altamente precisa. Ele aplica um modelo de machine learning a um pequeno conjunto de candidatos que foi reduzido pela FTS, pela pesquisa vetorial ou por uma combinação das duas. Para mais informações sobre a integração da Vertex AI com o Spanner, consulte a Visão geral da integração da Vertex AI com o Spanner.
É possível integrar o reordenamento por ML usando a função
ML.PREDICT
do Spanner com um modelo implantado da Vertex AI.
Implementar a reclassificação baseada em ML
- Implante um modelo de reclassificação (como da HuggingFace) em um endpoint da Vertex AI.
Crie um objeto
MODELdo Spanner que aponte para o endpoint da Vertex AI. Por exemplo, no seguinte exemplo de modeloReranker:text ARRAY<string(max)>são os documentos.text_pair ARRAY<string(max)>é o texto da consulta no exemplo.scoresão as pontuações de relevância atribuídas pelo modelo de ML para os pares de textos de entrada.
CREATE MODEL Reranker INPUT (text ARRAY<string(max)>, text_pair ARRAY<string(max)>) OUTPUT (score FLOAT32) REMOTE OPTIONS ( endpoint = '...' );Use uma subconsulta para extrair os candidatos iniciais (como os 100 principais resultados de uma pesquisa de ANN) e transmita-os para
ML.PREDICT. A função retorna uma nova coluna de pontuação para a ordenação 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;
A seguir
- Personalize seu mecanismo de pesquisa com a pesquisa híbrida com tecnologia de IA no Spanner.
- Saiba mais sobre a pesquisa de texto completo.