Partager via


Génération d'embeddings pour les connecteurs de stockage de vecteurs de noyau sémantique

Avertissement

La fonctionnalité de magasin de vecteurs du noyau sémantique est en préversion et des améliorations nécessitant des modifications majeures peuvent encore se produire dans des circonstances limitées avant la sortie.

Avertissement

La fonctionnalité de magasin de vecteurs du noyau sémantique est en préversion et des améliorations nécessitant des modifications majeures peuvent encore se produire dans des circonstances limitées avant la sortie.

Les connecteurs de stockage de vecteurs du noyau sémantique prennent en charge plusieurs méthodes de génération de vecteurs d'incorporation. Les incorporations peuvent être générées par le développeur et transmises dans le cadre d’un enregistrement lors de l’utilisation d’un VectorStoreCollection ou peuvent être générées en interne dans le VectorStoreCollection.

Laisser le magasin de vecteurs générer des incorporations

Vous pouvez configurer un générateur d’incorporation sur votre magasin de vecteurs, ce qui permet aux incorporations d’être générées automatiquement pendant les opérations upsert et de recherche, ce qui élimine la nécessité d’un prétraitement manuel.

Pour activer la génération automatique de vecteurs sur upsert, la propriété vector sur votre modèle de données est définie comme type source, par exemple chaîne, mais toujours décorée avec un VectorStoreVectorPropertyAttribute.

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

Avant upsert, la Embedding propriété doit contenir la chaîne à partir de laquelle un vecteur doit être généré. Le type du vecteur stocké dans la base de données (par exemple float32, float16, etc.) est dérivé du générateur d’incorporation configuré.

Important

Ces propriétés vectorielles ne prennent pas en charge la récupération du vecteur généré ou du texte d’origine à partir duquel le vecteur a été généré. Ils ne stockent pas non plus le texte d’origine. Si le texte d’origine doit être stocké, une propriété de données distincte doit être ajoutée pour la stocker.

Les générateurs d’incorporation implémentant les Microsoft.Extensions.AI abstractions sont pris en charge et peuvent être configurés à différents niveaux :

  1. Dans le magasin de vecteurs : vous pouvez définir un générateur d’incorporation par défaut pour l’intégralité du magasin vectoriel. Ce générateur sera utilisé pour toutes les collections et propriétés, sauf en cas de substitution.

    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. Dans une collection : vous pouvez configurer un générateur d'intégration pour une collection spécifique, en remplaçant le générateur au niveau du magasin.

    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. Sur une définition d’enregistrement : lors de la définition des propriétés par programmation VectorStoreCollectionDefinition, vous pouvez spécifier un générateur d’incorporation pour toutes les propriétés.

    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. Sur une définition de propriété vectorielle : lorsque vous définissez des propriétés par programmation, vous pouvez définir un générateur d’incorporation directement sur la propriété.

    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
    };
    

Exemple d’utilisation

L’exemple suivant montre comment utiliser le générateur d’incorporation pour générer automatiquement des vecteurs pendant les opérations upsert et de recherche. Cette approche simplifie les flux de travail en éliminant la nécessité de précomputer manuellement les incorporations.


// 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}");
}

Génération de vos propres embeddings

Construction d’un générateur d’incorporation

Consultez La génération d’incorporation pour obtenir des exemples sur la construction d’instances de noyau ITextEmbeddingGenerationService sémantique.

Pour plus d’informations sur la construction de services de génération Microsoft.Extensions.AI.

Génération d’incorporations sur upsert avec le noyau sémantique 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" }
    });
}

Génération d’incorporations sur la recherche avec le noyau sémantique 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);
}

Conseil

Pour plus d’informations sur la génération d’incorporations, reportez-vous à génération d’incorporation dans le noyau sémantique.

Incorporation des dimensions

Les bases de données vectorielles nécessitent généralement que vous spécifiiez le nombre de dimensions dont chaque vecteur a lors de la création de la collection. Différents modèles d’incorporation prennent généralement en charge la génération de vecteurs avec différentes tailles de dimension. Par exemple, OpenAI text-embedding-ada-002 génère des vecteurs avec 1536 dimensions. Certains modèles permettent également à un développeur de choisir le nombre de dimensions souhaitées dans le vecteur de sortie. Par exemple, Google text-embedding-004 produit des vecteurs avec 768 dimensions par défaut, mais permet à un développeur de choisir un nombre quelconque de dimensions comprises entre 1 et 768.

Il est important de s’assurer que les vecteurs générés par le modèle d’incorporation ont le même nombre de dimensions que le vecteur correspondant dans la base de données.

Si vous créez une collection à l’aide des abstractions du magasin de vecteurs du Semantic Kernel, vous devez spécifier le nombre de dimensions requises pour chaque propriété vectorielle via des annotations ou via la définition de l’enregistrement. Voici des exemples de la définition du nombre de dimensions à 1536.

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

Conseil

Pour plus d’informations sur la façon d’annoter votre modèle de données, reportez-vous à la définition de votre modèle de données.

Conseil

Pour plus d’informations sur la création d’une définition d’enregistrement, reportez-vous à la définition de votre schéma avec une définition d’enregistrement.

Bientôt disponible

Plus d’informations prochainement.

Bientôt disponible

Plus d’informations prochainement.