Compartilhar via


Gerando inserções para conectores do Repositório de Vetores do Kernel Semântico

Aviso

A funcionalidade do Repositório de Vetores do Kernel Semântico está em versão prévia, e algumas melhorias que exigem mudanças disruptivas ainda podem ocorrer em circunstâncias limitadas antes do lançamento.

Aviso

A funcionalidade do Repositório de Vetores do Kernel Semântico está em versão prévia, e algumas melhorias que exigem mudanças disruptivas ainda podem ocorrer em circunstâncias limitadas antes do lançamento.

Conectores semânticos do Kernel Vector Store dão suporte a várias maneiras de gerar inserções. As inserções podem ser geradas pelo desenvolvedor e passadas como parte de um registro ao usar um VectorStoreCollection ou podem ser geradas internamente para o VectorStoreCollection.

Permitindo que o Repositório vetor gere inserções

Você pode configurar um gerador de inserção em seu repositório de vetores, permitindo que as inserções sejam geradas automaticamente durante operações upsert e search, eliminando a necessidade de pré-processamento manual.

Para habilitar a geração de vetores automaticamente no upsert, a propriedade de vetor em seu modelo de dados é definida como o tipo de origem, por exemplo, cadeia de caracteres, mas ainda decorada com um VectorStoreVectorPropertyAttribute.

    [VectorStoreVector(1536)]
    public string Embedding { get; set; }

Antes de upsert, a Embedding propriedade deve conter a cadeia de caracteres da qual um vetor deve ser gerado. O tipo do vetor armazenado no banco de dados (por exemplo, float32, float16 etc.) será derivado do gerador de inserção configurado.

Importante

Essas propriedades de vetor não dão suporte à recuperação do vetor gerado ou do texto original do qual o vetor foi gerado. Eles também não armazenam o texto original. Se o texto original precisar ser armazenado, uma propriedade de dados separada deverá ser adicionada para armazená-la.

Os geradores de inserção que implementam as Microsoft.Extensions.AI abstrações têm suporte e podem ser configurados em vários níveis:

  1. No Repositório de Vetores: você pode definir um gerador de inserção padrão para todo o repositório de vetores. Esse gerador será usado para todas as coleções e propriedades, a menos que seja substituído.

    using Microsoft.Extensions.AI;
    using Microsoft.SemanticKernel.Connectors.Qdrant;
    using OpenAI;
    using Qdrant.Client;
    
    var embeddingGenerator = new OpenAIClient("your key")
        .GetEmbeddingClient("your chosen model")
        .AsIEmbeddingGenerator();
    
    var vectorStore = new QdrantVectorStore(
        new QdrantClient("localhost"),
        ownsClient: true,
        new QdrantVectorStoreOptions
        {
             EmbeddingGenerator = embeddingGenerator
        });
    
  2. Em uma coleção: você pode configurar um gerador de inserção para uma coleção específica, substituindo o gerador no nível do repositório.

    using Microsoft.Extensions.AI;
    using Microsoft.SemanticKernel.Connectors.Qdrant;
    using OpenAI;
    using Qdrant.Client;
    
    var embeddingGenerator = new OpenAIClient("your key")
        .GetEmbeddingClient("your chosen model")
        .AsIEmbeddingGenerator();
    
    var collectionOptions = new QdrantCollectionOptions
    {
        EmbeddingGenerator = embeddingGenerator
    };
    var collection = new QdrantCollection<ulong, MyRecord>(
        new QdrantClient("localhost"),
        "myCollection",
        ownsClient: true,
        collectionOptions);
    
  3. Em uma definição de registro: ao definir propriedades programaticamente usando VectorStoreCollectionDefinition, você pode especificar um gerador de inserção para todas as propriedades.

    using Microsoft.Extensions.AI;
    using Microsoft.Extensions.VectorData;
    using Microsoft.SemanticKernel.Connectors.Qdrant;
    using OpenAI;
    using Qdrant.Client;
    
    var embeddingGenerator = new OpenAIClient("your key")
        .GetEmbeddingClient("your chosen model")
        .AsIEmbeddingGenerator();
    
    var definition = new VectorStoreCollectionDefinition
    {
        EmbeddingGenerator = embeddingGenerator,
        Properties = new List<VectorStoreProperty>
        {
            new VectorStoreKeyProperty("Key", typeof(ulong)),
            new VectorStoreVectorProperty("DescriptionEmbedding", typeof(string), dimensions: 1536)
        }
    };
    
    var collectionOptions = new QdrantCollectionOptions
    {
        Definition = definition
    };
    var collection = new QdrantCollection<ulong, MyRecord>(
        new QdrantClient("localhost"),
        "myCollection",
        ownsClient: true,
        collectionOptions);
    
  4. Em uma definição de propriedade vetor: ao definir propriedades programaticamente, você pode definir um gerador de inserção diretamente na propriedade.

    using Microsoft.Extensions.AI;
    using Microsoft.Extensions.VectorData;
    using OpenAI;
    
    var embeddingGenerator = new OpenAIClient("your key")
        .GetEmbeddingClient("your chosen model")
        .AsIEmbeddingGenerator();
    
    var vectorProperty = new VectorStoreVectorProperty("DescriptionEmbedding", typeof(string), dimensions: 1536)
    {
         EmbeddingGenerator = embeddingGenerator
    };
    

Exemplo de Uso

O exemplo a seguir demonstra como usar o gerador de embeddings para gerar automaticamente vetores durante operações de inserção/atualização e busca. Essa abordagem simplifica os fluxos de trabalho eliminando a necessidade de pré-compilar inserções manualmente.


// The data model
internal class FinanceInfo
{
    [VectorStoreKey]
    public string Key { get; set; } = string.Empty;

