Une bibliothèque de recherche vectorielle côté client qui peut intégrer, rechercher et cache. Fonctionne du côté du navigateur et du serveur.
Il surpasse le texte d'Openai-Embedding-ADA-002 et est bien plus rapide que PineCone et autres Vectordbs.
Je suis le fondateur de SearchBase.App et nous en avions besoin pour notre produit et nos clients. Nous utiliserons cette bibliothèque en production. Vous pouvez être sûr qu'il sera entretenu et amélioré.
Beaucoup d'améliorations arrivent!
Notre objectif est de construire une recherche vectorielle super simple et rapide qui fonctionne avec quelques cent à des milliers de vecteurs. ~ 1k vecteurs par utilisateur couvre 99% des cas d'utilisation.
Nous garderons initialement les choses super simples et sous 100 ms
npm i client-vector-searchCette bibliothèque fournit une solution plug-and-play pour l'intégration et la recherche vectorielle. Il est conçu pour être facile à utiliser, efficace et polyvalent. Voici un guide de démarrage rapide:
import { getEmbedding , EmbeddingIndex } from 'client-vector-search' ;
// getEmbedding is an async function, so you need to use 'await' or '.then()' to get the result
const embedding = await getEmbedding ( "Apple" ) ; // Returns embedding as number[]
// Each object should have an 'embedding' property of type number[]
const initialObjects = [
{ id : 1 , name : "Apple" , embedding : embedding } ,
{ id : 2 , name : "Banana" , embedding : await getEmbedding ( "Banana" ) } ,
{ id : 3 , name : "Cheddar" , embedding : await getEmbedding ( "Cheddar" ) } ,
{ id : 4 , name : "Space" , embedding : await getEmbedding ( "Space" ) } ,
{ id : 5 , name : "database" , embedding : await getEmbedding ( "database" ) } ,
] ;
const index = new EmbeddingIndex ( initialObjects ) ; // Creates an index
// The query should be an embedding of type number[]
const queryEmbedding = await getEmbedding ( 'Fruit' ) ; // Query embedding
const results = await index . search ( queryEmbedding , { topK : 5 } ) ; // Returns top similar objects
// specify the storage type
await index . saveIndex ( 'indexedDB' ) ;
const results = await index . search ( [ 1 , 2 , 3 ] , {
topK : 5 ,
useStorage : 'indexedDB' ,
// storageOptions: { // use only if you overrode the defaults
// indexedDBName: 'clientVectorDB',
// indexedDBObjectStoreName: 'ClientEmbeddingStore',
// },
} ) ;
console . log ( results ) ;
await index . deleteIndexedDB ( ) ; // if you overrode default, specify db name Pour l'utiliser à l'intérieur des projets NextJS, vous devrez mettre à jour le fichier next.config.js pour inclure ce qui suit:
module . exports = {
// Override the default webpack configuration
webpack : ( config ) => {
// See https://webpack.js.org/configuration/resolve/#resolvealias
config . resolve . alias = {
... config . resolve . alias ,
sharp$ : false ,
"onnxruntime-node$" : false ,
} ;
return config ;
} ,
} ; Vous pouvez initialiser le modèle avant de l'utiliser pour générer des intégres. Cela garantira que le modèle est chargé avant de l'utiliser et de fournir une meilleure UX.
import { initializeModel } from "client-vector-search"
. . .
useEffect ( ( ) => {
try {
initializeModel ( ) ;
} catch ( e ) {
console . log ( e ) ;
}
} , [ ] ) ; Ce guide offre une procédure pas à pas des principales caractéristiques de la bibliothèque. Il couvre tout, de la génération d'intégration pour une chaîne à des opérations effectuées sur l'index telles que l'ajout, la mise à jour et la suppression des objets. Il comprend également des instructions sur la façon d'enregistrer l'index dans une base de données et d'effectuer des opérations de recherche.
Jusqu'à ce que nous ayons une documentation de référence, vous pouvez trouver toutes les méthodes et leur utilisation dans ce guide. Chaque étape est accompagnée d'un extrait de code pour illustrer l'utilisation de la méthode en question. Assurez-vous de suivre et d'essayer les exemples de votre propre environnement pour mieux comprendre comment tout fonctionne.
Commençons!
Générez des incorporations pour une chaîne donnée à l'aide de la méthode getEmbedding .
const embedding = await getEmbedding ( "Apple" ) ; // Returns embedding as number[]Remarque :
getEmbeddingest asynchrone; Assurez-vous d'utiliserawait.
Calculez la similitude du cosinus entre deux intérêts.
const similarity = cosineSimilarity ( embedding1 , embedding2 , 6 ) ;Remarque : Les deux intégres doivent être de la même longueur.
Créez un index avec un tableau initial d'objets. Chaque objet doit avoir une propriété «intégrer».
const initialObjects = [ ... ] ;
const index = new EmbeddingIndex ( initialObjects ) ;Ajoutez un objet à l'index.
const objectToAdd = { id : 6 , name : 'Cat' , embedding : await getEmbedding ( 'Cat' ) } ;
index . add ( objectToAdd ) ;Mettez à jour un objet existant dans l'index.
const vectorToUpdate = { id : 6 , name : 'Dog' , embedding : await getEmbedding ( 'Dog' ) } ;
index . update ( { id : 6 } , vectorToUpdate ) ;Supprimez un objet de l'index.
index . remove ( { id : 6 } ) ;Récupérez un objet de l'index.
const vector = index . get ( { id : 1 } ) ;Recherchez l'index avec une requête incorporée.
const queryEmbedding = await getEmbedding ( 'Fruit' ) ;
const results = await index . search ( queryEmbedding , { topK : 5 } ) ;Imprimez l'index entier de la console.
index . printIndex ( ) ;Enregistrez l'index dans une base de données persistante indexée. Note
await index . saveIndex ( "indexedDB" , { DBName : "clientVectorDB" , objectStoreName : "ClientEmbeddingStore" } )Effectuez une opération de recherche dans l'indexéddb.
const results = await index . search ( queryEmbedding , {
topK : 5 ,
useStorage : "indexedDB" ,
storageOptions : { // only if you want to override the default options, defaults are below
indexedDBName : 'clientVectorDB' ,
indexedDBObjectStoreName : 'ClientEmbeddingStore'
}
} ) ;
-- -
### Delete Database
To delete an entire database .
`` ` ts
await IndexedDbManager . deleteIndexedDB ( "clientVectorDB" ) ;Pour supprimer un magasin d'objets d'une base de données.
await IndexedDbManager . deleteIndexedDBObjectStore ( "clientVectorDB" , "ClientEmbeddingStore" ) ;Pour récupérer tous les objets à partir d'un magasin d'objets spécifique.
const allObjects = await IndexedDbManager . getAllObjectsFromIndexedDB ( "clientVectorDB" , "ClientEmbeddingStore" ) ;