Usando o conector Qdrant (versão prévia)
Aviso
A funcionalidade do Repositório de Vetores do Kernel Semântico está em versão prévia e as melhorias que exigem alterações significativas ainda podem ocorrer em circunstâncias limitadas antes do lançamento.
Visão geral
O conector Qdrant Vector Store pode ser usado para acessar e gerenciar dados no Qdrant. O conector tem as seguintes características.
Área de recurso | Suporte |
---|---|
A coleção é mapeada para | Coleção Qdrant com índices de carga para campos de dados filtráveis |
Tipos de propriedade de chave com suporte |
|
Tipos de propriedade de dados com suporte |
|
Tipos de propriedade de vetor com suporte | Float ReadOnlyMemory<> |
Tipos de índice com suporte | Hnsw |
Funções de distância suportadas |
|
Suporta vários vetores em um registro | Sim (configurável) |
IsFilterable suportado? | Sim |
IsFullTextSearchable suportado? | Sim |
StoragePropertyName com suporte? | Sim |
Introdução
Adicione o pacote NuGet do conector do Repositório de Vetores Qdrant ao seu projeto.
dotnet add package Microsoft.SemanticKernel.Connectors.Qdrant --prerelease
Você pode adicionar o repositório de vetores ao contêiner de injeção de dependência disponível no KernelBuilder
ou ao IServiceCollection
contêiner de injeção de dependência usando métodos de extensão fornecidos pelo Semantic Kernel.
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");
Métodos de extensão que não usam parâmetros também são fornecidos. Isso exige que uma instância da Qdrant.Client.QdrantClient
classe seja registrada separadamente com o contêiner de injeção de dependência.
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();
Você pode construir uma instância do Qdrant Vector Store diretamente.
using Microsoft.SemanticKernel.Connectors.Qdrant;
using Qdrant.Client;
var vectorStore = new QdrantVectorStore(new QdrantClient("localhost"));
É possível construir uma referência direta a uma coleção nomeada.
using Microsoft.SemanticKernel.Connectors.Qdrant;
using Qdrant.Client;
var collection = new QdrantVectorStoreRecordCollection<Hotel>(
new QdrantClient("localhost"),
"skhotels");
Mapeamento de dados
O conector Qdrant fornece um mapeador padrão ao mapear dados do modelo de dados para o armazenamento. O Qdrant requer que as propriedades sejam mapeadas em agrupamentos de id, payload e vetor(es). O mapeador padrão usa as anotações do modelo ou a definição de registro para determinar o tipo de cada propriedade e fazer esse mapeamento.
- A propriedade do modelo de dados anotada como uma chave será mapeada para a ID do ponto Qdrant.
- As propriedades do modelo de dados anotadas como dados serão mapeadas para o objeto de carga útil do ponto Qdrant.
- As propriedades do modelo de dados anotadas como vetores serão mapeadas para o objeto vetorial de ponto Qdrant.
Substituição do nome da propriedade
Para propriedades de dados e propriedades de vetor (se estiver usando o modo de vetores nomeados), você pode fornecer nomes de campo de substituição a serem usados no armazenamento que sejam diferentes dos nomes de propriedade no modelo de dados. Isso não é suportado para chaves, já que uma chave tem um nome fixo no Qdrant. Também não há suporte para vetores no modo de vetor único sem nome, pois o vetor é armazenado com um nome fixo.
A substituição do nome da propriedade é feita definindo a StoragePropertyName
opção por meio dos atributos do modelo de dados ou da definição de registro.
Aqui está um exemplo de um modelo de dados com StoragePropertyName
conjunto em seus atributos e como isso será representado no 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],
}
}
Introdução
Instale o kernel semântico com os extras qdrant, que inclui o cliente qdrant.
pip install semantic-kernel[qdrant]
Em seguida, você pode criar uma instância de armazenamento de vetores usando a QdrantStore
classe, isso criará um AsyncQdrantClient usando as variáveis QDRANT_URL
de ambiente , QDRANT_API_KEY
, QDRANT_HOST
, QDRANT_PORT
, QDRANT_GRPC_PORT
, QDRANT_PATH
, e QDRANT_LOCATION
QDRANT_PREFER_GRPS
para se conectar à instância Qdrant, esses valores também podem ser fornecidos diretamente. Se nada for fornecido, ele volta para location=:memory:
.
from semantic_kernel.connectors.memory.qdrant import QdrantStore
vector_store = QdrantStore()
Você também pode criar o armazenamento de vetores com sua própria instância do cliente 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)
Você também pode criar uma coleção diretamente.
from semantic_kernel.connectors.memory.qdrant import QdrantCollection
collection = QdrantCollection(collection_name="skhotels", data_model_type=hotel)
Serialização
O conector Qdrant usa um modelo chamado PointStruct
para leitura e gravação no repositório. Isso pode ser importado do from qdrant_client.models import PointStruct
. Os métodos de serialização esperam uma saída de uma lista de objetos PointStruct e o método de desserialização recebe uma lista de objetos PointStruct.
Existem algumas considerações especiais para isso que têm a ver com vetores nomeados ou não nomeados, veja abaixo.
Para obter mais detalhes sobre esse conceito, consulte a documentação de serialização.
Modos vetoriais Qdrant
O Qdrant oferece suporte a dois modos de armazenamento vetorial e o Qdrant Connector com mapeador padrão oferece suporte a ambos os modos. O modo padrão é vetor único sem nome.
Vetor único sem nome
Com esta opção, uma coleção pode conter apenas um único vetor e não terá nome no modelo de armazenamento no Qdrant. Aqui está um exemplo de como um objeto é representado no Qdrant ao usar o modo de vetor único sem nome:
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],
)
Vetores nomeados
Se estiver usando o modo de vetores nomeados, isso significa que cada ponto em uma coleção pode conter mais de um vetor e cada um será nomeado. Aqui está um exemplo de como um objeto é representado no Qdrant ao usar o modo de vetores nomeados:
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],
},
)
Para habilitar o modo de vetores nomeados, passe isso como uma opção ao construir um Repositório de Vetores ou coleção. As mesmas opções também podem ser passadas para qualquer um dos métodos de extensão de contêiner de injeção de dependência fornecidos.
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 });
Em python, o valor padrão para named_vectors
é True, mas você também pode desabilitar isso conforme mostrado abaixo.
from semantic_kernel.connectors.memory.qdrant import QdrantCollection
collection = QdrantCollection(
collection_name="skhotels",
data_model_type=Hotel,
named_vectors=False,
)