基于Microsoft.Extensions.VectorData实现语义搜索

大家好,我是Edison。

上周水了一篇 Microsoft.Extensions.AI 的介绍文章,很多读者反馈想要了解更多。很多时候,除了集成LLM实现聊天对话,还会有很多语义搜索和RAG的使用场景,那么今天就给大家介绍一下如何完成语义搜索。

Microsoft.Extensions.VectorData介绍

语义搜索正在改变应用程序查找和解释数据的方式,它专注于语义关联,而不仅仅是关键字匹配。

Microsoft.Extensions.VectorData 是一组 .NET代码库,旨在管理 .NET 应用程序中基于向量的数据。这些库为与向量存储交互提供了一个统一的 C# 抽象层,使开发人员能够有效地处理嵌入并执行向量相似性查询。

更多该代码库的内容请参考:Luis 《Introducting Microsoft.Extensions.VectorData

在接下来的demo中,我们会使用以下工具:

(1) Qdrant 作为 VectorStore

(2) Ollama 运行 all-minilm 模型 作为 Emedding生成器

复制代码
ollama pull all-minilm

Qdrant向量搜索引擎

Qdrant是一个向量相似性搜索引擎,它提供了一个生产就绪的服务,拥有便捷的 API来存储、搜索和管理带有额外负载的点(即向量)。它非常适合需要高效相似性搜索的应用程序。我们可以在 Docker 容器中运行 它,这也使它成为对开发人员友好的选择。

容器运行Qdrant:

复制代码
docker run -p 6333:6333 -p 6334:6334 \
-v $(pwd)/qdrant_storage:/qdrant/storage \
qdrant/qdrant

验证Qdrant运行:访问 server:6333/dashboard

开始DEMO案例

安装NuGet包:

复制代码
Microsoft.Extensions.AI (preview)
Microsoft.Extensions.Ollama (preivew)
Microsoft.Extensions.AI.OpenAI (preivew)
Microsoft.Extensions.VectorData.Abstractions (preivew)
Microsoft.SemanticKernel.Connectors.Qdrant (preivew)

这里我们假设做一个CloudService的语义搜索,分下面一些步骤来实现它。

Step1. 配置文件appsettings.json:

复制代码
{
  "Embedding": {
    "EndPoint": "http://localhost:11434",
    "Model": "all-minilm"
  },
  "Qdrant": {
    "Host": "edt-dev-server",
    "Port": 6334
  }
}

Step2. 加载配置:

复制代码
var config = new ConfigurationBuilder()
    .AddJsonFile($"appsettings.json")
    .Build();

Step3. 初始化Embedding生成器:这里我们使用的是本地的Ollama运行all-minilm模型来做。

复制代码
var generator =
    new OllamaEmbeddingGenerator(new Uri(config["Embedding:EndPoint"]), config["Embedding:Model"]);

此外,我们也可以使用OpenAI的Embedding服务:

复制代码
var generator = new OpenAIClient(new ApiKeyCredential(config["OneAPI:ApiKey"]), new OpenAIClientOptions() { Endpoint = new Uri(config["OneAPI:EndPoint"]) })
    .AsEmbeddingGenerator(modelId: config["Embedding:ModelId"]);

Step4. 初始化Qdrant向量存储:

复制代码
var vectorStore = new QdrantVectorStore(new QdrantClient(config["Qdrant:Host"], int.Parse(config["Qdrant:Port"])));
// Get the collection if it exist in qdrant
var cloudServicesStore = vectorStore.GetCollection<ulong, CloudService>("cloudServices");
// Create the collection if it doesn't exist yet.
await cloudServicesStore.CreateCollectionIfNotExistsAsync();

Step5. 插入测试数据:

复制代码
// Define the test data
var cloudServices = new List<CloudService>()
{
    new CloudService
        {
            Key=1,
            Name="Azure App Service",
            Description="Host .NET, Java, Node.js, and Python web applications and APIs in a fully managed Azure service. You only need to deploy your code to Azure. Azure takes care of all the infrastructure management like high availability, load balancing, and autoscaling."
        },
    new CloudService
        {
            Key=2,
            Name="Azure Service Bus",
            Description="A fully managed enterprise message broker supporting both point to point and publish-subscribe integrations. It's ideal for building decoupled applications, queue-based load leveling, or facilitating communication between microservices."
        },
    new CloudService
        {
            Key=3,
            Name="Azure Blob Storage",
            Description="Azure Blob Storage allows your applications to store and retrieve files in the cloud. Azure Storage is highly scalable to store massive amounts of data and data is stored redundantly to ensure high availability."
        },
    new CloudService
        {
            Key=4,
            Name="Microsoft Entra ID",
            Description="Manage user identities and control access to your apps, data, and resources.."
        },
    new CloudService
        {
            Key=5,
            Name="Azure Key Vault",
            Description="Store and access application secrets like connection strings and API keys in an encrypted vault with restricted access to make sure your secrets and your application aren't compromised."
        },
    new CloudService
        {
            Key=6,
            Name="Azure AI Search",
            Description="Information retrieval at scale for traditional and conversational search applications, with security and options for AI enrichment and vectorization."
        }
};
// Insert test data into the collection in qdrant
foreach (var service in cloudServices)
{
    service.Vector = await generator.GenerateEmbeddingVectorAsync(service.Description);
    await cloudServicesStore.UpsertAsync(service);
}

其中,CloudService的定义如下:

复制代码
public class CloudService
{
    [VectorStoreRecordKey]
    public ulong Key { get; set; }

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

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

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

Step6. 生成查询Emedding并从Qdrant中执行查询:

复制代码
// Generate query embedding
var query = "Which Azure service should I use to store my Word documents?";
var queryEmbedding = await generator.GenerateEmbeddingVectorAsync(query);
// Query from vector data store
var searchOptions = new VectorSearchOptions()
{
    Top = 1, // Only return the Top 1 record from Qdrant
    VectorPropertyName = "Vector"
};
var results = await cloudServicesStore.VectorizedSearchAsync(queryEmbedding, searchOptions);
await foreach (var result in results.Results)
{
    Console.WriteLine($"Name: {result.Record.Name}");
    Console.WriteLine($"Description: {result.Record.Description}");
    Console.WriteLine($"Vector match score: {result.Score}");
    Console.WriteLine();
}

首先,验证下Qdrant中是否新增了数据:

其次,查看运行结果显示:返回最匹配的一个数据返回,因为我们设置的Top1记录。

完整的代码示例请参考该示例代码的GitHub仓库

小结

本文介绍了Microsoft.Extensions.Vector的基本概念 和 基本使用,结合Embedding Model(如all-minilm) 和 VectorStore(如Qdrant),我们可以快速实现语义搜索,而不仅仅是关键字匹配。

如果你也是.NET程序员希望参与AI应用的开发,那就快快了解和使用基于Microsoft.Extensioins.AI的生态组件库吧。

参考内容

Eddie Chen,《探索Microsoft.Extensions.VectorData与Qdrant和Azure AI搜索的使用》

Luis,《Introducting Microsoft.Extensions.VectorData》

路边石,《Microsoft.Extensions.AI.OpenAI官方代码示例》

推荐内容

Microsoft Learn

eShopSupport

devblogs


作者:周旭龙

出处:https://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

相关推荐
wendao2 小时前
我开发了个极简的LLM提供商编辑器
前端·react.js·llm
Mintopia3 小时前
🤖 AIGC在Web教育场景中的自适应学习技术设计
前端·javascript·aigc
短视频矩阵源码定制14 小时前
矩阵系统全面解析:构建智能营销体系的核心引擎
java·人工智能·矩阵·aigc·视频
墨风如雪14 小时前
Kimi Linear:告别O(N²)!AI长文本的新一代“记忆大师”
aigc
陈果然DeepVersion17 小时前
Java大厂面试真题:Spring Boot微服务+Kafka消息队列+AIGC场景实战问答全解析
spring boot·redis·微服务·kafka·消息队列·aigc·java面试
Mintopia17 小时前
物联网数据驱动 AIGC:Web 端设备状态预测的技术实现
前端·javascript·aigc
IvanCodes18 小时前
一、初识 LangChain:架构、应用与开发环境部署
人工智能·语言模型·langchain·llm
程序员X小鹿20 小时前
腾讯发布国内首个交互式AI播客!3步上手,告别传统学习(附保姆级教程)
aigc
大千AI助手21 小时前
Megatron-LM张量并行详解:原理、实现与应用
人工智能·大模型·llm·transformer·模型训练·megatron-lm张量并行·大千ai助手
DO_Community21 小时前
AI 推理 GPU 选型指南:从 A100 到 L40S 再看 RTX 4000 Ada
人工智能·aigc·ai编程·ai推理