Apa itu konektor Semantic Kernel Vector Store? (Pratinjau)
Peringatan
Fungsionalitas Penyimpanan Vektor Kernel Semantik sedang dalam pratinjau, dan peningkatan yang memerlukan perubahan yang melanggar mungkin masih terjadi dalam keadaan terbatas sebelum rilis.
Tip
Jika Anda mencari informasi tentang konektor Penyimpanan Memori warisan, lihat halaman Penyimpanan Memori.
Database vektor memiliki banyak kasus penggunaan di berbagai domain dan aplikasi yang melibatkan pemrosesan bahasa alami (NLP), computer vision (CV), sistem rekomendasi (RS), dan area lain yang memerlukan pemahaman semantik dan pencocokan data.
Satu kasus penggunaan untuk menyimpan informasi dalam database vektor adalah mengaktifkan model bahasa besar (LLM) untuk menghasilkan respons yang lebih relevan dan koheren. Model bahasa besar sering menghadapi tantangan seperti menghasilkan informasi yang tidak akurat atau tidak relevan; tidak memiliki konsistensi faktual atau akal sehat; mengulangi atau bertentangan dengan diri mereka sendiri; menjadi bias atau menyinggung. Untuk membantu mengatasi tantangan ini, Anda dapat menggunakan database vektor untuk menyimpan informasi tentang berbagai topik, kata kunci, fakta, opini, dan/atau sumber yang terkait dengan domain atau genre yang Anda inginkan. Database vektor memungkinkan Anda menemukan subset informasi yang terkait dengan pertanyaan atau topik tertentu secara efisien. Anda kemudian dapat meneruskan informasi dari database vektor dengan permintaan Anda ke model bahasa besar Anda untuk menghasilkan konten yang lebih akurat dan relevan.
Misalnya, jika Anda ingin menulis posting blog tentang tren terbaru di AI, Anda dapat menggunakan database vektor untuk menyimpan informasi terbaru tentang topik itu dan meneruskan informasi bersama dengan permintaan ke LLM untuk menghasilkan posting blog yang memanfaatkan informasi terbaru.
Semantic Kernel dan .net menyediakan abstraksi untuk berinteraksi dengan Vector Stores dan daftar konektor out-of-the-box yang mengimplementasikan abstraksi ini. Fitur termasuk membuat, mencantumkan, dan menghapus koleksi rekaman, dan mengunggah, mengambil, dan menghapus rekaman. Abstraksi memudahkan untuk bereksperimen dengan Vektor Store gratis atau yang dihosting secara lokal dan kemudian beralih ke layanan ketika perlu meningkatkan skala.
Pengambilan Augmented Generation (RAG) dengan Vector Stores
Abstraksi penyimpanan vektor adalah api tingkat rendah untuk menambahkan dan mengambil data dari penyimpanan vektor.
Semantic Kernel memiliki dukungan bawaan untuk menggunakan salah satu implementasi Vector Store untuk RAG.
Ini dicapai dengan membungkus IVectorizedSearch<TRecord>
dan mengeksposnya sebagai implementasi Pencarian Teks.
Tip
Untuk mempelajari selengkapnya tentang cara menggunakan penyimpanan vektor untuk RAG, lihat Cara menggunakan Penyimpanan Vektor dengan Pencarian Teks Kernel Semantik.
Tip
Untuk mempelajari selengkapnya tentang pencarian teks, lihat Apa itu Pencarian Teks Kernel Semantik?
Abstraksi Penyimpanan Vektor
Antarmuka utama dalam abstraksi Vector Store adalah sebagai berikut.
Microsoft.Extensions.VectorData.IVectorStore
IVectorStore
berisi operasi yang mencakup semua koleksi di penyimpanan vektor, misalnya ListCollectionNames.
Ini juga menyediakan kemampuan untuk mendapatkan IVectorStoreRecordCollection<TKey, TRecord>
instans.
Microsoft.Extensions.VectorData.IVectorStoreRecordCollection<TKey, TRecord>
IVectorStoreRecordCollection<TKey, TRecord>
mewakili koleksi.
Koleksi ini mungkin atau mungkin tidak ada, dan antarmuka menyediakan metode untuk memeriksa apakah koleksi ada, membuatnya, atau menghapusnya.
Antarmuka juga menyediakan metode untuk melakukan upsert, mendapatkan, dan menghapus rekaman.
Akhirnya, antarmuka mewarisi dari IVectorizedSearch<TRecord>
menyediakan kemampuan pencarian vektor.
Microsoft.Extensions.VectorData.IVectorizedSearch<TRecord>
IVectorizedSearch<TRecord>
berisi metode untuk melakukan pencarian vektor.
IVectorStoreRecordCollection<TKey, TRecord>
mewarisi dari IVectorizedSearch<TRecord>
memungkinkan untuk digunakan IVectorizedSearch<TRecord>
sendiri dalam kasus di mana hanya pencarian yang diperlukan dan tidak diperlukan manajemen rekaman atau koleksi.
IVectorizableTextSearch<TRecord>
IVectorizableTextSearch<TRecord>
berisi metode untuk melakukan pencarian vektor di mana database vektor memiliki kemampuan untuk menghasilkan penyematan secara otomatis. Misalnya, Anda dapat memanggil metode ini dengan string teks dan database akan menghasilkan penyematan untuk Anda dan mencari bidang vektor. Ini tidak didukung oleh semua database vektor dan oleh karena itu hanya diimplementasikan oleh konektor tertentu.
Pengambilan Augmented Generation (RAG) dengan Vector Stores
Abstraksi penyimpanan vektor adalah api tingkat rendah untuk menambahkan dan mengambil data dari penyimpanan vektor.
Semantic Kernel memiliki dukungan bawaan untuk menggunakan salah satu implementasi Vector Store untuk RAG.
Ini dicapai dengan membungkus VectorSearchBase[TKey, TModel]
dengan VectorizedSearchMixin[Tmodel]
, VectorizableTextSearchMixin[TModel]
atau VectorTextSearch[TModel]
dan mengeksposnya sebagai implementasi Pencarian Teks.
Tip
Untuk mempelajari selengkapnya tentang cara menggunakan penyimpanan vektor untuk RAG, lihat Cara menggunakan Penyimpanan Vektor dengan Pencarian Teks Kernel Semantik.
Tip
Untuk mempelajari selengkapnya tentang pencarian teks, lihat Apa itu Pencarian Teks Kernel Semantik?
Abstraksi Penyimpanan Vektor
Antarmuka utama dalam abstraksi Vector Store adalah sebagai berikut.
com.microsoft.semantickernel.data.vectorstorage.VectorStore
VectorStore
berisi operasi yang mencakup semua koleksi di penyimpanan vektor, misalnya listCollectionNames.
Ini juga menyediakan kemampuan untuk mendapatkan VectorStoreRecordCollection<Key, Record>
instans.
com.microsoft.semantickernel.data.vectorstorage.VectorStoreRecordCollection<Key, Record>
VectorStoreRecordCollection<Key, Record>
mewakili koleksi.
Koleksi ini mungkin atau mungkin tidak ada, dan antarmuka menyediakan metode untuk memeriksa apakah koleksi ada, membuatnya, atau menghapusnya.
Antarmuka juga menyediakan metode untuk melakukan upsert, mendapatkan, dan menghapus rekaman.
Akhirnya, antarmuka mewarisi dari VectorizedSearch<Record>
menyediakan kemampuan pencarian vektor.
com.microsoft.semantickernel.data.vectorsearch.VectorizedSearch<Record>
VectorizedSearch<Record>
berisi metode untuk melakukan pencarian vektor.
VectorStoreRecordCollection<Key, Record>
mewarisi dari VectorizedSearch<Record>
memungkinkan untuk digunakan VectorizedSearch<Record>
sendiri dalam kasus di mana hanya pencarian yang diperlukan dan tidak diperlukan manajemen rekaman atau koleksi.
com.microsoft.semantickernel.data.vectorsearch.VectorizableTextSearch<Record>
VectorizableTextSearch<Record>
berisi metode untuk melakukan pencarian vektor di mana database vektor memiliki kemampuan untuk menghasilkan penyematan secara otomatis. Misalnya, Anda dapat memanggil metode ini dengan string teks dan database akan menghasilkan penyematan untuk Anda dan mencari bidang vektor. Ini tidak didukung oleh semua database vektor dan oleh karena itu hanya diimplementasikan oleh konektor tertentu.
Mulai menggunakan konektor Vector Store
Mengimpor paket nuget yang diperlukan
Semua antarmuka penyimpanan vektor dan kelas terkait abstraksi tersedia dalam Microsoft.Extensions.VectorData.Abstractions
paket nuget.
Setiap implementasi penyimpanan vektor tersedia dalam paket nugetnya sendiri. Untuk daftar implementasi yang diketahui, lihat halaman Konektor di luar kotak.
Paket abstraksi dapat ditambahkan seperti ini.
dotnet add package Microsoft.Extensions.VectorData.Abstractions --prerelease
Peringatan
Dari versi 1.23.0 dari Semantic Kernel, abstraksi Vector Store telah dihapus dari Microsoft.SemanticKernel.Abstractions
dan tersedia dalam paket khusus Microsoft.Extensions.VectorData.Abstractions
baru.
Perhatikan bahwa dari versi 1.23.0, Microsoft.SemanticKernel.Abstractions
memiliki dependensi pada Microsoft.Extensions.VectorData.Abstractions
, oleh karena itu tidak perlu mereferensikan paket tambahan.
Abstraksi sekarang akan berada di namespace baru Microsoft.Extensions.VectorData
.
Saat meningkatkan dari 1.22.0 atau yang lebih lama ke 1.23.0 atau yang lebih baru, Anda harus menambahkan klausul tambahan using Microsoft.Extensions.VectorData;
dalam file di mana salah satu jenis abstraksi Vector Store digunakan misalnya IVectorStore
, , IVectorStoreRecordCollection
, VectorStoreRecordDataAttribute
, VectorStoreRecordKeyProperty
dll.
Perubahan ini telah dilakukan untuk mendukung penyedia penyimpanan vektor saat membuat implementasi mereka sendiri. Penyedia hanya harus mereferensikan Microsoft.Extensions.VectorData.Abstractions
paket. Ini mengurangi potensi konflik versi dan memungkinkan Semantic Kernel untuk terus berkembang dengan cepat tanpa memengaruhi penyedia penyimpanan vektor.
Tentukan model data Anda
Konektor Semantic Kernel Vector Store menggunakan pendekatan pertama model untuk berinteraksi dengan database. Ini berarti bahwa langkah pertama adalah menentukan model data yang memetakan ke skema penyimpanan. Untuk membantu konektor membuat koleksi rekaman dan memetakan ke skema penyimpanan, model dapat dianotasi untuk menunjukkan fungsi setiap properti.
using Microsoft.Extensions.VectorData;
public class Hotel
{
[VectorStoreRecordKey]
public ulong HotelId { get; set; }
[VectorStoreRecordData(IsFilterable = true)]
public string HotelName { get; set; }
[VectorStoreRecordData(IsFullTextSearchable = true)]
public string Description { get; set; }
[VectorStoreRecordVector(Dimensions: 4, DistanceFunction.CosineSimilarity, IndexKind.Hnsw)]
public ReadOnlyMemory<float>? DescriptionEmbedding { get; set; }
[VectorStoreRecordData(IsFilterable = true)]
public string[] Tags { get; set; }
}
from dataclasses import dataclass, field
from typing import Annotated
from semantic_kernel.data import (
DistanceFunction,
IndexKind,
VectorStoreRecordDataField,
VectorStoreRecordDefinition,
VectorStoreRecordKeyField,
VectorStoreRecordVectorField,
vectorstoremodel,
)
@vectorstoremodel
@dataclass
class Hotel:
hotel_id: Annotated[str, VectorStoreRecordKeyField()] = field(default_factory=lambda: str(uuid4()))
hotel_name: Annotated[str, VectorStoreRecordDataField(is_filterable=True)]
description: Annotated[str, VectorStoreRecordDataField(is_full_text_searchable=True)]
description_embedding: Annotated[list[float], VectorStoreRecordVectorField(dimensions=4, distance_function=DistanceFunction.COSINE, index_kind=IndexKind.HNSW)]
tags: Annotated[list[str], VectorStoreRecordDataField(is_filterable=True)]
import com.microsoft.semantickernel.data.vectorstorage.annotations.VectorStoreRecordData;
import com.microsoft.semantickernel.data.vectorstorage.annotations.VectorStoreRecordKey;
import com.microsoft.semantickernel.data.vectorstorage.annotations.VectorStoreRecordVector;
import com.microsoft.semantickernel.data.vectorstorage.definition.DistanceFunction;
import com.microsoft.semantickernel.data.vectorstorage.definition.IndexKind;
import java.util.Collections;
import java.util.List;
public class Hotel {
@VectorStoreRecordKey
private String hotelId;
@VectorStoreRecordData(isFilterable = true)
private String name;
@VectorStoreRecordData(isFullTextSearchable = true)
private String description;
@VectorStoreRecordVector(dimensions = 4, indexKind = IndexKind.HNSW, distanceFunction = DistanceFunction.COSINE_DISTANCE)
private List<Float> descriptionEmbedding;
@VectorStoreRecordData(isFilterable = true)
private List<String> tags;
public Hotel() { }
public Hotel(String hotelId, String name, String description, List<Float> descriptionEmbedding, List<String> tags) {
this.hotelId = hotelId;
this.name = name;
this.description = description;
this.descriptionEmbedding = Collections.unmodifiableList(descriptionEmbedding);
this.tags = Collections.unmodifiableList(tags);
}
public String getHotelId() { return hotelId; }
public String getName() { return name; }
public String getDescription() { return description; }
public List<Float> getDescriptionEmbedding() { return descriptionEmbedding; }
public List<String> getTags() { return tags; }
}
Tip
Untuk informasi selengkapnya tentang cara membuat anotasi model data Anda, lihat menentukan model data Anda.
Tip
Untuk alternatif untuk menganotasi model data Anda, lihat menentukan skema Anda dengan definisi rekaman.
Menyambungkan ke database Anda dan memilih koleksi
Setelah Anda menentukan model data, langkah selanjutnya adalah membuat instans VectorStore untuk database pilihan Anda dan memilih kumpulan rekaman.
Dalam contoh ini, kita akan menggunakan Qdrant. Oleh karena itu, Anda harus mengimpor paket nuget Qdrant.
dotnet add package Microsoft.SemanticKernel.Connectors.Qdrant --prerelease
Jika Anda ingin menjalankan Qdrant secara lokal menggunakan Docker, gunakan perintah berikut untuk memulai kontainer Qdrant dengan pengaturan yang digunakan dalam contoh ini.
docker run -d --name qdrant -p 6333:6333 -p 6334:6334 qdrant/qdrant:latest
Untuk memverifikasi bahwa instans Qdrant Anda aktif dan berjalan dengan benar, kunjungi dasbor Qdrant yang dibangun ke dalam kontainer docker Qdrant: http://localhost:6333/dashboard
Karena database mendukung berbagai jenis kunci dan rekaman, kami memungkinkan Anda menentukan jenis kunci dan rekaman untuk koleksi Anda menggunakan generik.
Dalam kasus kami, jenis rekaman akan menjadi kelas yang Hotel
sudah kami tentukan, dan jenis kuncinya adalah ulong
, karena HotelId
properti adalah ulong
dan Qdrant hanya mendukung Guid
atau ulong
kunci.
using Microsoft.SemanticKernel.Connectors.Qdrant;
using Qdrant.Client;
// Create a Qdrant VectorStore object
var vectorStore = new QdrantVectorStore(new QdrantClient("localhost"));
// Choose a collection from the database and specify the type of key and record stored in it via Generic parameters.
var collection = vectorStore.GetCollection<ulong, Hotel>("skhotels");
Karena database mendukung berbagai jenis kunci dan rekaman, kami memungkinkan Anda menentukan jenis kunci dan rekaman untuk koleksi Anda menggunakan generik.
Dalam kasus kami, jenis rekaman akan menjadi kelas yang Hotel
sudah kami tentukan, dan jenis kuncinya adalah str
, karena HotelId
properti adalah str
dan Qdrant hanya mendukung str
atau int
kunci.
from semantic_kernel.connectors.memory.qdrant import QdrantStore
# Create a Qdrant VectorStore object, this will look in the environment for Qdrant related settings, and will fall back to the default, which is to run in-memory.
vector_store = QdrantStore()
# Choose a collection from the database and specify the type of key and record stored in it via Generic parameters.
collection = vector_store.get_collection(
collection_name="skhotels",
data_model_type=Hotel
)
Karena database mendukung berbagai jenis kunci dan rekaman, kami memungkinkan Anda menentukan jenis kunci dan rekaman untuk koleksi Anda menggunakan generik.
Dalam kasus kami, jenis rekaman akan menjadi kelas yang Hotel
sudah kami tentukan, dan jenis kuncinya adalah String
, karena hotelId
properti adalah String
penyimpanan JDBC dan hanya mendukung String
kunci.
import com.microsoft.semantickernel.data.jdbc.JDBCVectorStore;
import com.microsoft.semantickernel.data.jdbc.JDBCVectorStoreOptions;
import com.microsoft.semantickernel.data.jdbc.JDBCVectorStoreRecordCollectionOptions;
import com.microsoft.semantickernel.data.jdbc.mysql.MySQLVectorStoreQueryProvider;
import com.mysql.cj.jdbc.MysqlDataSource;
import java.util.List;
public class Main {
public static void main(String[] args) {
// Create a MySQL data source
var dataSource = new MysqlDataSource();
dataSource.setUrl("jdbc:mysql://localhost:3306/sk");
dataSource.setPassword("root");
dataSource.setUser("root");
// Create a JDBC vector store
var vectorStore = JDBCVectorStore.builder()
.withDataSource(dataSource)
.withOptions(
JDBCVectorStoreOptions.builder()
.withQueryProvider(MySQLVectorStoreQueryProvider.builder()
.withDataSource(dataSource)
.build())
.build()
)
.build();
// Get a collection from the vector store
var collection = vectorStore.getCollection("skhotels",
JDBCVectorStoreRecordCollectionOptions.<Hotel>builder()
.withRecordClass(Hotel.class)
.build()
);
}
}
Tip
Untuk informasi selengkapnya tentang jenis kunci dan bidang apa yang didukung setiap konektor Vector Store, lihat dokumentasi untuk setiap konektor.
Membuat koleksi dan menambahkan rekaman
// Placeholder embedding generation method.
async Task<ReadOnlyMemory<float>> GenerateEmbeddingAsync(string textToVectorize)
{
// your logic here
}
// Create the collection if it doesn't exist yet.
await collection.CreateCollectionIfNotExistsAsync();
// Upsert a record.
string descriptionText = "A place where everyone can be happy.";
ulong hotelId = 1;
// Create a record and generate a vector for the description using your chosen embedding generation implementation.
await collection.UpsertAsync(new Hotel
{
HotelId = hotelId,
HotelName = "Hotel Happy",
Description = descriptionText,
DescriptionEmbedding = await GenerateEmbeddingAsync(descriptionText),
Tags = new[] { "luxury", "pool" }
});
// Retrieve the upserted record.
Hotel? retrievedHotel = await collection.GetAsync(hotelId);
Membuat koleksi dan menambahkan rekaman
# Create the collection if it doesn't exist yet.
await collection.create_collection_if_not_exists()
# Upsert a record.
description = "A place where everyone can be happy."
hotel_id = "1"
await collection.upsert(Hotel(
hotel_id = hotel_id,
hotel_name = "Hotel Happy",
description = description,
description_embedding = await GenerateEmbeddingAsync(description),
tags = ["luxury", "pool"]
))
# Retrieve the upserted record.
retrieved_hotel = await collection.get(hotel_id)
// Create the collection if it doesn't exist yet.
collection.createCollectionAsync().block();
// Upsert a record.
var description = "A place where everyone can be happy";
var hotelId = "1";
var hotel = new Hotel(
hotelId,
"Hotel Happy",
description,
generateEmbeddingsAsync(description).block(),
List.of("luxury", "pool")
);
collection.upsertAsync(hotel, null).block();
// Retrieve the upserted record.
var retrievedHotel = collection.getAsync(hotelId, null).block();
Tip
Untuk informasi selengkapnya tentang cara membuat penyematan, lihat pembuatan penyematan.
Melakukan pencarian vektor
// Placeholder embedding generation method.
async Task<ReadOnlyMemory<float>> GenerateEmbeddingAsync(string textToVectorize)
{
// your logic here
}
// Generate a vector for your search text, using your chosen embedding generation implementation.
ReadOnlyMemory<float> searchVector = await GenerateEmbeddingAsync("I'm looking for a hotel where customer happiness is the priority.");
// Do the search.
var searchResult = await collection.VectorizedSearchAsync(searchVector, new() { Top = 1 });
// Inspect the returned hotel.
await foreach (var record in searchResult.Results)
{
Console.WriteLine("Found hotel description: " + record.Record.Description);
Console.WriteLine("Found record score: " + record.Score);
}
Melakukan pencarian vektor
# Generate a vector for your search text, using your chosen embedding generation implementation.
# Just showing a placeholder method here for brevity.
search_vector = await GenerateEmbedding("I'm looking for a hotel where customer happiness is the priority.");
# Do the search.
search_result = await collection.vectorized_search(vector=searchVector, VectorSearchOptions(top = 1 ))
# Inspect the returned hotels.
async for result in search_result.results:
print(f"Found hotel description: {result.record.description}")
// Generate a vector for your search text, using your chosen embedding generation implementation.
// Just showing a placeholder method here for brevity.
var searchVector = generateEmbeddingsAsync("I'm looking for a hotel where customer happiness is the priority.").block();
// Do the search.
var searchResult = collection.searchAsync(searchVector, VectorSearchOptions.builder()
.withTop(1).build()
).block();
Hotel record = searchResult.getResults().get(0).getRecord();
System.out.printf("Found hotel description: %s\n", record.getDescription());
Tip
Untuk informasi selengkapnya tentang cara membuat penyematan, lihat pembuatan penyematan.