Utilisation du connecteur Qdrant (préversion)
Avertissement
La fonctionnalité de magasin de vecteurs du noyau sémantique est en préversion et des améliorations nécessitant des modifications cassants peuvent toujours se produire dans des circonstances limitées avant la mise en production.
Vue d’ensemble
Le connecteur du magasin de vecteurs Qdrant peut être utilisé pour accéder aux données et les gérer dans Qdrant. Le connecteur présente les caractéristiques suivantes.
Zone Fonctionnalités | Support |
---|---|
Mappages de collection à | Collection Qdrant avec des index de charge utile pour les champs de données filtrables |
Types de propriétés de clé pris en charge |
|
Types de propriétés de données pris en charge |
|
Types de propriétés vectorielles pris en charge | Float ReadOnlyMemory<> |
Types d’index pris en charge | Hnsw |
Fonctions de distance prises en charge |
|
Prend en charge plusieurs vecteurs dans un enregistrement | Oui (configurable) |
Est-il pris en charge ? | Oui |
IsFullTextSearchable pris en charge ? | Oui |
StoragePropertyName pris en charge ? | Oui |
Mise en route
Ajoutez le package NuGet du connecteur Du magasin de vecteurs Qdrant à votre projet.
dotnet add package Microsoft.SemanticKernel.Connectors.Qdrant --prerelease
Vous pouvez ajouter le magasin de vecteurs au conteneur d’injection de dépendances disponible sur le KernelBuilder
conteneur ou au conteneur d’injection de dépendances à l’aide IServiceCollection
de méthodes d’extension fournies par le noyau sémantique.
using Microsoft.SemanticKernel;
// Using Kernel Builder.
var kernelBuilder = Kernel
.CreateBuilder()
.AddQdrantVectorStore("localhost");
using Microsoft.SemanticKernel;
// Using IServiceCollection with ASP.NET Core.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddQdrantVectorStore("localhost");
Les méthodes d’extension qui ne prennent aucun paramètre sont également fournies. Celles-ci nécessitent qu’une instance de la Qdrant.Client.QdrantClient
classe soit inscrite séparément auprès du conteneur d’injection de dépendances.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using Qdrant.Client;
// Using Kernel Builder.
var kernelBuilder = Kernel.CreateBuilder();
kernelBuilder.Services.AddSingleton<QdrantClient>(sp => new QdrantClient("localhost"));
kernelBuilder.AddQdrantVectorStore();
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using Qdrant.Client;
// Using IServiceCollection with ASP.NET Core.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<QdrantClient>(sp => new QdrantClient("localhost"));
builder.Services.AddQdrantVectorStore();
Vous pouvez construire directement une instance de magasin de vecteurs Qdrant.
using Microsoft.SemanticKernel.Connectors.Qdrant;
using Qdrant.Client;
var vectorStore = new QdrantVectorStore(new QdrantClient("localhost"));
Il est possible de construire une référence directe à une collection nommée.
using Microsoft.SemanticKernel.Connectors.Qdrant;
using Qdrant.Client;
var collection = new QdrantVectorStoreRecordCollection<Hotel>(
new QdrantClient("localhost"),
"skhotels");
Mappage de données
Le connecteur Qdrant fournit un mappeur par défaut lors du mappage des données du modèle de données au stockage. Qdrant nécessite que les propriétés soient mappées en regroupements id, charge utile et vecteurs. Le mappeur par défaut utilise les annotations de modèle ou la définition d’enregistrement pour déterminer le type de chaque propriété et effectuer ce mappage.
- La propriété de modèle de données annotée en tant que clé est mappée à l’ID de point Qdrant.
- Les propriétés du modèle de données annotées en tant que données seront mappées à l’objet de charge utile du point Qdrant.
- Les propriétés du modèle de données annotées en tant que vecteurs sont mappées à l’objet vecteur de point Qdrant.
Remplacement du nom de propriété
Pour les propriétés de données et les propriétés vectorielles (si vous utilisez le mode vecteurs nommés), vous pouvez fournir des noms de champs de remplacement à utiliser dans le stockage différent des noms de propriétés sur le modèle de données. Cela n’est pas pris en charge pour les clés, car une clé a un nom fixe dans Qdrant. Il n’est pas non plus pris en charge pour les vecteurs en mode vectoriel unique sans nom , car le vecteur est stocké sous un nom fixe.
Le remplacement du nom de propriété est effectué en définissant l’option StoragePropertyName
via les attributs du modèle de données ou la définition d’enregistrement.
Voici un exemple de modèle de données avec StoragePropertyName
défini sur ses attributs et comment cela sera représenté dans Qdrant.
using Microsoft.Extensions.VectorData;
public class Hotel
{
[VectorStoreRecordKey]
public ulong HotelId { get; set; }
[VectorStoreRecordData(IsFilterable = true, StoragePropertyName = "hotel_name")]
public string HotelName { get; set; }
[VectorStoreRecordData(IsFullTextSearchable = true, StoragePropertyName = "hotel_description")]
public string Description { get; set; }
[VectorStoreRecordVector(4, DistanceFunction.CosineDistance, IndexKind.Hnsw, StoragePropertyName = "hotel_description_embedding")]
public ReadOnlyMemory<float>? DescriptionEmbedding { get; set; }
}
{
"id": 1,
"payload": { "hotel_name": "Hotel Happy", "hotel_description": "A place where everyone can be happy." },
"vector": {
"hotel_description_embedding": [0.9, 0.1, 0.1, 0.1],
}
}
Mise en route
Installez le noyau sémantique avec les extras qdrant, qui inclut le client qdrant.
pip install semantic-kernel[qdrant]
Vous pouvez ensuite créer une instance de magasin de vecteurs à l’aide de la QdrantStore
classe, ce qui crée asyncQdrantClient à l’aide des variables QDRANT_URL
d’environnement, , QDRANT_API_KEY
, QDRANT_HOST
, QDRANT_PORT
QDRANT_GRPC_PORT
, QDRANT_PATH
QDRANT_LOCATION
et QDRANT_PREFER_GRPS
pour se connecter à l’instance Qdrant, ces valeurs peuvent également être fournies directement. Si rien n’est fourni, il revient à location=:memory:
.
from semantic_kernel.connectors.memory.qdrant import QdrantStore
vector_store = QdrantStore()
Vous pouvez également créer le magasin de vecteurs avec votre propre instance du client qdrant.
from qdrant_client.async_qdrant_client import AsyncQdrantClient
from semantic_kernel.connectors.memory.qdrant import QdrantStore
client = AsyncQdrantClient(host='localhost', port=6333)
vector_store = QdrantStore(client=client)
Vous pouvez également créer une collection directement.
from semantic_kernel.connectors.memory.qdrant import QdrantCollection
collection = QdrantCollection(collection_name="skhotels", data_model_type=hotel)
Sérialisation
Le connecteur Qdrant utilise un modèle appelé PointStruct
pour la lecture et l’écriture dans le magasin. Cela peut être importé à partir de from qdrant_client.models import PointStruct
. Les méthodes de sérialisation attendent une sortie d’une liste d’objets PointStruct, et la méthode de désérialisation renvoie une liste d’objets PointStruct.
Il existe des considérations particulières à prendre en compte pour cela avec des vecteurs nommés ou non nommés, voir ci-dessous.
Pour plus d’informations sur ce concept, consultez la documentation de sérialisation.
Modes de vecteur Qdrant
Qdrant prend en charge deux modes pour le stockage vectoriel et le connecteur Qdrant avec le mappeur par défaut prend en charge les deux modes. Le mode par défaut est un vecteur unique sans nom.
Vecteur unique sans nom
Avec cette option, une collection ne peut contenir qu’un seul vecteur et il ne sera pas nommé dans le modèle de stockage dans Qdrant. Voici un exemple de représentation d’un objet dans Qdrant lors de l’utilisation d’un mode vectoriel sans nom unique :
new Hotel
{
HotelId = 1,
HotelName = "Hotel Happy",
Description = "A place where everyone can be happy.",
DescriptionEmbedding = new float[4] { 0.9f, 0.1f, 0.1f, 0.1f }
};
{
"id": 1,
"payload": { "HotelName": "Hotel Happy", "Description": "A place where everyone can be happy." },
"vector": [0.9, 0.1, 0.1, 0.1]
}
Hotel(
hotel_id = 1,
hotel_name = "Hotel Happy",
description = "A place where everyone can be happy.",
description_embedding = [0.9f, 0.1f, 0.1f, 0.1f],
)
from qdrant_client.models import PointStruct
PointStruct(
id=1,
payload={ "hotel_name": "Hotel Happy", "description": "A place where everyone can be happy." },
vector=[0.9, 0.1, 0.1, 0.1],
)
Vecteurs nommés
Si vous utilisez le mode vecteurs nommés, cela signifie que chaque point d’une collection peut contenir plusieurs vecteurs, et chacun sera nommé. Voici un exemple de représentation d’un objet dans Qdrant lors de l’utilisation du mode vecteurs nommés :
new Hotel
{
HotelId = 1,
HotelName = "Hotel Happy",
Description = "A place where everyone can be happy.",
HotelNameEmbedding = new float[4] { 0.9f, 0.5f, 0.5f, 0.5f }
DescriptionEmbedding = new float[4] { 0.9f, 0.1f, 0.1f, 0.1f }
};
{
"id": 1,
"payload": { "HotelName": "Hotel Happy", "Description": "A place where everyone can be happy." },
"vector": {
"HotelNameEmbedding": [0.9, 0.5, 0.5, 0.5],
"DescriptionEmbedding": [0.9, 0.1, 0.1, 0.1],
}
}
Hotel(
hotel_id = 1,
hotel_name = "Hotel Happy",
description = "A place where everyone can be happy.",
hotel_name_embedding = [0.9f, 0.5f, 0.5f, 0.5f],
description_embedding = [0.9f, 0.1f, 0.1f, 0.1f],
)
from qdrant_client.models import PointStruct
PointStruct(
id=1,
payload={ "hotel_name": "Hotel Happy", "description": "A place where everyone can be happy." },
vector={
"hotel_name_embedding": [0.9, 0.5, 0.5, 0.5],
"description_embedding": [0.9, 0.1, 0.1, 0.1],
},
)
Pour activer le mode vecteurs nommés, passez-le en tant qu’option lors de la construction d’un magasin de vecteurs ou d’une collection. Les mêmes options peuvent également être passées à l’une des méthodes d’extension de conteneur d’injection de dépendances fournies.
using Microsoft.SemanticKernel.Connectors.Qdrant;
using Qdrant.Client;
var vectorStore = new QdrantVectorStore(
new QdrantClient("localhost"),
new() { HasNamedVectors = true });
var collection = new QdrantVectorStoreRecordCollection<Hotel>(
new QdrantClient("localhost"),
"skhotels",
new() { HasNamedVectors = true });
Dans Python, la valeur par défaut est named_vectors
True, mais vous pouvez également la désactiver comme indiqué ci-dessous.
from semantic_kernel.connectors.memory.qdrant import QdrantCollection
collection = QdrantCollection(
collection_name="skhotels",
data_model_type=Hotel,
named_vectors=False,
)