Bienvenue dans la recherche de similarité vectorielle de Firebase Data Connect, l'implémentation Firebase de la recherche sémantique qui s'intègre à Google Vertex AI.
Au cœur de cette fonctionnalité se trouvent les embeddings vectoriels, qui sont des tableaux de nombres à virgule flottante représentant la signification sémantique d'un texte ou d'un contenu multimédia. En exécutant une recherche des voisins les plus proches à l'aide d'un embedding vectoriel d'entrée, vous pouvez trouver tous les contenus sémantiquement similaires. Data Connect utilise l'extension pgvector
de PostgreSQL pour cette fonctionnalité.
Cette puissante recherche sémantique peut être utilisée dans des cas d'utilisation tels que les moteurs de recommandation et les moteurs de recherche. Il s'agit également d'un élément clé de la génération augmentée par récupération dans les flux d'IA générative. La documentation Vertex AI est un excellent point de départ pour en savoir plus.
Vous pouvez vous appuyer sur la compatibilité intégrée de Data Connect pour générer automatiquement des embeddings vectoriels à l'aide de l'API Embeddings de Vertex AI, ou utiliser cette API pour les générer manuellement.
Prérequis
Configurez Data Connect pour votre projet.
Activez les API Vertex AI.
Prérequis
Vous pouvez choisir entre un flux de développement local (si vous êtes un développeur Web, Kotlin Android ou iOS) ou un flux IDX (pour les développeurs Web). Vous pouvez utiliser une base de données locale ou votre projet Data Connect de production et son instance Cloud SQL pour PostgreSQL pour le développement.
Ces instructions supposent que vous avez créé votre projet Data Connect en suivant le guide de démarrage rapide.
Intégrer à PostgreSQL local
- Configurez une instance PostgreSQL locale.
- Attribuez-vous le rôle IAM Utilisateur Vertex AI.
- Configurez les identifiants par défaut de l'application Google Cloud dans votre environnement.
- Installez l'extension
pgvector
dans votre instance PostgreSQL locale. - Activez l'extension à l'aide de
CREATE EXTENSION vector
, conformément aux instructions du dépôtpgvector
.
Intégrer IDX
- Configurez votre espace de travail IDX à l'aide du modèle Data Connect.
- Attribuez-vous le rôle IAM Utilisateur Vertex AI.
- Activez l'extension à l'aide de
CREATE EXTENSION vector
, conformément aux instructions du dépôtpgvector
.
Concevoir votre schéma
Pour effectuer une recherche vectorielle, ajoutez un champ de type Vector
à votre schéma. Par exemple, si vous souhaitez effectuer une recherche sémantique à l'aide de descriptions de films, ajoutez un champ pour contenir les embeddings vectoriels associés à la description du film. Dans ce schéma, descriptionEmbedding
est ajouté pour stocker les embeddings vectoriels du champ 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)
// ...
}
Générer et récupérer des embeddings
Data Connect offre une prise en charge intégrée des embeddings vectoriels avec la valeur de serveur _embed
. Cela indique à Data Connect de générer des embeddings vectoriels en appelant en interne les API d'embedding de Vertex AI. La valeur du serveur _embed
peut être utilisée dans les mutations et les requêtes.
Mutations
Générer et stocker un embedding avec Data Connect
Dans votre application de recherche vectorielle, vous souhaiterez probablement demander que les embeddings soient générés dès que vous ajoutez des enregistrements à votre base de données. Voici une mutation createMovie
qui ajoute un enregistrement de film à la table Movie
et transmet également une description de film avec un embedding spécifié model
.
mutation createMovie($movieData: Movie_Data! @pick(fields: ["title", "genre", "description"])) {
movie_insert(data: {
...movieData,
descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: $movieData.description}
})
}
Dans certains cas, vous pouvez mettre à jour la description et l'intégration du film.
mutation updateDescription($id: String!, $description: String!) {
movie_update(id: $id, data: {
description: $description,
descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: $description}
})
}
Pour appeler cette dernière mutation à partir d'un client :
import { updateMovieDescriptionWithEmbed } from 'lib/dataconnect-sdk/';
await updateMovieDescriptionWithEmbed({ id: movieId, description: description});
// Use the response
Requêtes
Récupérez les embeddings vectoriels à l'aide d'une requête semblable à celle-ci. Notez que le descriptionEmbedding
renvoyé par la requête est un tableau de valeurs float, qui n'est généralement pas lisible par un humain. Par conséquent, les SDK générés par Data Connect ne permettent pas de le renvoyer directement.
Vous pouvez utiliser les embeddings vectoriels renvoyés pour effectuer une recherche de similarité, comme décrit dans la section suivante.
query getMovieDescription($id: String!) @auth(is: PUBLIC) {
movie(id: $id)
id
description
descriptionEmbedding
}
Effectuer une recherche de similarités
Nous pouvons maintenant effectuer une recherche par similarité.
Pour chaque champ Vector
, Data Connect génère une fonction GraphQL qui implémente la recherche par similarité. Le nom de cette fonction générée est ${pluralType}_${vectorFieldName}_similarity
. Il accepte quelques paramètres, comme indiqué dans les exemples suivants et dans la liste de référence.
Vous pouvez définir une fonction GraphQL qui appelle la recherche par similarité. Comme mentionné ci-dessus, la valeur de serveur _embed
indique à Data Connect de générer les embeddings vectoriels à l'aide des API Embedding de Vertex AI. Dans ce cas, il s'agit de créer des embeddings pour la chaîne de recherche utilisée pour la comparaison avec les embeddings de description de film.
Dans cet exemple, la recherche de similarités renverra jusqu'à cinq films dont la description est sémantiquement la plus proche de la requête saisie. L'ensemble de résultats est trié par ordre croissant de distance (du plus proche au plus éloigné).
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
}
}
Ajuster la requête de similarité
Les valeurs par défaut des paramètres de recherche tels que method
et within
fonctionnent bien pour la plupart des cas d'utilisation. Toutefois, si vous remarquez que votre requête renvoie des résultats trop différents ou qu'il manque des résultats que vous souhaitez inclure, essayez d'ajuster ces paramètres.
Pour trouver une valeur appropriée pour within
, nous pouvons ajouter _metadata.distance
aux champs sélectionnés pour voir à quelle distance du vecteur de requête se trouve chaque résultat. En fonction des valeurs distance
renvoyées, nous pouvons définir le paramètre within
. Seuls les résultats dont la distance est inférieure à la valeur de within
seront inclus :
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
}
}
}
Vous pouvez également tester différentes fonctions de distance en définissant le paramètre 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
}
}
}
Notez que différentes méthodes renvoient des valeurs de distance très différentes. Si vous avez défini within
, vous devrez à nouveau ajuster cette valeur après avoir modifié method
.
Appeler la requête de similarité
Pour appeler une recherche de similarités à partir du code client :
import { searchMovieDescriptionUsingL2similarity} from 'lib/dataconnect-sdk';
const response = await searchMovieDescriptionUsingL2similarity({ query });
// Use the response
Utiliser des embeddings personnalisés
Data Connect vous permet également de travailler directement avec les embeddings en tant que Vector
s au lieu d'utiliser la valeur du serveur _embed
pour les générer.
Stocker un embedding personnalisé
À l'aide de l'API Vertex Embeddings, spécifiez un modèle de correspondance et demandez des résultats d'embedding de la bonne dimension.
Ensuite, convertissez le tableau de valeurs float renvoyé en Vector
pour le transmettre à l'opération de mise à jour pour le stockage.
mutation updateDescription($id: String!, $description: String!, $descriptionEmbedding: Vector!) {
movie_update(id: $id, data: {
// title, genre...
description: $description,
descriptionEmbedding: $descriptionEmbedding
})
}
Effectuer une recherche de similarité à l'aide d'embeddings personnalisés
Effectuez la même opération pour récupérer les embeddings des termes de recherche et les caster en Vectors
.
Appelez ensuite la requête _similarity
pour effectuer chaque recherche.
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
}
}
Déployer en production
Déployer votre schéma et votre connecteur
La dernière étape d'une itération Data Connect typique consiste à déployer vos composants en production.
Lorsque vous déployez votre schéma contenant des types Vector
sur Cloud SQL à l'aide de la commande firebase deploy
, l'interface de ligne de commande Firebase prend les mesures nécessaires pour activer la génération d'embeddings basés sur Vertex AI sur votre instance Cloud SQL.
firebase deploy --only dataconnect
Si vous souhaitez activer manuellement la prise en charge de l'intégration dans votre instance Cloud SQL ou si vous rencontrez une erreur CLI, suivez ces instructions.
Syntaxe de la recherche vectorielle
Extensions de schéma
Le type de données Vector
de Data Connect est mappé sur le type vector
de PostgreSQL, tel que défini par l'extension pgvector
. Le type vector
de pgvector est stocké sous forme de tableau de nombres à virgule flottante de simple précision dans PostgreSQL.
Dans Data Connect, le type Vector
est représenté sous la forme d'un tableau de nombres JSON. Les entrées sont forcées dans un tableau de valeurs float32
. Si la conversion échoue, une erreur est générée.
Utilisez le paramètre de taille de la directive @col
pour définir les dimensions du vecteur.
type Question @table {
text: String!
category: String!
textEmbedding: Vector! @col(size: 768)
}
size
n'est compatible qu'avec les types Vector
. Les opérations Vector
, telles que la recherche par similarité, nécessitent que tous les Vector
aient le même nombre de dimensions.
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
Valeur du serveur _embed
pour les requêtes et les mutations
_embed
Cette valeur de serveur indique au service Data Connect de générer et de stocker des embeddings à l'aide des API d'embedding de Vertex AI. Cette valeur de serveur peut être utilisée à la fois pour les requêtes et les mutations.
Paramètres de la recherche par similarité
method: COSINE|INNER_PRODUCT|L2
Fonction de distance utilisée pour rechercher les voisins les plus proches. Les algorithmes actuellement compatibles sont un sous-ensemble des algorithmes de recherche pgvector.
within: float
Contrainte sur la distance dans laquelle la recherche de voisin le plus proche est effectuée.
where: FDC filter condition
Consultez le guide sur les schémas, les requêtes et les mutations.
limit: int
Nombre de résultats à renvoyer.