Pinecone.net adalah perpustakaan C# sepenuhnya untuk database vektor Pinecone.
Ini adalah perpustakaan komunitas yang menyediakan dukungan kelas satu untuk Pinecone di C# dan F#.
dotnet add package Pinecone.NET atau Install-Package Pinecone.NET
Bekerja dengan indeks
using Pinecone ;
// Initialize the client with your API key
using var pinecone = new PineconeClient ( "your-api-key" ) ;
// List all indexes
var indexes = await pinecone . ListIndexes ( ) ;
// Create a new index if it doesn't exist
var indexName = "myIndex" ;
if ( ! indexes . Contains ( indexName ) )
{
await pinecone . CreateServerlessIndex ( indexName , 1536 , Metric . Cosine , "aws" , "us-east-1" ) ;
}
// Get the Pinecone index by name (uses REST by default).
// The index client is thread-safe, consider caching and/or
// injecting it as a singleton into your DI container.
using var index = await pinecone . GetIndex ( indexName ) ;
// Configure an index
await pinecone . ConfigureIndex ( indexName , replicas : 2 , podType : "p2" ) ;
// Delete an index
await pinecone . DeleteIndex ( indexName ) ;Bekerja dengan vektor
// Assuming you have an instance of `index`
// Create and upsert vectors
var vectors = new [ ]
{
new Vector
{
Id = "vector1" ,
Values = new float [ ] { 0.1f , 0.2f , 0.3f , .. . } ,
Metadata = new MetadataMap
{
[ "genre" ] = "horror" ,
[ "duration" ] = 120
}
}
} ;
await index . Upsert ( vectors ) ;
// Fetch vectors by IDs
var fetched = await index . Fetch ( [ "vector1" ] ) ;
// Query scored vectors by ID
var scored = await index . Query ( "vector1" , topK : 10 ) ;
// Query scored vectors by a new, previously unseen vector
var vector = new [ ] { 0.1f , 0.2f , 0.3f , .. . } ;
var scored = await index . Query ( vector , topK : 10 ) ;
// Query scored vectors by ID with metadata filter
var filter = new MetadataMap
{
[ "genre" ] = new MetadataMap
{
[ "$in" ] = new [ ] { "documentary" , "action" }
}
} ;
var scored = await index . Query ( "birds" , topK : 10 , filter ) ;
// Delete vectors by vector IDs
await index . Delete ( new [ ] { "vector1" } ) ;
// Delete vectors by metadata filter
await index . Delete ( new MetadataMap
{
[ "genre" ] = new MetadataMap
{
[ "$in" ] = new [ ] { "documentary" , "action" }
}
} ) ;
// Delete all vectors in the index
await index . DeleteAll ( ) ;Bekerja dengan koleksi
using Pinecone ;
// Assuming you have an instance of `PineconeClient` named `pinecone`
// List all collections
var collections = await pinecone . ListCollections ( ) ;
// Create a new collection
await pinecone . CreateCollection ( "myCollection" , "myIndex" ) ;
// Describe a collection
var details = await pinecone . DescribeCollection ( "myCollection" ) ;
// Delete a collection
await pinecone . DeleteCollection ( "myCollection" ) ; Pulih dari kegagalan pada upsert paralel batched
// Upsert with recovery from up to three failures on batched parallel upsert.
//
// The parallelization is done automatically by the client based on the vector
// dimension and the number of vectors to upsert. It aims to keep the individual
// request size below Pinecone's 2MiB limit with some safety margin for metadata.
// This behavior can be further controlled by calling the 'Upsert' overload with
// custom values for 'batchSize' and 'parallelism' parameters.
//
// This is not the most efficient implementation in terms of allocations in
// GC pause frequency sensitive scenarios, but is perfectly acceptable
// for pretty much all regular back-end applications.
// Assuming there is an instance of 'index' available
// Generate 25k random vectors
var vectors = Enumerable
. Range ( 0 , 25_000 )
. Select ( _ => new Vector
{
Id = Guid . NewGuid ( ) . ToString ( ) ,
Values = Enumerable
. Range ( 0 , 1536 )
. Select ( _ => Random . Shared . NextSingle ( ) )
. ToArray ( )
} )
. ToArray ( ) ;
// Specify the retry limit we are okay with
var retries = 3 ;
while ( true )
{
try
{
// Perform the upsert
await index . Upsert ( vectors ) ;
// If no exception is thrown, break out of the retry loop
break ;
}
catch ( ParallelUpsertException e ) when ( retries -- > 0 )
{
// Create a hash set to efficiently filter out the failed vectors
var filter = e . FailedBatchVectorIds . ToHashSet ( ) ;
// Filter out the failed vectors from the batch and assign them to
// the 'vectors' variable consumed by 'Upsert' operation above
vectors = vectors . Where ( v => filter . Contains ( v . Id ) ) . ToArray ( ) ;
Console . WriteLine ( $ "Retrying upsert due to error: { e . Message } " ) ;
}
} Pendekatan serupa dapat digunakan untuk pulih dari operasi streamed atau batched lainnya.
Lihat ListOperationException , ParallelFetchException dan ParallelDeleteException di vectortypes.cs.
Lebih suka RestTransport secara default. Silakan temukan penjelasan terperinci untuk skenario spesifik di bawah ini.
GrpcTransport adalah alternatif yang layak untuk mengurangi lalu lintas jaringan saat bekerja dengan vektor besar di bawah skenario throughput rendah hingga sedang.
Protobuf mengkodekan vektor dengan cara yang jauh lebih kompak, jadi jika Anda memiliki vektor dimensi tinggi (1536-3072+), tingkat permintaan yang rendah dan biasanya meningkatkan atau mengambil vektor dalam bacthes kecil, ada baiknya mempertimbangkan GrpcTransport untuk kasus penggunaan Anda.
Secara teoritis, throughput konkurensi yang rendah mungkin lebih tinggi dengan GrpcTransport karena berkurangnya lalu lintas jaringan, tetapi karena seberapa sepele untuk hanya mengirimkan banyak permintaan secara paralel (dan fakta bahwa Fetch , Upsert dan Delete melakukannya secara otomatis), keuntungan dari pendekatan ini cenderung terbatas.
Pada saat penulisan, tumpukan HTTP/2 Pinecone dikonfigurasi untuk memungkinkan sedikit atau bahkan hanya 1 aliran bersamaan per koneksi HTTP/2 tunggal.
Karena HTTP/2 wajib untuk GRPC, ini menyebabkan permintaan yang signifikan mengantri melalui saluran GRPC di bawah skenario konkurensi tinggi, yang menghasilkan skalabilitas yang buruk dari GrpcTransport dengan langit -langit rendah untuk throughput.
Pengguna yang tidak menyadari batasan ini dapat mengalami peningkatan latensi yang tidak terduga dalam operasi kueri mereka di bawah jumlah pengguna yang berkembang per node aplikasi dan/atau jauh lebih rendah dari yang diharapkan dan mengambil throughput bahkan ketika secara manual menentukan tingkat paralelis yang lebih besar dari operasi Upsert dan Fetch .
Pinecone.NET Sebagian mengurangi masalah ini dengan mengkonfigurasi saluran GRPC untuk memanfaatkan penyeimbangan beban sisi klien (berdasarkan catatan DNS) untuk memanfaatkan beberapa sub-saluran (saat ini masih ada 3 yang dikembalikan oleh permintaan DNS), yang diharapkan dapat memberikan throughput yang lebih baik daripada klien lain. Ini juga memungkinkan penggunaan beberapa koneksi HTTP/2 per titik akhir untuk SocketsHttpHandler yang mendasarinya tetapi implementasi GRPC saat ini tampaknya tidak memanfaatkannya dengan baik.
Di atas adalah pengamatan perilaku klien di bawah pengujian beban dan faktor infrastruktur tambahan mungkin berperan seperti yang ditunjukkan oleh laporan pengguna di forum komunitas Pinecone WRT skalabilitas dalam implementasi lain.
Pengguna ahli yang masih ingin menggunakan transportasi GRPC dalam skenario beban tinggi mungkin ingin mengeksplorasi item tindakan lebih lanjut yang berada di luar cakupan perpustakaan yang didukung komunitas sederhana ini:
Pengguna reguler disarankan untuk menggunakan RestTransport untuk skenario throughput tinggi dan/atau konkurensi tinggi sebagai gantinya, kecuali jika evaluasi GrpcTransport mereka di lingkungan spesifik mereka menghasilkan hasil yang lebih baik.
Sampai sekarang, RestTransport dan System.Text.Json yang digunakan untuk serialisasi tampaknya lebih efisien memori daripada GrpcTransport dan Protobuf . Ini bukan batasan yang melekat dari GRPC, melainkan hasil dari implementasi grpc-dotnet saat ini. System.Text.Json sangat dioptimalkan sehubungan dengan lalu lintas alokasi dan menghasilkan penggunaan memori berkelanjutan yang secara signifikan lebih rendah di bawah beban ringan dan berat. Mengingat kondisi implementasi grpc-dotnet saat ini, saya tidak mengantisipasi hal ini untuk berubah dalam waktu dekat. Ini "cukup baik" untuk sebagian besar aplikasi, tetapi perbedaan ukuran tumpukan berkelanjutan di bawah beban cukup signifikan untuk menjamin menyatakan ini secara eksplisit.
Harap dicatat bahwa Pinecone.NET sudah melakukan konstruksi nol-salinan/pembacaan yang RepeatedField<float> yang menyimpan nilai vektor untuk mengurangi tekanan alokasi, tetapi tidak cukup untuk mengimbangi keuntungan menggunakan System.Text.Json polos.text.json.
Kontribusi dipersilakan! Jangan ragu untuk membuka masalah atau PR.