Co jsou konektory sémantického úložiště vektorů jádra? (Preview)
Upozorňující
Funkce sémantického úložiště vektorů jádra je ve verzi Preview a vylepšení, která vyžadují zásadní změny, se můžou vyskytovat za omezených okolností před vydáním.
Tip
Pokud hledáte informace o starších konektorech úložiště paměti, podívejte se na stránku Úložiště paměti.
Vektorové databáze mají mnoho případů použití v různých doménách a aplikacích, které zahrnují zpracování přirozeného jazyka (NLP), počítačové zpracování obrazu (CV), systémy doporučení (RS) a další oblasti, které vyžadují sémantické porozumění a porovnávání dat.
Jedním z případů použití pro ukládání informací do vektorové databáze je umožnit velkým jazykovým modelům (LLM) generovat relevantnější a koherentní odpovědi. Velké jazykové modely často čelí výzvám, jako je generování nepřesných nebo irelevantních informací; nedostatek faktické konzistence nebo běžného rozumu; opakování nebo v rozporu se sebou; být zkreslený nebo urážlivý. Pokud chcete tyto výzvy překonat, můžete pomocí vektorové databáze ukládat informace o různých tématech, klíčových slovech, faktech, názorech a zdrojích souvisejících s požadovanou doménou nebo žánrem. Vektorová databáze umožňuje efektivně najít podmnožinu informací souvisejících s konkrétní otázkou nebo tématem. Pak můžete předat informace z vektorové databáze s výzvou k vytvoření přesnějšího a relevantnějšího obsahu ve velkém jazykovém modelu.
Pokud například chcete napsat blogový příspěvek o nejnovějších trendech v AI, můžete použít vektorovou databázi k uložení nejnovějších informací o tomto tématu a předání informací spolu s dotazem na LLM, aby se vygeneroval blogový příspěvek, který využívá nejnovější informace.
Sémantické jádro a .net poskytují abstrakci pro interakci s vektorovými úložišti a seznam předpočinkových konektorů, které tyto abstrakce implementují. Mezi funkce patří vytváření, výpis a odstraňování kolekcí záznamů a nahrávání, načítání a odstraňování záznamů. Abstrakce usnadňuje experimentování s bezplatným nebo místně hostovaným Vector Storem a následným přepnutím na službu, když potřebujete vertikálně navýšit kapacitu.
Abstrakce úložiště vektorů
Hlavní rozhraní abstrakce vektorového úložiště jsou následující.
Microsoft.Extensions.VectorData.IVectorStore
IVectorStore
obsahuje operace, které pokrývají všechny kolekce v úložišti vektorů, například ListCollectionNames.
Poskytuje také možnost získat IVectorStoreRecordCollection<TKey, TRecord>
instance.
Microsoft.Extensions.VectorData.IVectorStoreRecordCollection<TKey, TRecord>
IVectorStoreRecordCollection<TKey, TRecord>
představuje kolekci.
Tato kolekce může nebo nemusí existovat a rozhraní poskytuje metody pro kontrolu, zda kolekce existuje, vytvořit ji nebo odstranit.
Rozhraní také poskytuje metody pro upsertování, získání a odstranění záznamů.
Nakonec rozhraní dědí z IVectorizedSearch<TRecord>
poskytování funkcí vektorového vyhledávání.
Microsoft.Extensions.VectorData.IVectorizedSearch<TRecord>
IVectorizedSearch<TRecord>
obsahuje metodu pro provádění vektorových hledání.
IVectorStoreRecordCollection<TKey, TRecord>
dědí od IVectorizedSearch<TRecord>
toho, aby bylo možné použít IVectorizedSearch<TRecord>
samostatně v případech, kdy je potřeba pouze hledat a není potřeba žádná správa záznamů nebo kolekcí.
IVectorizableTextSearch<TRecord>
IVectorizableTextSearch<TRecord>
obsahuje metodu pro vyhledávání vektorů, ve kterých má vektorová databáze schopnost automaticky generovat vkládání. Tuto metodu můžete například volat s textovým řetězcem a databáze vygeneruje vkládání za vás a prohledává vektorové pole. Tato funkce není podporována všemi vektorovými databázemi a proto je implementována pouze pomocí vybraných konektorů.
Abstrakce úložiště vektorů
Hlavní rozhraní abstrakce vektorového úložiště jsou následující.
com.microsoft.semantickernel.data.vectorstorage.VectorStore
VectorStore
obsahuje operace, které pokrývají všechny kolekce v úložišti vektorů, například listCollectionNames.
Poskytuje také možnost získat VectorStoreRecordCollection<Key, Record>
instance.
com.microsoft.semantickernel.data.vectorstorage.VectorStoreRecordCollection<Key, Record>
VectorStoreRecordCollection<Key, Record>
představuje kolekci.
Tato kolekce může nebo nemusí existovat a rozhraní poskytuje metody pro kontrolu, zda kolekce existuje, vytvořit ji nebo odstranit.
Rozhraní také poskytuje metody pro upsertování, získání a odstranění záznamů.
Nakonec rozhraní dědí z VectorizedSearch<Record>
poskytování funkcí vektorového vyhledávání.
com.microsoft.semantickernel.data.vectorsearch.VectorizedSearch<– záznam>
VectorizedSearch<Record>
obsahuje metodu pro provádění vektorových hledání.
VectorStoreRecordCollection<Key, Record>
dědí od VectorizedSearch<Record>
toho, aby bylo možné použít VectorizedSearch<Record>
samostatně v případech, kdy je potřeba pouze hledat a není potřeba žádná správa záznamů nebo kolekcí.
com.microsoft.semantickernel.data.vectorsearch.VectorizableTextSearch<– záznam>
VectorizableTextSearch<Record>
obsahuje metodu pro vyhledávání vektorů, ve kterých má vektorová databáze schopnost automaticky generovat vkládání. Tuto metodu můžete například volat s textovým řetězcem a databáze vygeneruje vkládání za vás a prohledává vektorové pole. Tato funkce není podporována všemi vektorovými databázemi a proto je implementována pouze pomocí vybraných konektorů.
Začínáme s konektory služby Vector Store
Import potřebných balíčků NuGet
Všechna rozhraní úložiště vektorů a všechny abstrakce související třídy jsou k dispozici v Microsoft.Extensions.VectorData.Abstractions
balíčku nuget.
Každá implementace úložiště vektorů je k dispozici ve vlastním balíčku NuGet. Seznamznámýchch
Balíček abstrakcí lze přidat takto.
dotnet add package Microsoft.Extensions.VectorData.Abstractions --prerelease
Upozorňující
Z verze 1.23.0 sémantického jádra byly abstrakce vektorového úložiště odebrány Microsoft.SemanticKernel.Abstractions
a jsou k dispozici v novém vyhrazeném Microsoft.Extensions.VectorData.Abstractions
balíčku.
Všimněte si, Microsoft.SemanticKernel.Abstractions
že od verze 1.23.0 je závislost na Microsoft.Extensions.VectorData.Abstractions
, a proto není nutné odkazovat na další balíčky.
Abstrakce ale budou v novém Microsoft.Extensions.VectorData
oboru názvů.
Při upgradu z verze 1.22.0 nebo starší na verzi 1.23.0 nebo novější budete muset do souborů přidat další using Microsoft.Extensions.VectorData;
klauzuli, ve které se používají některé typy abstrakce služby Vector Store, například IVectorStore
, IVectorStoreRecordCollection
, VectorStoreRecordDataAttribute
, VectorStoreRecordKeyProperty
, atd.
Tato změna byla provedena kvůli podpoře poskytovatelů vektorových úložiště při vytváření vlastních implementací. Zprostředkovatel musí odkazovat pouze na Microsoft.Extensions.VectorData.Abstractions
balíček. To snižuje potenciální konflikty verzí a umožňuje sémantickému jádru pokračovat v rychlém vývoji, aniž by to mělo vliv na zprostředkovatele úložiště vektorů.
Definování datového modelu
Konektory sémantického úložiště vektorů jádra používají první přístup modelu k interakci s databázemi. To znamená, že prvním krokem je definování datového modelu, který se mapuje na schéma úložiště. Aby konektory pomohly vytvářet kolekce záznamů a mapovat na schéma úložiště, může být model opatřen poznámkami k označení funkce jednotlivých vlastností.
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.CosineDistance, 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
Další informace o tom, jak anotovat datový model, najdete v tématu definování datového modelu.
Tip
Alternativu k přidávání poznámek k datovému modelu najdete v definování schématu s definicí záznamu.
Připojte se k databázi a vyberte kolekci.
Jakmile definujete datový model, dalším krokem je vytvoření instance VectorStore pro databázi podle vašeho výběru a výběr kolekce záznamů.
V tomto příkladu použijeme Qdrant. Proto budete muset importovat balíček nuget Qdrant.
dotnet add package Microsoft.SemanticKernel.Connectors.Qdrant --prerelease
Vzhledem k tomu, že databáze podporují mnoho různých typů klíčů a záznamů, umožňujeme určit typ klíče a záznamu pro vaši kolekci pomocí obecných typů.
V našem případě bude typ záznamu Hotel
třídou, již jsme definovali, a typ klíče bude ulong
, protože HotelId
vlastnost je ulong
a Qdrant podporuje Guid
pouze nebo ulong
klíče.
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");
Vzhledem k tomu, že databáze podporují mnoho různých typů klíčů a záznamů, umožňujeme určit typ klíče a záznamu pro vaši kolekci pomocí obecných typů.
V našem případě bude typ záznamu Hotel
třídou, již jsme definovali, a typ klíče bude str
, protože HotelId
vlastnost je str
a Qdrant podporuje str
pouze nebo int
klíče.
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
)
Vzhledem k tomu, že databáze podporují mnoho různých typů klíčů a záznamů, umožňujeme určit typ klíče a záznamu pro vaši kolekci pomocí obecných typů.
V našem případě bude typ záznamu Hotel
třídou, již jsme definovali, a typ klíče bude String
, protože hotelId
vlastnost je String
a úložiště JDBC podporuje String
pouze klíče.
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
Další informace o tom, jaké typy klíčů a polí každý konektor Vector Store podporuje, najdete v dokumentaci ke každému konektoru.
Vytvoření kolekce a přidání záznamů
// 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.
// Just showing a placeholder embedding generation method here for brevity.
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);
Vytvoření kolekce a přidání záznamů
# 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
Další informace o tom, jak vygenerovat vkládání, najdete v tématu generování vkládání.
Hledání vektorů
// Generate a vector for your search text, using your chosen embedding generation implementation.
// Just showing a placeholder method here for brevity.
var 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 }).Results.ToListAsync()
// Inspect the returned hotels.
Hotel hotel = searchResult.First().Record;
Console.WriteLine("Found hotel description: " + hotel.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
Další informace o tom, jak vygenerovat vkládání, najdete v tématu generování vkládání.