Compartilhar via


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
  • ulong
  • Guid
Tipos de propriedade de dados com suporte
  • string
  • INT
  • longo
  • duplo
  • float
  • bool
  • e enumeráveis de cada um desses tipos
Tipos de propriedade de vetor com suporte Float ReadOnlyMemory<>
Tipos de índice com suporte Hnsw
Funções de distância suportadas
  • Semelhança de cosseno
  • DotProductSimilarity
  • Distância Euclidiana
  • ManhattanDistância
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_URLde 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,
)