通过


适用于 .NET AI 应用的矢量数据库

矢量数据库存储和管理矢量 嵌入。 嵌入是保留语义含义的数据的数字表示形式。 单词、文档、图像、音频和其他类型的数据都可以矢量化。 你可以使用嵌入来帮助 AI 模型了解输入内容的含义,以便它可以执行比较和转换操作,例如汇总文本、查找上下文相关数据或根据文本说明创建图像。

例如,可以使用矢量数据库来执行以下操作:

  • 根据图像、主题、情绪和样式识别相似的图像、文档和歌曲。
  • 根据产品特征、功能和用户组识别相似的产品。
  • 根据用户偏好推荐内容、产品或服务。
  • 从大型选项池中确定最佳潜在选项以满足复杂要求。
  • 识别与主要模式或正常模式不同的数据异常或欺诈活动。

矢量数据库提供矢量搜索功能,以便根据它们的数据特征而不是属性字段的完全匹配来查找类似的项。 矢量搜索的工作原理是分析使用 AI 嵌入模型(如 Azure OpenAI 嵌入模型)创建的数据的向量表示形式。 搜索过程会测量数据矢量与查询矢量之间的距离。 最接近查询向量的数据向量是语义上最相似的向量。

大多数新式数据库产品支持矢量搜索以及传统查询;Azure SQL/SQL ServerAzure Cosmos DBPostgreSQL 和其他许多主要产品都是这种情况。 作为替代方法,存在广泛的专用专用向量数据库产品。 这些产品经过高度优化以执行矢量搜索,通常与传统数据库一起安装,以专门处理矢量搜索工作负载。

使用 .NET 和 OpenAI 的矢量搜索工作流

矢量数据库及其搜索功能在具有 Azure OpenAI 的 RAG 模式工作流中特别有用。 通过此模式,可以使用对数据的其他语义丰富的知识来增强 AI 模型。 使用矢量数据库的常见 AI 工作流包括以下步骤:

  1. 使用 OpenAI 嵌入模型为数据创建嵌入。
  2. 在向量数据库或搜索服务中存储嵌入内容并编制索引。
  3. 将用户提示从应用程序转换为嵌入。
  4. 跨数据运行矢量搜索,将用户提示与数据库中的嵌入内容进行比较。
  5. 使用 gpt-4o 等语言模型根据矢量搜索结果生成用户友好的结果。

有关此流的实践示例,请参阅 Implement Azure OpenAI with RAG 在 .NET 应用中使用矢量搜索教程。

RAG 模式的其他优势包括:

  • 从 AI 模型生成与用户提示的上下文相关的准确响应。
  • 克服 LLM 令牌限制——主要工作通过数据库矢量搜索来完成。
  • 减少因在更新数据上进行频繁微调而产生的成本。

Microsoft Extensions.VectorData 库

若要从.NET使用矢量搜索,可以使用常规数据库驱动程序或 SDK,而无需任何其他库或 API。 例如,SQL Server 在使用标准.NET驱动程序 SqlClient 时,可以在 T-SQL 中执行矢量搜索。 但是,以这种方式访问矢量搜索通常是相当低级别的,需要相当多的仪式来处理序列化/反序列化,并且生成的代码不能跨数据库移植。

或者,📦 Microsoft。Extensions.VectorData.Abstractions 包提供统一的抽象层,用于与.NET中的矢量存储进行交互。 通过这些抽象,您可以针对单个 API 编写简单的高级别代码,并以对应用程序进行最少更改的方式替换底层向量存储。

该库提供以下关键功能:

  • 无缝.NET类型映射:将.NET类型直接映射到数据库,类似于对象/关系映射工具。
  • 统一的数据模型:使用.NET属性定义数据模型,并将其用于任何受支持的矢量存储。
  • CRUD 操作:在向量存储中创建、读取、更新和删除记录。
  • 矢量和混合搜索:使用矢量搜索通过语义相似性查询记录,或组合矢量和文本搜索进行混合搜索。
  • 嵌入生成管理:配置嵌入生成器一次,让库以透明方式处理生成。
  • 集合管理:在向量存储中创建、列出和删除集合(表或索引)。

Microsoft。Extensions.VectorData 也是其他更高级别层的构建基块,需要与向量数据库交互。 例如,Microsoft.Extensions.DataIngestion

Microsoft Extensions.VectorData 和 Entity Framework Core

如果已使用Entity Framework Core访问数据库,则数据库提供程序可能已经支持矢量搜索,并且 LINQ 查询可用于表达此类搜索;Microsoft。Extensions.VectorData 不一定需要在此类应用程序中使用。 但是,EF Core 不支持大多数专用矢量数据库,Microsoft。Extensions.VectorData 可以为使用这些扩展提供良好的体验。 此外,您可能会发现自己在同一应用程序中同时使用 EF 和 Microsoft.Extensions.VectorData,例如在使用额外层时,如 Microsoft.Extensions.DataIngestion。

关键抽象

下面是创建集合、更新插入记录和执行矢量搜索的最小端到端示例:

using Microsoft.Extensions.AI;
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel.Connectors.InMemory;

// Configure an embedding generator to transform text to embeddings
IEmbeddingGenerator<string, Embedding<float>> embeddingGenerator = ...;

// Create a vector store and get a collection with the embedding generator
var vectorStore = new InMemoryVectorStore(new() { EmbeddingGenerator = embeddingGenerator });
var collection = vectorStore.GetCollection<int, Movie>("movies");
await collection.EnsureCollectionExistsAsync();

// Upsert some records
await collection.UpsertAsync(new Movie { Key = 1, Title = "The Lion King", Description = "An animated film about a young lion prince" });
await collection.UpsertAsync(new Movie { Key = 2, Title = "Inception", Description = "A thief who steals corporate secrets through dream-sharing technology" });
await collection.UpsertAsync(new Movie { Key = 3, Title = "Finding Nemo", Description = "A fish searches the ocean for his lost son" });

// Search for movies similar to the query text
await foreach (var result in collection.SearchAsync("animals in the wild", top: 2))
{
    Console.WriteLine($"{result.Record.Title} (score: {result.Score})");
}

// Define the data model
class Movie
{
    [VectorStoreKey]
    public int Key { get; set; }

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

    [VectorStoreVector(Dimensions: 1536)]
    public string Description { get; set; }
}

矢量存储提供商

Microsoft.Extensions.VectorData.Abstractions 包定义抽象,并且单独的 provider 包为特定向量数据库提供实现。 选择与矢量数据库匹配的提供程序,例如,Microsoft。SemanticKernel.Connectors.AzureAISearch

注释

尽管包名称中包含“SemanticKernel”,但这些提供程序与语义内核无关,并且可用于.NET中的任何位置,包括代理框架。

所有提供程序实现相同的 VectorStoreVectorStoreCollection<TKey,TRecord> 抽象类,因此可以在它们之间切换,而无需更改应用程序逻辑。

小窍门

使用内存中提供程序(Microsoft.SemanticKernel.Connectors.InMemory)在最初的开发/原型设计阶段——它不需要任何外部服务或配置,以后可在以后替换为生产环境中的提供程序。 避免使用 InMemory 提供程序进行测试,因为此提供程序与生产数据库之间可能存在重要差异。 请考虑使用 testcontainers 针对生产数据库系统运行测试。