    [VectorStoreData]
    public string Text { get; set; } = string.Empty;

    // Note that the vector property is typed as a string, and
    // its value is derived from the Text property. The string
    // value will however be converted to a vector on upsert and
    // stored in the database as a vector.
    [VectorStoreVector(1536)]
    public string Embedding => this.Text;
}

// Create an OpenAI embedding generator.
var embeddingGenerator = new OpenAIClient("your key")
    .GetEmbeddingClient("your chosen model")
    .AsIEmbeddingGenerator();

// Use the embedding generator with the vector store.
var vectorStore = new InMemoryVectorStore(new() { EmbeddingGenerator = embeddingGenerator });
var collection = vectorStore.GetCollection<string, FinanceInfo>("finances");
await collection.EnsureCollectionExistsAsync();

// Create some test data.
string[] budgetInfo =
{
    "The budget for 2020 is EUR 100 000",
    "The budget for 2021 is EUR 120 000",
    "The budget for 2022 is EUR 150 000",
    "The budget for 2023 is EUR 200 000",
    "The budget for 2024 is EUR 364 000"
};

// Embeddings are generated automatically on upsert.
var records = budgetInfo.Select((input, index) => new FinanceInfo { Key = index.ToString(), Text = input });
await collection.UpsertAsync(records);

// Embeddings for the search is automatically generated on search.
var searchResult = collection.SearchAsync(
    "What is my budget for 2024?",
    top: 1);

// Output the matching result.
await foreach (var result in searchResult)
{
    Console.WriteLine($"Key: {result.Record.Key}, Text: {result.Record.Text}");
}

Gerando embeddings por conta própria

Construindo um gerador de incorporação

Consulte a Geração de Incorporamento para obter exemplos sobre como construir instâncias do ITextEmbeddingGenerationService Kernel Semântico.

Consulte Microsoft.Extensions.AI.Abstractions para obter informações sobre como construir serviços de geração de incorporações Microsoft.Extensions.AI.

Gerando inserções em upsert com Kernel Semântico ITextEmbeddingGenerationService

public async Task GenerateEmbeddingsAndUpsertAsync(
    ITextEmbeddingGenerationService textEmbeddingGenerationService,
    VectorStoreCollection<ulong, Hotel> collection)
{
    // Upsert a record.
    string descriptionText = "A place where everyone can be happy.";
    ulong hotelId = 1;

    // Generate the embedding.
    ReadOnlyMemory<float> embedding =
        await textEmbeddingGenerationService.GenerateEmbeddingAsync(descriptionText);

    // Create a record and upsert with the already generated embedding.
    await collection.UpsertAsync(new Hotel
    {
        HotelId = hotelId,
        HotelName = "Hotel Happy",
        Description = descriptionText,
        DescriptionEmbedding = embedding,
        Tags = new[] { "luxury", "pool" }
    });
}

Gerando inserções na pesquisa com Kernel Semântico ITextEmbeddingGenerationService

public async Task GenerateEmbeddingsAndSearchAsync(
    ITextEmbeddingGenerationService textEmbeddingGenerationService,
    VectorStoreCollection<ulong, Hotel> collection)
{
    // Upsert a record.
    string descriptionText = "Find me a hotel with happiness in mind.";

    // Generate the embedding.
    ReadOnlyMemory<float> searchEmbedding =
        await textEmbeddingGenerationService.GenerateEmbeddingAsync(descriptionText);

    // Search using the already generated embedding.
    IAsyncEnumerable<VectorSearchResult<Hotel>> searchResult = collection.SearchAsync(searchEmbedding, top: 1);
    List<VectorSearchResult<Hotel>> resultItems = await searchResult.ToListAsync();

    // Print the first search result.
    Console.WriteLine("Score for first result: " + resultItems.FirstOrDefault()?.Score);
    Console.WriteLine("Hotel description for first result: " + resultItems.FirstOrDefault()?.Record.Description);
}

Dica

Para obter mais informações sobre como gerar inserções, consulte Geração de inserção no kernel semântico.

Dimensões de incorporação

Os bancos de dados vetoriais normalmente exigem que você especifique o número de dimensões que cada vetor tem ao criar a coleção. Modelos de inserção diferentes normalmente dão suporte à geração de vetores com vários tamanhos de dimensão. Por exemplo, o OpenAI text-embedding-ada-002 gera vetores com dimensões 1536. Alguns modelos também permitem que um desenvolvedor escolha o número de dimensões desejadas no vetor de saída. Por exemplo, o Google text-embedding-004 produz vetores com 768 dimensões por padrão, mas permite que um desenvolvedor escolha qualquer número de dimensões entre 1 e 768.

É importante garantir que os vetores gerados pelo modelo de incorporação tenham o mesmo número de dimensões que o vetor correspondente no banco de dados.

Se estiver criando uma coleção usando as abstrações do Repositório de Vetores do Kernel Semântico, você precisará especificar o número de dimensões necessárias para cada propriedade de vetor por meio de anotações ou por meio da definição de registro. Aqui estão exemplos de como definir o número de dimensões como 1536.

[VectorStoreVector(Dimensions: 1536)]
public ReadOnlyMemory<float>? DescriptionEmbedding { get; set; }
new VectorStoreVectorProperty("DescriptionEmbedding", typeof(float), dimensions: 1536);

Dica

Para obter mais informações sobre como anotar seu modelo de dados, consulte definindo seu modelo de dados.

Dica

Para obter mais informações sobre como criar uma definição de registro, consulte a seção sobre a definição do seu esquema com uma definição de registro.

Em breve

Mais informações em breve.

Em breve

Mais informações em breve.