Vectra は、Pinecone や Qdrant に似た機能を備えた Node.js 用のローカル ベクター データベースですが、ローカル ファイルを使用して構築されます。各 Vectra インデックスはディスク上のフォルダーです。フォルダー内には、インデックスのすべてのベクターとインデックス付きメタデータが含まれるindex.json
ファイルがあります。インデックスを作成するときに、インデックスを作成するメタデータ プロパティを指定すると、それらのフィールドのみがindex.json
ファイルに保存されます。アイテムのその他のメタデータはすべて、GUID をキーとする別のファイルとしてディスクに保存されます。
Vectra にクエリを実行する場合、Pinecone がサポートする Mongo DB クエリ演算子の同じサブセットを使用でき、結果は類似性によってソートされて返されます。インデックス内のすべての項目は、まずメタデータによってフィルター処理され、次に類似性に関してランク付けされます。すべての項目はメモリ内で評価されるため、ほぼ瞬時に評価されます。かなり大きなインデックスでも 1 ミリ秒から 2 ミリ秒かかる可能性があります。小さいインデックスは 1ms 未満である必要があります。
Vectra インデックス全体がメモリに読み込まれるため、チャット ボットの長期メモリなどのシナリオにはあまり適していないことに注意してください。そのためには実ベクトル DB を使用します。 Vectra は、プロンプトに含めたいほとんど静的なデータの小さなコーパスがあるシナリオで使用することを目的としています。無限の少数のショットのサンプルは、Vectra の優れた使用例、または質問したい 1 つのドキュメントだけでも使用できます。
松ぼっくりスタイルの名前空間は直接サポートされていませんが、名前空間ごとに個別の Vectra インデックス (およびフォルダー) を作成することで簡単に模倣できます。
このリポジトリには Vectra の TypeScript/JavaScript バインディングが含まれていますが、他の言語バインディングが作成されています。 Vectra はファイルベースであるため、任意の言語バインディングを使用して Vectra インデックスの読み取りまたは書き込みを行うことができます。つまり、JS を使用して Vectra インデックスを構築し、Python を使用してそれを読み取ることができます。
$ npm install vectra
まず、アイテムを保存するフォルダーへのパスを指定してLocalIndex
のインスタンスを作成します。
import { LocalIndex } from 'vectra' ;
const index = new LocalIndex ( path . join ( __dirname , '..' , 'index' ) ) ;
次に、非同期関数内からインデックスを作成します。
if ( ! ( await index . isIndexCreated ( ) ) ) {
await index . createIndex ( ) ;
}
インデックスにいくつかの項目を追加します。
import { OpenAI } from 'openai' ;
const openai = new OpenAI ( {
apiKey : `<YOUR_KEY>` ,
} ) ;
async function getVector ( text : string ) {
const response = await openai . embeddings . create ( {
'model' : 'text-embedding-ada-002' ,
'input' : text ,
} ) ;
return response . data [ 0 ] . embedding ;
}
async function addItem ( text : string ) {
await index . insertItem ( {
vector : await getVector ( text ) ,
metadata : { text } ,
} ) ;
}
// Add items
await addItem ( 'apple' ) ;
await addItem ( 'oranges' ) ;
await addItem ( 'red' ) ;
await addItem ( 'blue' ) ;
次に、項目をクエリします。
async function query ( text : string ) {
const vector = await getVector ( text ) ;
const results = await index . queryItems ( vector , 3 ) ;
if ( results . length > 0 ) {
for ( const result of results ) {
console . log ( `[ ${ result . score } ] ${ result . item . metadata . text } ` ) ;
}
} else {
console . log ( `No results found.` ) ;
}
}
await query ( 'green' ) ;
/*
[0.9036569942401076] blue
[0.8758153664568566] red
[0.8323828606103998] apple
*/
await query ( 'banana' ) ;
/*
[0.9033128691220631] apple
[0.8493374123092652] oranges
[0.8415324469533297] blue
*/