Sdílet prostřednictvím


Změny ve vektorovém úložišti – Preview 2 – duben 2025

Integrovaná podpora pro generování vestavění v úložišti vektorů

Aktualizace z dubna 2025 zavádí vestavěnou podporu pro generování embeddingu přímo ve vektorovém úložišti. Konfigurací generátoru vkládání teď můžete automaticky generovat vkládání pro vlastnosti vektoru, aniž byste je museli předkomputovat externě. Tato funkce zjednodušuje pracovní postupy a snižuje potřebu dalších kroků předběžného zpracování.

Konfigurace generátoru vkládání

Generátory vkládání implementující Microsoft.Extensions.AI abstrakce jsou podporovány a lze je konfigurovat na různých úrovních:

  1. Ve vektorovém úložišti: Můžete nastavit výchozí generátor vkládání pro celé úložiště vektorů. Tento generátor se použije pro všechny kolekce a vlastnosti, pokud nebude přepsán.

    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"), new QdrantVectorStoreOptions
    {
         EmbeddingGenerator = embeddingGenerator
    });
    
  2. Na kolekci: Můžete nakonfigurovat generátor vkládání pro konkrétní kolekci, čímž přepíšete generátor na úrovni úložiště.

    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 QdrantVectorStoreRecordCollectionOptions<MyRecord>
    {
        EmbeddingGenerator = embeddingGenerator
    };
    var collection = new QdrantVectorStoreRecordCollection<ulong, MyRecord>(new QdrantClient("localhost"), "myCollection", collectionOptions);
    
  3. Definice záznamu: Při programovém definování vlastností pomocí VectorStoreRecordDefinition můžete specifikovat generátor vkládání pro všechny vlastnosti.

    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 recordDefinition = new VectorStoreRecordDefinition
    {
        EmbeddingGenerator = embeddingGenerator,
        Properties = new List<VectorStoreRecordProperty>
        {
            new VectorStoreRecordKeyProperty("Key", typeof(ulong)),
            new VectorStoreRecordVectorProperty("DescriptionEmbedding", typeof(string), dimensions: 1536)
        }
    };
    
    var collectionOptions = new QdrantVectorStoreRecordCollectionOptions<MyRecord>
    {
        VectorStoreRecordDefinition = recordDefinition
    };
    var collection = new QdrantVectorStoreRecordCollection<ulong, MyRecord>(new QdrantClient("localhost"), "myCollection", collectionOptions);
    
  4. Při definici vektorové vlastnosti: Při programovém definování vlastností můžete nastavit generátor vkládání přímo na vlastnost.

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

Příklad použití

