Was sind Semantic Kernel Vector Store Connectors? (Vorschau)
Warnung
Die Funktionalität des semantischen Kernelvektorspeichers befindet sich in der Vorschau, und Verbesserungen, die fehlerhafte Änderungen erfordern, können unter begrenzten Umständen noch vor der Veröffentlichung auftreten.
Tipp
Wenn Sie nach Informationen zu den älteren Speicherspeicherconnectors suchen, lesen Sie die Seite "Speicherspeicher".
Vektordatenbanken haben viele Anwendungsfälle in verschiedenen Domänen und Anwendungen, die die Verarbeitung natürlicher Sprachen (Natural Language Processing, NLP), Computer vision (CV), Empfehlungssysteme (RS) und andere Bereiche umfassen, die semantisches Verständnis und Abgleich von Daten erfordern.
Ein Anwendungsfall zum Speichern von Informationen in einer Vektordatenbank besteht darin, großen Sprachmodellen (LLMs) die Generierung relevanterer und kohärenterer Antworten zu ermöglichen. Große Sprachmodelle stellen sich häufig vor Herausforderungen, z. B. das Generieren ungenauer oder irrelevanter Informationen; fehlende sachliche Konsistenz oder Allgemeinverstand; sich wiederholen oder widersprechen; sie sind voreingenommen oder anstößig. Um diese Herausforderungen zu überwinden, können Sie eine Vektordatenbank verwenden, um Informationen zu verschiedenen Themen, Schlüsselwörtern, Fakten, Meinungen und/oder Quellen im Zusammenhang mit Ihrer gewünschten Domäne oder Ihrem Genre zu speichern. Mit der Vektordatenbank können Sie die Teilmenge der Informationen, die sich auf eine bestimmte Frage oder ein bestimmtes Thema beziehen, effizient finden. Anschließend können Sie Informationen aus der Vektordatenbank mit Der Aufforderung an Ihr großes Sprachmodell übergeben, um genauere und relevantere Inhalte zu generieren.
Wenn Sie beispielsweise einen Blogbeitrag zu den neuesten Trends in KI schreiben möchten, können Sie eine Vektordatenbank verwenden, um die neuesten Informationen zu diesem Thema zu speichern und die Informationen zusammen mit der Anforderung an eine LLM zu übergeben, um einen Blogbeitrag zu generieren, der die neuesten Informationen nutzt.
Der semantische Kernel und .net bietet eine Abstraktion für die Interaktion mit Vector Stores und eine Liste von out-of-the-box Connectors, die diese Abstraktionen implementieren. Zu den Features gehören das Erstellen, Auflisten und Löschen von Auflistungen von Datensätzen sowie das Hochladen, Abrufen und Löschen von Datensätzen. Die Abstraktion erleichtert das Experimentieren mit einem kostenlosen oder lokal gehosteten Vector Store und wechselt dann bei Bedarf zum Skalieren zu einem Dienst.
Abstraktion des Vektorspeichers
Die wichtigsten Schnittstellen in der Vektorspeicher-Abstraktion sind die folgenden.
Microsoft.Extensions.VectorData.IVectorStore
IVectorStore
enthält Vorgänge, die sich über alle Auflistungen im Vektorspeicher erstrecken, z. B. ListCollectionNames.
Es bietet auch die Möglichkeit, Instanzen abzurufen IVectorStoreRecordCollection<TKey, TRecord>
.
Microsoft.Extensions.VectorData.IVectorStoreRecordCollection<TKey, TRecord>
IVectorStoreRecordCollection<TKey, TRecord>
stellt eine Auflistung dar.
Diese Auflistung ist möglicherweise vorhanden oder nicht vorhanden, und die Schnittstelle stellt Methoden bereit, um zu überprüfen, ob die Auflistung vorhanden ist, sie zu erstellen oder zu löschen.
Die Schnittstelle stellt außerdem Methoden zum Upsert-, Abrufen und Löschen von Datensätzen bereit.
Schließlich erbt die Schnittstelle von der Bereitstellung von IVectorizedSearch<TRecord>
Vektorsuchfunktionen.
Microsoft.Extensions.VectorData.IVectorizedSearch<TRecord>
IVectorizedSearch<TRecord>
enthält eine Methode zum Ausführen von Vektorsuchen.
IVectorStoreRecordCollection<TKey, TRecord>
erbt von der IVectorizedSearch<TRecord>
Möglichkeit, die Verwendung allein in Fällen zu ermöglichen IVectorizedSearch<TRecord>
, in denen nur eine Suche erforderlich ist und keine Datensatz- oder Sammlungsverwaltung erforderlich ist.
IVectorizableTextSearch<TRecord>
IVectorizableTextSearch<TRecord>
enthält eine Methode zum Ausführen von Vektorsuchen, bei denen die Vektordatenbank die Möglichkeit hat, Einbettungen automatisch zu generieren. Sie können diese Methode z. B. mit einer Textzeichenfolge aufrufen, und die Datenbank generiert die Einbettung für Sie und sucht nach einem Vektorfeld. Dies wird nicht von allen Vektordatenbanken unterstützt und wird daher nur von ausgewählten Connectors implementiert.
Abstraktion des Vektorspeichers
Die wichtigsten Schnittstellen in der Vektorspeicher-Abstraktion sind die folgenden.
com.microsoft.semantickernel.data.vectorstorage.VectorStore
VectorStore
enthält Vorgänge, die sich über alle Auflistungen im Vektorspeicher erstrecken, z. B. listCollectionNames.
Es bietet auch die Möglichkeit, Instanzen abzurufen VectorStoreRecordCollection<Key, Record>
.
com.microsoft.semantickernel.data.vectorstorage.VectorStoreRecordCollection<Key, Record>
VectorStoreRecordCollection<Key, Record>
stellt eine Auflistung dar.
Diese Auflistung ist möglicherweise vorhanden oder nicht vorhanden, und die Schnittstelle stellt Methoden bereit, um zu überprüfen, ob die Auflistung vorhanden ist, sie zu erstellen oder zu löschen.
Die Schnittstelle stellt außerdem Methoden zum Upsert-, Abrufen und Löschen von Datensätzen bereit.
Schließlich erbt die Schnittstelle von der Bereitstellung von VectorizedSearch<Record>
Vektorsuchfunktionen.
com.microsoft.semantickernel.data.vectorsearch.VectorizedSearch<Record>
VectorizedSearch<Record>
enthält eine Methode zum Ausführen von Vektorsuchen.
VectorStoreRecordCollection<Key, Record>
erbt von der VectorizedSearch<Record>
Möglichkeit, die Verwendung allein in Fällen zu ermöglichen VectorizedSearch<Record>
, in denen nur eine Suche erforderlich ist und keine Datensatz- oder Sammlungsverwaltung erforderlich ist.
com.microsoft.semantickernel.data.vectorsearch.VectorizableTextSearch<Record>
VectorizableTextSearch<Record>
enthält eine Methode zum Ausführen von Vektorsuchen, bei denen die Vektordatenbank die Möglichkeit hat, Einbettungen automatisch zu generieren. Sie können diese Methode z. B. mit einer Textzeichenfolge aufrufen, und die Datenbank generiert die Einbettung für Sie und sucht nach einem Vektorfeld. Dies wird nicht von allen Vektordatenbanken unterstützt und wird daher nur von ausgewählten Connectors implementiert.
Erste Schritte mit Vector Store-Connectors
Importieren der erforderlichen Nuget-Pakete
Alle Vektorspeicherschnittstellen und alle zugehörigen Abstraktionsklassen sind im Microsoft.Extensions.VectorData.Abstractions
Nuget-Paket verfügbar.
Jede Vektorspeicherimplementierung ist in einem eigenen Nuget-Paket verfügbar. Eine Liste bekannter Implementierungen finden Sie auf der Seite "Out-of-the-box connectors".
Das Abstraktionspaket kann wie folgt hinzugefügt werden.
dotnet add package Microsoft.Extensions.VectorData.Abstractions --prerelease
Warnung
Ab Version 1.23.0 des semantischen Kernels wurden die Vektorspeicherabstraktionen entfernt Microsoft.SemanticKernel.Abstractions
und stehen im neuen dedizierten Microsoft.Extensions.VectorData.Abstractions
Paket zur Verfügung.
Beachten Sie, dass von Version 1.23.0 Microsoft.SemanticKernel.Abstractions
eine Abhängigkeit besteht Microsoft.Extensions.VectorData.Abstractions
, daher müssen keine zusätzlichen Pakete referenziert werden.
Die Abstraktionen befinden sich jedoch jetzt im neuen Microsoft.Extensions.VectorData
Namespace.
Beim Upgrade von 1.22.0 oder früher auf 1.23.0 oder höher müssen Sie eine zusätzliche using Microsoft.Extensions.VectorData;
Klausel in Dateien hinzufügen, in denen eines der Vector Store-Abstraktionstypen verwendet wird, z. B. IVectorStore
, IVectorStoreRecordCollection
, , VectorStoreRecordDataAttribute
, VectorStoreRecordKeyProperty
usw.
Diese Änderung wurde vorgenommen, um Vektorspeicheranbieter beim Erstellen eigener Implementierungen zu unterstützen. Ein Anbieter muss nur auf das Microsoft.Extensions.VectorData.Abstractions
Paket verweisen. Dadurch werden potenzielle Versionskonflikte reduziert und der semantische Kernel kann sich weiterhin schnell weiterentwickeln, ohne dass sich dies auf Vektorspeicheranbieter auswirkt.
Definieren des Datenmodells
Die Connectors für den semantischen Kernelvektorspeicher verwenden zunächst einen Modellansatz für die Interaktion mit Datenbanken. Dies bedeutet, dass der erste Schritt darin besteht, ein Datenmodell zu definieren, das dem Speicherschema zugeordnet ist. Damit die Connectors Sammlungen von Datensätzen erstellen und dem Speicherschema zugeordnet werden können, kann das Modell kommentiert werden, um die Funktion jeder Eigenschaft anzugeben.
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; }
}
Tipp
Weitere Informationen zum Kommentieren des Datenmodells finden Sie unter Definieren des Datenmodells.
Tipp
Eine Alternative zum Kommentieren des Datenmodells finden Sie unter Definieren des Schemas mit einer Datensatzdefinition.
Stellen Sie eine Verbindung mit Ihrer Datenbank her, und wählen Sie eine Sammlung aus.
Nachdem Sie Das Datenmodell definiert haben, besteht der nächste Schritt darin, eine VectorStore-Instanz für die Datenbank Ihrer Wahl zu erstellen und eine Sammlung von Datensätzen auszuwählen.
In diesem Beispiel verwenden wir Qdrant. Daher müssen Sie das Qdrant Nuget-Paket importieren.
dotnet add package Microsoft.SemanticKernel.Connectors.Qdrant --prerelease
Da Datenbanken viele verschiedene Arten von Schlüsseln und Datensätzen unterstützen, können Sie den Schlüssel- und Datensatztyp für Ihre Sammlung mithilfe von Generika angeben.
In unserem Fall ist der Typ des Datensatzes die Klasse, die Hotel
wir bereits definiert haben, und der Schlüsseltyp istulong
, da die HotelId
Eigenschaft ein ulong
und Qdrant nur unterstützt oder ulong
Schlüssel istGuid
.
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");
Da Datenbanken viele verschiedene Arten von Schlüsseln und Datensätzen unterstützen, können Sie den Schlüssel- und Datensatztyp für Ihre Sammlung mithilfe von Generika angeben.
In unserem Fall ist der Typ des Datensatzes die Klasse, die Hotel
wir bereits definiert haben, und der Schlüsseltyp iststr
, da die HotelId
Eigenschaft ein str
und Qdrant nur unterstützt oder int
Schlüssel iststr
.
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
)
Da Datenbanken viele verschiedene Arten von Schlüsseln und Datensätzen unterstützen, können Sie den Schlüssel- und Datensatztyp für Ihre Sammlung mithilfe von Generika angeben.
In unserem Fall ist der Typ des Datensatzes die Klasse, die Hotel
wir bereits definiert haben, und der Schlüsseltyp lautet String
, da die hotelId
Eigenschaft ein String
und VORGANGsspeicher nur Schlüssel unterstützt String
.
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()
);
}
}
Tipp
Weitere Informationen dazu, welche Schlüssel- und Feldtypen jeder Vector Store-Connector unterstützt, finden Sie in der Dokumentation für jeden Connector.
Erstellen der Sammlung und Hinzufügen von Datensätzen
// 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);
Erstellen der Sammlung und Hinzufügen von Datensätzen
# 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();
Tipp
Weitere Informationen zum Generieren von Einbettungen finden Sie unter "Einbettungsgenerierung".
Durchführen einer Vektorsuche
// 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());
Tipp
Weitere Informationen zum Generieren von Einbettungen finden Sie unter "Einbettungsgenerierung".