Vektorové vyhledávání pomocí zprostředkovatelů úložiště vektorů

Knihovna Microsoft.Extensions.VectorData poskytuje funkce vektorového vyhledávání v rámci abstrakcí vektorového úložiště. Mezi tyto možnosti patří filtrování a mnoho dalších možností.

Metoda SearchAsync provádí vyhledávání podobnosti a vrací záznamy, jejichž vektorová vlastnost je nejvíce podobná dané hodnotě. Za předpokladu, že máte kolekci, která už obsahuje data, tady je minimální ukázka ukazující vektorové vyhledávání pomocí Qdrantu:

// Create a Qdrant VectorStore object and get a VectorStoreCollection for a collection that already contains records
VectorStore vectorStore = new QdrantVectorStore(new QdrantClient("localhost"), ownsClient: true);
VectorStoreCollection<ulong, Hotel> collection = vectorStore.GetCollection<ulong, Hotel>("skhotels");

// Get the 3 hotels whose vector property is most similar to the query text
IAsyncEnumerable<VectorSearchResult<Hotel>> results = collection.SearchAsync("Big rooms with a view", top: 3);

// Inspect the returned hotels and their similarity scores
await foreach (VectorSearchResult<Hotel> record in results)
{
    Console.WriteLine("Found hotel description: " + record.Record.Description);
    Console.WriteLine("Found record score: " + record.Score);
}

Další informace o generování vkládání naleznete v tématu Vektorové vlastnosti a generování vkládání.

Počet výsledků a vynechání výsledků

SearchAsync má povinný top parametr, který řídí maximální počet záznamů vrácených z hledání. Vždy zvažte, kolik nejlepších záznamů skutečně potřebujete, protože přílišné načítání může snížit výkon aplikace:

IAsyncEnumerable<VectorSearchResult<Hotel>> searchResult = collection.SearchAsync("Big rooms with a view", top: 3);

Kromě toho můžete volitelně přeskočit záznamy. Například následující hledání vrátí 20 nejrelevavantnějších produktů po vynechání 40:

IAsyncEnumerable<VectorSearchResult<Product>> results = collection.SearchAsync(
    "Green socks",
    top: 20,
    new() { Skip = 40 });

top a Skip lze použít k provádění stránkování pro načtení velkého počtu výsledků pomocí samostatných volání. Tato technika ale nemusí s databází dobře fungovat, protože stále musí najít a zpracovat přeskočené záznamy. Další informace najdete v dokumentaci k databázi.

Filtrování metadat

VectorSearchOptions<TRecord>.Filter Před použitím vektorového vyhledávání použijte možnost filtrování záznamů ve vybrané kolekci. To má několik výhod:

  • Snižuje latenci a náklady na zpracování, protože je potřeba porovnat s vektorem hledání pouze záznamy, které zůstávají po filtrování, a proto je potřeba provést menší počet porovnání vektorů.
  • Omezuje sadu výsledků. Můžete například implementovat řízení přístupu tak, že vyloučíte data, ke kterým by uživatel neměl mít přístup, nebo můžete hledat jenom v konkrétní kategorii produktů.

Aby bylo možné pole použít k filtrování, mnoho úložišť vektorů vyžaduje, aby se tato pole indexovala jako první. Další informace o tom, jak povolit indexování vlastností dat, naleznete v tématu Data vlastnost.

Filtry se vyjadřují pomocí výrazů LINQ na základě typu datového modelu. Sada podporovaných výrazů LINQ se liší v závislosti na funkcích podporovaných jednotlivými databázemi, ale všechny databáze podporují širokou základnu běžných výrazů, například rovná se, nerovná se, anda or.

class Glossary
{
    // ...

    // Category is marked as indexed, since you want to filter using this property.
    [VectorStoreData(IsIndexed = true)]
    public required string Category { get; set; }

    // Tags is marked as indexed, since you want to filter using this property.
    [VectorStoreData(IsIndexed = true)]
    public required List<string> Tags { get; set; }
}

IAsyncEnumerable<VectorSearchResult<Glossary>> results = collection.SearchAsync(
    "Some term",
    top: 3,
    new()
    {
        Filter = r => r.Category == "External Definitions" && r.Tags.Contains("memory")
    });

Zahrnutí vektorů do výsledků

Ve výchozím nastavení nejsou ve výsledcích hledání zahrnuty vlastnosti vektoru, což snižuje přenos dat. Vyhledávání můžete nakonfigurovat tak, aby zahrnovalo:

IAsyncEnumerable<VectorSearchResult<Product>> results = collection.SearchAsync(
    "Green socks",
    top: 3,
    new() { IncludeVectors = true });

Určení vektorové vlastnosti

Ve většině scénářů je v datovém modelu definována pouze jedna vektorová vlastnost a SearchAsync ji automaticky prohledává. Pokud je však definováno více vektorových vlastností, musíte určit, který z nich se má použít:

class Product
{
    // ...

    // Multiple vector properties:
    [VectorStoreVector(1536)]
    public ReadOnlyMemory<float> DescriptionEmbedding { get; set; }

    [VectorStoreVector(1536)]
    public ReadOnlyMemory<float> FeatureListEmbedding { get; set; }
}

IAsyncEnumerable<VectorSearchResult<Hotel>> results = collection.SearchAsync(
    "I'm looking for a product with a specific feature.",
    top: 3,
    new() { VectorProperty = r => r.FeatureListEmbedding });

Hybridní vyhledávání kombinuje hledání vektorové podobnosti s tradičním vyhledáváním klíčových slov, které spouští paralelně i vrací kombinaci obou sad výsledků. To může zlepšit kvalitu vyhledávání, protože párování klíčových slov může zachytit přesné shody termínů, které by vektorová podobnost mohla přehlédnout, a naopak.

Poznámka:

Hybridní vyhledávání je dostupné jenom u databází, které ho podporují. Rozhraní IKeywordHybridSearchable<TRecord> implementují poskytovatelé jenom těchto databází.

Aby bylo možné použít hybridní vyhledávání, musí mít datový model řetězcové pole s povoleným fulltextovým vyhledáváním prostřednictvím IsFullTextIndexed:

class Hotel
{
    [VectorStoreKey]
    public ulong Key { get; set; }

    [VectorStoreData(IsFullTextIndexed = true)]
    public required string Description { get; set; }

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

Pak zavolejte HybridSearchAsynca předejte hledaný text i klíčová slova:

var hybridCollection = (IKeywordHybridSearchable<Hotel>)collection;

IAsyncEnumerable<VectorSearchResult<Hotel>> results = hybridCollection.HybridSearchAsync(
    "I'm looking for a hotel where customer happiness is the priority.",
    ["happiness", "hotel", "customer"],
    top: 3);

Všechny možnosti popsané pro vektorové vyhledávání (top, Skip, Filter, IncludeVectors, VectorProperty) jsou také k dispozici pro hybridní vyhledávání prostřednictvím HybridSearchOptions<TRecord>.

Hybridní vyhledávání navíc podporuje AdditionalProperty možnost určení, na kterou vlastnost fulltextového vyhledávání se má zacílit. Pokud má váš datový model pouze jednu vlastnost s IsFullTextIndexed = true, použije se automaticky; pokud jich je více, musíte určit, kterou.

IAsyncEnumerable<VectorSearchResult<Hotel>> results = hybridCollection.HybridSearchAsync(
    "I'm looking for a hotel where customer happiness is the priority.",
    ["happiness", "hotel", "customer"],
    top: 3,
    new()
    {
        VectorProperty = r => r.DescriptionEmbedding,
        AdditionalProperty = r => r.Description
    });