Una biblioteca de búsqueda vectorial del lado del cliente que puede incrustar, buscar y caché. Funciona en el navegador y el lado del servidor.
Supera el texto de OpenAI-Embeding-ADA-002 y es mucho más rápido que Pinecone y otros Vectordbs.
Soy el fundador de SearchBase.App y necesitamos esto para nuestro producto y clientes. Usaremos esta biblioteca en producción. Puede estar seguro de que se mantendrá y mejorará.
¡Vienen muchas mejoras!
Nuestro objetivo es construir una búsqueda vectorial súper simple y rápida que funcione con un par cien a miles de vectores. ~ 1k vectores por usuario cubre el 99% de los casos de uso.
Inicialmente mantendremos cosas súper simples y sub 100 m.
npm i client-vector-searchEsta biblioteca proporciona una solución plug-and-play para la incrustación y la búsqueda vectorial. Está diseñado para ser fácil de usar, eficiente y versátil. Aquí hay una guía de inicio rápido:
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 Para usarlo dentro de los proyectos NextJS, deberá actualizar el archivo next.config.js para incluir lo siguiente:
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 ;
} ,
} ; Puede inicializar el modelo antes de usarlo para generar incrustaciones. Esto asegurará que el modelo se cargue antes de usarlo y proporcionará un mejor UX.
import { initializeModel } from "client-vector-search"
. . .
useEffect ( ( ) => {
try {
initializeModel ( ) ;
} catch ( e ) {
console . log ( e ) ;
}
} , [ ] ) ; Esta guía proporciona un tutorial paso a paso de las características principales de la biblioteca. Cubre todo, desde la generación de incrustaciones para una cadena hasta realizar operaciones en el índice, como agregar, actualizar y eliminar objetos. También incluye instrucciones sobre cómo guardar el índice en una base de datos y realizar operaciones de búsqueda dentro de ella.
Hasta que tengamos una documentación de referencia, puede encontrar todos los métodos y su uso en esta guía. Cada paso se acompaña de un fragmento de código para ilustrar el uso del método en cuestión. Asegúrese de seguir y probar los ejemplos en su propio entorno para comprender mejor cómo funciona todo.
¡Comencemos!
Genere incrustaciones para una cadena dada utilizando el método getEmbedding .
const embedding = await getEmbedding ( "Apple" ) ; // Returns embedding as number[]Nota :
getEmbeddinges asíncrono; Asegúrese de usarawait.
Calcule la similitud cosena entre dos incrustaciones.
const similarity = cosineSimilarity ( embedding1 , embedding2 , 6 ) ;Nota : Ambos incrustaciones deben ser de la misma longitud.
Cree un índice con una matriz inicial de objetos. Cada objeto debe tener una propiedad de 'incrustación'.
const initialObjects = [ ... ] ;
const index = new EmbeddingIndex ( initialObjects ) ;Agregue un objeto al índice.
const objectToAdd = { id : 6 , name : 'Cat' , embedding : await getEmbedding ( 'Cat' ) } ;
index . add ( objectToAdd ) ;Actualizar un objeto existente en el índice.
const vectorToUpdate = { id : 6 , name : 'Dog' , embedding : await getEmbedding ( 'Dog' ) } ;
index . update ( { id : 6 } , vectorToUpdate ) ;Elimine un objeto del índice.
index . remove ( { id : 6 } ) ;Recuperar un objeto del índice.
const vector = index . get ( { id : 1 } ) ;Busque el índice con una incrustación de consulta.
const queryEmbedding = await getEmbedding ( 'Fruit' ) ;
const results = await index . search ( queryEmbedding , { topK : 5 } ) ;Imprima el índice completo en la consola.
index . printIndex ( ) ;Guarde el índice en una base de datos INDEDDB persistente. Nota
await index . saveIndex ( "indexedDB" , { DBName : "clientVectorDB" , objectStoreName : "ClientEmbeddingStore" } )Realice una operación de búsqueda en IndexedDB.
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" ) ;Para eliminar un almacén de objetos de una base de datos.
await IndexedDbManager . deleteIndexedDBObjectStore ( "clientVectorDB" , "ClientEmbeddingStore" ) ;Para recuperar todos los objetos de una tienda de objetos específico.
const allObjects = await IndexedDbManager . getAllObjectsFromIndexedDB ( "clientVectorDB" , "ClientEmbeddingStore" ) ;