Partilhar via


Gerando incorporações para conectores do Armazenamento Vetorial do Semantic Kernel

Aviso

A funcionalidade Semantic Kernel Vector Store está em fase de teste, e melhorias que exigem alterações de quebra ainda podem ocorrer em circunstâncias limitadas antes do lançamento.

Aviso

A funcionalidade Semantic Kernel Vector Store está em fase de teste, e melhorias que exigem alterações de quebra ainda podem ocorrer em circunstâncias limitadas antes do lançamento.

Os conectores do Semantic Kernel Vetor Store suportam várias maneiras de gerar incorporações. As incorporaçõ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 Vetor Store gere incorporações

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

Para habilitar a geração de vetores automaticamente durante o upsert, a propriedade vetor no seu modelo de dados é definida como o tipo de origem, por exemplo, string, 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 a partir da qual um vetor deve ser gerado. O tipo de vetor armazenado no banco de dados (por exemplo, float32, float16, etc.) será derivado do gerador de incorporação configurado.

Importante

Essas propriedades vetoriais não suportam a recuperação do vetor gerado ou do texto original a partir do qual o vetor foi gerado. Também não armazenam o texto original. Se o texto original precisar ser armazenado, uma propriedade Data separada deverá ser adicionada para armazená-lo.

Os geradores de incorporação que implementam as Microsoft.Extensions.AI abstrações são suportados e podem ser configurados em vários níveis:

  1. No Vetor Store: Você pode definir um gerador de incorporação padrão para todo o repositório de vetores. Este 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: pode configurar um gerador de inserção para uma coleção específica, sobrescrevendo o gerador ao nível da loja.

    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 VectorStoreCollectionDefinitiono , você pode especificar um gerador de incorporaçã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 vetorial: Ao definir propriedades programaticamente, você pode definir um gerador de incorporaçã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 Utilização

O exemplo a seguir demonstra como usar o gerador de embebimento para gerar vetores automaticamente durante tanto as operações de upsert quanto de pesquisa. Essa abordagem simplifica os fluxos de trabalho, eliminando a necessidade de pré-calcular incorporaçõ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 incorporações você mesmo

Construção de um gerador de incorporação

Consulte Embedding Generation para obter exemplos sobre como construir instâncias do Kernel Semântico ITextEmbeddingGenerationService .

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

Gerando incorporações no upsert com o 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 incorporações na pesquisa com o 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);
}

Gorjeta

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

Incorporação de dimensões

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. Diferentes modelos de incorporação normalmente suportam a geração de vetores com vários tamanhos de dimensão. Por exemplo, OpenAI text-embedding-ada-002 gera vetores com 1536 dimensões. Alguns modelos também permitem que um desenvolvedor escolha o número de dimensões que deseja 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.

Ao criar uma coleção usando as abstrações do Semantic Kernel Vetor Store, você precisará especificar o número de dimensões necessárias para cada propriedade vetorial por meio de anotações ou por meio da definição de registro. Aqui estão exemplos de ambos definindo o número de dimensões para 1536.

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

Gorjeta

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

Gorjeta

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

Brevemente

Mais informações em breve.

Brevemente

Mais informações em breve.