Ti diamo il benvenuto nella ricerca di similarità vettoriale di Firebase Data Connect, l'implementazione della ricerca semantica di Firebase che si integra con Google Vertex AI.
Al centro di questa funzionalità ci sono i vector embedding, ovvero array di numeri in virgola mobile che rappresentano il significato semantico di testo o contenuti multimediali. Eseguendo una
ricerca del vicino più prossimo utilizzando un incorporamento vettoriale di input, puoi trovare tutti
i contenuti semanticamente simili. Data Connect utilizza l'estensione pgvector
di PostgreSQL per questa funzionalità.
Questa potente ricerca semantica può essere utilizzata in casi d'uso come i motori per suggerimenti e i motori di ricerca. È anche un componente chiave nella generazione basata sul recupero nei flussi di AI generativa. La documentazione di Vertex AI è un ottimo punto di partenza per scoprire di più.
Puoi fare affidamento sul supporto integrato di Data Connect per la generazione automatica di incorporamenti vettoriali utilizzando l'API Embeddings di Vertex AI oppure utilizzare questa API per generarli manualmente.
Prerequisiti
Configura Data Connect per il tuo progetto.
Abilita le API Vertex AI.
Configurazione
Puoi scegliere tra un flusso di sviluppo locale (se sei uno sviluppatore web, Kotlin Android o iOS) o un flusso IDX (per gli sviluppatori web). Puoi utilizzare un database locale o il tuo progetto Data Connect di produzione e la relativa istanza Cloud SQL per PostgreSQL per lo sviluppo.
Queste istruzioni presuppongono che tu abbia creato il tuo progetto Data Connect seguendo la guida rapida.
Eseguire l'integrazione con PostgreSQL locale
- Configura un'istanza PostgreSQL locale.
- Concediti il ruolo IAM Utente Vertex AI.
- Configura le credenziali predefinite dell'applicazione Google Cloud nel tuo ambiente.
- Installa l'estensione
pgvector
nell'istanza PostgreSQL locale. - Attiva l'estensione utilizzando
CREATE EXTENSION vector
come indicato nelle istruzioni del repositorypgvector
.
Integrare con IDX
- Configura il tuo spazio di lavoro IDX utilizzando il modello Data Connect.
- Concediti il ruolo IAM Utente Vertex AI.
- Attiva l'estensione utilizzando
CREATE EXTENSION vector
come indicato nelle istruzioni del repositorypgvector
.
Progettare lo schema
Per eseguire la ricerca vettoriale, aggiungi un nuovo campo di tipo Vector
allo schema. Ad esempio, se vuoi eseguire una ricerca semantica utilizzando le descrizioni dei film, aggiungi un campo per contenere gli embedding vettoriali associati alla descrizione del film. In
questo schema, descriptionEmbedding
viene aggiunto per archiviare gli incorporamenti vettoriali per
il 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)
// ...
}
Generare e recuperare incorporamenti
Data Connect offre il supporto integrato per gli incorporamenti vettoriali con
il valore del server _embed
. In questo modo Data Connect genera
embedding vettoriali chiamando internamente le API Embedding di Vertex AI. Il valore del server _embed
può essere utilizzato sia nelle mutazioni che nelle query.
Mutazioni
Genera e memorizza un incorporamento tramite Data Connect
Nella tua app di ricerca vettoriale, probabilmente vorrai richiedere che gli embedding vengano generati non appena aggiungi record al database. Ecco una mutazione createMovie
che aggiunge un record di film alla tabella Movie
e passa anche una descrizione del film con un incorporamento model
specificato.
mutation createMovie($movieData: Movie_Data! @pick(fields: ["title", "genre", "description"])) {
movie_insert(data: {
...movieData,
descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: $movieData.description}
})
}
In alcuni casi, potresti voler aggiornare la descrizione e l'incorporamento del film.
mutation updateDescription($id: String!, $description: String!) {
movie_update(id: $id, data: {
description: $description,
descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: $description}
})
}
Per chiamare l'ultima mutazione da un client:
import { updateMovieDescriptionWithEmbed } from 'lib/dataconnect-sdk/';
await updateMovieDescriptionWithEmbed({ id: movieId, description: description});
// Use the response
Query
Recupera gli embedding vettoriali utilizzando una query come la seguente. Tieni presente che il
descriptionEmbedding
restituito dalla query è un array di numeri in virgola mobile, che
in genere non è leggibile. Pertanto, gli SDK generati da Data Connect non
supportano la restituzione diretta.
Puoi utilizzare gli incorporamenti vettoriali restituiti per eseguire la ricerca di similarità, come descritto nella sezione successiva.
query getMovieDescription($id: String!) @auth(is: PUBLIC) {
movie(id: $id)
id
description
descriptionEmbedding
}
Eseguire la ricerca di somiglianze
Ora possiamo eseguire la ricerca per similarità.
Per ogni campo Vector
, Data Connect genera una funzione GraphQL
che implementa la ricerca per similarità. Il nome di questa funzione generata è
${pluralType}_${vectorFieldName}_similarity
. Supporta alcuni parametri
come mostrato negli esempi seguenti e nell'elenco di riferimento.
Puoi definire una funzione GraphQL che richiama la ricerca di similarità. Come
accennato in precedenza, il valore del server _embed
indica a Data Connect di
generare gli incorporamenti vettoriali utilizzando le API di incorporamento di Vertex AI, in questo caso
per creare incorporamenti per la stringa di ricerca utilizzata per il confronto con gli incorporamenti della descrizione del film.
In questo esempio, la ricerca per similarità restituirà fino a 5 film la cui descrizione è semanticamente più vicina alla query di input. Il set di risultati è ordinato in ordine crescente di distanza, dalla più vicina alla più lontana.
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
}
}
Ottimizzare la query di similarità
I valori predefiniti per i parametri di ricerca come method
e within
funzionano bene per la maggior parte dei casi d'uso. Tuttavia, se noti che la query restituisce risultati troppo diversi o mancano risultati che vuoi includere, prova a modificare questi parametri.
Per trovare un valore appropriato per within
, possiamo aggiungere _metadata.distance
ai
campi selezionati per vedere a quale distanza dal vettore della query si trova ogni risultato. In base ai
valori distance
restituiti, possiamo impostare il parametro within
; verranno inclusi solo i risultati con
distanza inferiore al valore di 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
}
}
}
Puoi anche sperimentare con diverse funzioni di distanza impostando il parametro 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
}
}
}
Tieni presente che metodi diversi restituiscono valori molto diversi per la distanza: se
hai impostato within
, dovrai regolare nuovamente questo valore dopo aver modificato method
.
Chiama la query di similarità
Per chiamare una ricerca per somiglianza dal codice client:
import { searchMovieDescriptionUsingL2similarity} from 'lib/dataconnect-sdk';
const response = await searchMovieDescriptionUsingL2similarity({ query });
// Use the response
Utilizzare gli incorporamenti personalizzati
Data Connect ti consente anche di lavorare direttamente con gli incorporamenti come Vector
anziché utilizzare il valore del server _embed
per generarli.
Memorizzare un incorporamento personalizzato
Utilizzando l'API Vertex Embeddings, specifica un modello di corrispondenza e richiedi risultati di embedding della dimensione corretta.
Poi, esegui il cast dell'array di numeri in virgola mobile restituito in un Vector
da passare all'operazione di aggiornamento
per l'archiviazione.
mutation updateDescription($id: String!, $description: String!, $descriptionEmbedding: Vector!) {
movie_update(id: $id, data: {
// title, genre...
description: $description,
descriptionEmbedding: $descriptionEmbedding
})
}
Eseguire la ricerca di similarità utilizzando gli incorporamenti personalizzati
Esegui la stessa operazione per recuperare gli incorporamenti per i termini di ricerca e trasmettere
a Vectors
.
Quindi, chiama la query _similarity
per eseguire ogni ricerca.
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
}
}
Distribuzione in produzione
Esegui il deployment dello schema e del connettore
L'ultimo passaggio di un'iterazione tipica di Data Connect consiste nel deployment degli asset in produzione.
Quando esegui il deployment dello schema contenente i tipi Vector
in Cloud SQL utilizzando il comando firebase deploy
, la CLI Firebase esegue i passaggi necessari per attivare la generazione di incorporamenti basata su Vertex AI nell'istanza Cloud SQL.
firebase deploy --only dataconnect
Se vuoi attivare manualmente il supporto dell'incorporamento nella tua istanza CloudSQL o riscontri un errore della CLI, segui queste istruzioni.
Sintassi della ricerca vettoriale
Estensioni dello schema
Il tipo di dati Vector
di Data Connect viene mappato al tipo vector
di PostgreSQL
come definito dall'estensione pgvector
.
Il tipo vector
di pgvector viene archiviato come array di numeri in virgola mobile a precisione singola in PostgreSQL.
In Data Connect, il tipo Vector
è rappresentato come un array di numeri JSON. Gli input vengono forzati in un array di valori float32
. Se la forzatura
non va a buon fine, viene generato un errore.
Utilizza il parametro size della direttiva @col
per impostare le dimensioni del
vettore.
type Question @table {
text: String!
category: String!
textEmbedding: Vector! @col(size: 768)
}
size
è supportato solo per i tipi Vector
. Vector
, come la ricerca per somiglianza, richiedono che tutti i Vector
abbiano lo stesso numero di dimensioni.
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
Valore del server _embed
per query e mutazioni
_embed
Questo valore del server indica al servizio Data Connect di generare e archiviare gli incorporamenti utilizzando le API Embedding di Vertex AI. Questo valore del server può essere utilizzato sia per le query che per le mutazioni.
Parametri per la ricerca di somiglianze
method: COSINE|INNER_PRODUCT|L2
La funzione di distanza utilizzata per cercare i vicini nelle vicinanze. Gli algoritmi attualmente supportati sono un sottoinsieme degli algoritmi di ricerca pgvector.
within: float
Un vincolo sulla distanza entro la quale viene eseguita la ricerca del vicino più prossimo.
where: FDC filter condition
Consulta la guida a schemi, query e mutazioni.
limit: int
Il numero di risultati da restituire.