Následující příklad ukazuje, jak pomocí generátoru vkládání automaticky generovat vektory během operací upsert i vyhledávání. Tento přístup zjednodušuje pracovní postupy tím, že eliminuje nutnost ručního dokončování vkládání.


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

    [VectorStoreRecordData]
    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.
    [VectorStoreRecordVector(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.CreateCollectionAsync();

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

Přechod z IVectorizableTextSearch a IVectorizedSearch do IVectorSearch

Rozhraní IVectorizableTextSearch a IVectorizedSearch byla označena jako zastaralá a nahrazena jednotnějším a flexibilnějším rozhraním IVectorSearch. Tato změna zjednodušuje povrch rozhraní API a poskytuje konzistentnější přístup k operacím vektorového vyhledávání.

Změny klíčů

  1. Sjednocené rozhraní:

    • Rozhraní IVectorSearch konsoliduje funkce obou IVectorizableTextSearch a IVectorizedSearch do jednoho rozhraní.
  2. Přejmenování metody:

    • VectorizableTextSearchAsync byla IVectorizableTextSearch nahrazena SearchAsync v IVectorSearch.
    • VectorizedSearchAsync byla IVectorizedSearch nahrazena SearchEmbeddingAsync v IVectorSearch.
  3. Vylepšená flexibilita:

    • Metoda SearchAsync v IVectorSearch zpracovává vytváření vkládání a podporuje buď místní vkládání, pokud je nakonfigurován generátor vkládání, nebo vkládání na straně serveru.
    • Metoda SearchEmbeddingAsync v IVectorSearch umožňuje přímé vyhledávání založené na vkládání a poskytuje nízkoúrovňové API pro pokročilé případy použití.

Změna návratového typu u vyhledávacích metod

Kromě změny v pojmenování pro vyhledávací metody se změnil návratový typ pro všechny metody hledání, aby se zjednodušilo použití. Typ výsledku vyhledávacích metod je nyní IAsyncEnumerable<VectorSearchResult<TRecord>>, který umožňuje procházet výsledky přímo. Dříve vrácený objekt obsahoval IAsyncEnumerable vlastnost.

Podpora vyhledávání bez vektorů / filtrovaného získávání

Aktualizace z dubna 2025 zavádí podporu hledání záznamů pomocí filtru a vrácení výsledků s konfigurovatelným pořadím řazení. To umožňuje vytvořit výčet záznamů v předvídatelném pořadí, což je zvlášť užitečné, když potřebujete synchronizovat úložiště vektorů s externím zdrojem dat.

Příklad: Použití filtrovaného GetAsync

Následující příklad ukazuje, jak použít metodu GetAsync s filtrem a možnostmi k načtení záznamů z kolekce vektorového úložiště. Tento přístup umožňuje použít kritéria filtrování a řadit výsledky podle předvídatelného pořadí.

// Define a filter to retrieve products priced above $600
Expression<Func<ProductInfo, bool>> filter = product => product.Price > 600;

// Define the options with a sort order
var options = new GetFilteredRecordOptions<ProductInfo>();
options.OrderBy.Descending(product => product.Price);

// Use GetAsync with the filter and sort order
var filteredProducts = await collection.GetAsync(filter, top: 10, options)
    .ToListAsync();

Tento příklad ukazuje, jak pomocí GetAsync metody načíst filtrované záznamy a seřadit je na základě konkrétních kritérií, jako je cena.

Nové metody v IVectorStore

Některé nové metody jsou k dispozici v IVectorStore rozhraní, které umožňují provádět více operací přímo bez nutnosti VectorStoreRecordCollection objektu.

Kontrola existence kolekce

Nyní můžete ověřit, zda kolekce existuje v vektorovém úložišti, aniž by bylo nutné vytvořit VectorStoreRecordCollection objekt.

// Example: Check if a collection exists
bool exists = await vectorStore.CollectionExistsAsync("myCollection", cancellationToken);
if (exists)
{
    Console.WriteLine("The collection exists.");
}
else
{
    Console.WriteLine("The collection does not exist.");
}

Odstranění kolekce

Nová metoda umožňuje odstranit kolekci z vektorového úložiště, aniž by bylo nutné vytvořit VectorStoreRecordCollection objekt.

// Example: Delete a collection
await vectorStore.DeleteCollectionAsync("myCollection", cancellationToken);
Console.WriteLine("The collection has been deleted.");

Nahrazení VectorStoreGenericDataModel<TKey> za Dictionary<string, object?>

Abstrakce vektorových dat podporují práci s databázemi, kde schéma kolekce není v době sestavení známo. Dříve to bylo podporováno prostřednictvím VectorStoreGenericDataModel<TKey> typu, kde lze tento model použít místo vlastního datového modelu.

V této verzi VectorStoreGenericDataModel<TKey> byla zastaralá a doporučeným postupem je místo toho použít Dictionary<string, object?> .

Stejně jako předtím je potřeba k určení schématu kolekce dodat definici záznamu. Všimněte si také, že požadovaný typ klíče při získání instance kolekce je object, zatímco ve schématu je pevně nastaven na string.

var recordDefinition = new VectorStoreRecordDefinition
{
    Properties = new List<VectorStoreRecordProperty>
    {
        new VectorStoreRecordKeyProperty("Key", typeof(string)),
        new VectorStoreRecordDataProperty("Text", typeof(string)),
        new VectorStoreRecordVectorProperty("Embedding", typeof(ReadOnlyMemory<float>), 1536)
    }
};
var collection = vectorStore.GetCollection<object, Dictionary<string, object?>>("finances", recordDefinition);
var record = new Dictionary<string, object?>
{
    { "Key", "1" },
    { "Text", "The budget for 2024 is EUR 364 000" },
    { "Embedding", vector }
};
await collection.UpsertAsync(record);
var retrievedRecord = await collection.GetAsync("1");
Console.WriteLine(retrievedRecord["Text"]);

Změna konvence vytváření názvů metod batch

Rozhraní IVectorStoreRecordCollection bylo aktualizováno, aby zlepšilo konzistenci v konvencích vytváření názvů metod. Konkrétně byly metody s názvem Batch přejmenovány tak, aby se odebral výraz 'Batch' z jejich názvů. Tato změna odpovídá stručnější konvenci vytváření názvů.

Přejmenování příkladů

  • Stará metoda:GetBatchAsync(IEnumerable<TKey> keys, ...)
    Nová metoda:GetAsync(IEnumerable<TKey> keys, ...)

  • Stará metoda:DeleteBatchAsync(IEnumerable<TKey> keys, ...)
    Nová metoda:DeleteAsync(IEnumerable<TKey> keys, ...)

  • Stará metoda:UpsertBatchAsync(IEnumerable<TRecord> records, ...)
    Nová metoda:UpsertAsync(IEnumerable<TRecord> records, ...)

Změna návratového typu pro dávkovou metodu Upsert

Návratový typ metody dávkového upsertu byl změněn z IAsyncEnumerable<TKey> na Task<IReadOnlyList<TKey>>. Tato změna má vliv na způsob využívání metody. Teď můžete jednoduše očekávat výsledek a získat zpět seznam klíčů. Dříve, aby bylo zajištěno, že byly dokončeny všechny upserty, musel být IAsyncEnumerable zcela výčet. To zjednodušuje vývojářské prostředí při použití metody dávkového upsertu.

Vlastnost CollectionName byla změněna na Název.

Vlastnost CollectionName rozhraní IVectorStoreRecordCollection byla přejmenována na Name.

IsFilterable a IsFullTextSearchable byly přejmenovány na IsIndexed a IsFullTextIndexed

Vlastnosti IsFilterable a IsFullTextSearchable na třídách VectorStoreRecordDataAttribute a VectorStoreRecordDataProperty byly přejmenovány na IsIndexed a IsFullTextIndexed v uvedeném pořadí.

Dimenze se teď vyžadují pro atributy a definice vektorů.

V aktualizaci z dubna 2025 se určení počtu dimenzí stalo povinným při použití vektorových atributů nebo definic vektorových vlastností. Tím zajistíte, že úložiště vektorů bude mít vždy potřebné informace pro správné zpracování vkládání.

Změny v VectorStoreRecordVectorAttribute

Dříve VectorStoreRecordVectorAttribute umožňoval vynechat parametr Dimensions. Tato možnost už není povolená a Dimensions parametr se teď musí explicitně zadat.

Před:

[VectorStoreRecordVector]
public ReadOnlyMemory<float> DefinitionEmbedding { get; set; }

Po:

[VectorStoreRecordVector(Dimensions: 1536)]
public ReadOnlyMemory<float> DefinitionEmbedding { get; set; }

Změny v VectorStoreRecordVectorProperty

Podobně při programovém definování vektorové vlastnosti pomocí VectorStoreRecordVectorPropertyparametru dimensions je nyní povinný.

Před:

var vectorProperty = new VectorStoreRecordVectorProperty("DefinitionEmbedding", typeof(ReadOnlyMemory<float>));

Po:

var vectorProperty = new VectorStoreRecordVectorProperty("DefinitionEmbedding", typeof(ReadOnlyMemory<float>), dimensions: 1536);

Všechny kolekce vyžadují předání typu klíče jako parametr obecného typu.

Při přímé vytváření kolekce je teď nutné zadat TKey parametr obecného typu. Dříve, kdy některé databáze umožňovaly pouze jeden typ klíče, byl to teď povinný parametr, ale pokud chcete povolit použití kolekcí s typem Dictionary<string, object?> a typem object klíče, TKey musí být vždy k dispozici.

Nevztahuje se

Tyto změny se v současné době vztahují pouze v jazyce C.#

Nevztahuje se

Tyto změny se v současné době vztahují pouze v jazyce C.#