作者:Luis Quintanilla - 项目经理

我们很高兴推出 Microsoft.Extensions.VectorData.Abstractions 库,该库现已提供预览版。

正如 Microsoft.Extensions.AI 库(https://devblogs.microsoft.com/dotnet/introducing-microsoft-extensions-ai-preview/)为使用 AI 服务提供了一个统一层一样,此包为 .NET 生态系统提供了抽象,有助于将矢量存储集成到 .NET 应用程序和库中。


为什么选择矢量存储?


矢量数据库对于搜索和生成 AI 响应等任务非常重要。

与关系数据库和文档数据库针对结构化和半结构化数据进行优化的方式类似,矢量数据库的构建旨在高效存储、索引和管理以嵌入矢量表示的数据。因此,矢量数据库使用的索引算法经过优化,可高效检索在应用程序下游使用的数据。


什么是 Microsoft.Extensions.VectorData?


Microsoft.Extensions.VectorData 是一组由 Semantic Kernel 和更广泛的 .NET 生态系统一起合作开发的核心 .NET 库。这些库提供了一个统一的 C# 抽象层,用于与矢量存储交互。

Microsoft.Extensions.VectorData 中的抽象为库作者和开发人员提供了以下功能:

  • 能够对矢量存储执行创建-读取-更新-删除 (CRUD) 操作
  • 能够在矢量存储上使用矢量和文本搜索。


如何开始?


开始使用 Microsoft.Extensions.VectorData 抽象的最简单方法是使用任何一种语义内核矢量存储连接器(https://learn.microsoft.com/en-us/semantic-kernel/concepts/vector-store-connectors/out-of-the-box-connectors/)

在此示例中,我将使用内存矢量存储的实现。

为了完善此示例并使其更具真实感,我们还将使用 Microsoft.Extensions.AI 中的 Ollama 参考实现。不过,任何其他支持嵌入生成的实现也同样有效。

创建应用程序并添加 NuGet 包

1. 创建 一个 C# 控制台应用程序。

2. 安装以下 NuGet 包

  1. 将以下 using 语句添加到您的应用程序。
using System.Collections.ObjectModel;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.InMemory;

存储数据

此示例使用的场景是对电影集合执行语义搜索。


存储数据

首先定义一个类来表示您的电影数据。

public class Movie
{
    [VectorStoreRecordKey]
    public int Key {get;set;}


    [VectorStoreRecordData] 
    public string Title {get;set;}


    [VectorStoreRecordData]
    public string Description {get;set;}


    [VectorStoreRecordVector(384, DistanceFunction.CosineSimilarity)]
    public ReadOnlyMemory<float> Vector {get;set;}
}

通过使用 VectoStoreRecordKey、VectorStoreRecordVector 和 VectorStoreRecordData 等属性,您可以对数据模型进行注释,以便矢量存储实现更轻松地将 POCO 对象映射到其底层数据模型。有关每个属性所支持选项的更多信息,请参阅语义内核矢量存储数据模型学习页面(https://learn.microsoft.com/en-us/semantic-kernel/concepts/vector-store-connectors/defining-your-data-model?pivots=programming-language-csharp#attributes)

创建矢量存储和电影集合

现在您已经定义了数据模型,请创建一个带有集合的矢量存储来存储电影数据。

var movieData = new List<Movie>()
{
    new Movie
        {
            Key=0, 
            Title="Lion King", 
            Description="The Lion King is a classic Disney animated film that tells the story of a young lion named Simba who embarks on a journey to reclaim his throne as the king of the Pride Lands after the tragic death of his father."
        },
    new Movie
        {
            Key=1,
            Title="Inception", 
            Description="Inception is a science fiction film directed by Christopher Nolan that follows a group of thieves who enter the dreams of their targets to steal information."
        },
    new Movie
        {
            Key=2,
            Title="The Matrix", 
            Description="The Matrix is a science fiction film directed by the Wachowskis that follows a computer hacker named Neo who discovers that the world he lives in is a simulated reality created by machines."
        },
    new Movie
        {
            Key=3,
            Title="Shrek", 
            Description="Shrek is an animated film that tells the story of an ogre named Shrek who embarks on a quest to rescue Princess Fiona from a dragon and bring her back to the kingdom of Duloc."
        }
};


var vectorStore = new InMemoryVectorStore();


var movies = vectorStore.GetCollection<int, Movie>("movies");


await movies.CreateCollectionIfNotExistsAsync();

创建嵌入生成器

若要生成嵌入,请使用 Ollama 提供的托管模型之一。在此示例中,使用的模型是 all-minilm,但任何模型都可以使用。

  1. 安装 Ollama
    https://ollama.com/download
  2. 下载 all-minilm 模型
    https://ollama.com/library/all-minilm
  3. 在您的应用程序中配置 OllamaEmbeddingGenerator:
IEmbeddingGenerator<string,Embedding<float>> generator =
     new OllamaEmbeddingGenerator(new Uri("http://localhost:11434/"), "all-minilm");

生成嵌入

现在您有了一个嵌入生成器,请使用它为您的电影数据生成嵌入并将它们存储在矢量存储中。

foreach(var movie in movieData)
{
    movie.Vector = await generator.GenerateEmbeddingVectorAsync(movie.Description);
    await movies.UpsertAsync(movie);
}

查询数据

现在您的数据存储中已经有了数据,您可以查询它了。


生成查询嵌入

为查询“一部适合家庭观看的电影”生成一个嵌入。

var query = "A family friendly movie";
var queryEmbedding = await generator.GenerateEmbeddingVectorAsync(query);

查询数据存储

现在您已经有了查询的嵌入内容,您可以使用它在数据存储中搜索相关结果。

var searchOptions = new VectorSearchOptions()
{
    Top = 1,
    VectorPropertyName = "Vector"
};


var results = await movies.VectorizedSearchAsync(queryEmbedding, searchOptions);


await foreach(var result in results.Results)
{
    Console.WriteLine($"Title: {result.Record.Title}");
    Console.WriteLine($"Description: {result.Record.Description}");
    Console.WriteLine($"Score: {result.Score}");
    Console.WriteLine();
}

结果应如下所示:

技术速递|Microsoft.Extensions.VectorData 预览版简介_microsoft

继续学习

有关使用抽象的详细文档,请参阅语义内核矢量存储学习网站(https://learn.microsoft.com/en-us/semantic-kernel/concepts/vector-store-connectors/)

从以下示例中了解更多信息:

Microsoft.Extensions.VectorData 的下一步计划是什么?

与 Microsoft.Extensions.AI 类似,我们计划:

  • 继续与 Semantic Kernel 合作,在抽象和 Microsoft.Extensions.VectorData 的基础上进行构建,从而在 RAG 场景中带来更简化的体验。查看 Semantic Kernel 博客(https://devblogs.microsoft.com/semantic-kernel/microsoft-extensions-vectordata-abstractions-now-available/)以了解更多信息。
  • 与生态系统中的矢量存储合作伙伴合作,为整个 .NET 生态系统提供客户端 SDK、库作者和开发人员,以采用 Microsoft.Extensions.VectorData。

我们很高兴您开始使用 Microsoft.Extensions.VectorData 进行构建。

请试用并向我们提供反馈!


资料推荐

 《   智能GitHub Copilot副驾驶®提示和技巧 》

 《   Azure OpenAI 生成式人工智能白皮书 》

 《   利用 AI 和 DevOps 重新定义开发人员体验 》

 《   SAP on Microsoft Cloud 》