大家好,我是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

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

基于Microsoft.Extensions.VectorData实现语义搜索的更多相关文章

  1. Asp.Net Core 2.0 项目实战(9) 日志记录,基于Nlog或Microsoft.Extensions.Logging的实现及调用实例

    本文目录 1. Net下日志记录 2. NLog的使用     2.1 添加nuget引用NLog.Web.AspNetCore     2.2 配置文件设置     2.3 依赖配置及调用     ...

  2. Microsoft.Extensions.Options支持什么样的配置类?

    在.Net core中,微软放弃了笨重基于XML的.Config配置文件(好吧,像我这种咸鱼早都忘了如何自己写一个Section了). 现在主推新的高度可扩展的配置文件(参见此处) 对于新的配置系统, ...

  3. 基于Microsoft Azure、ASP.NET Core和Docker的博客系统

    欢迎阅读daxnet的新博客:一个基于Microsoft Azure.ASP.NET Core和Docker的博客系统   2008年11月,我在博客园开通了个人帐号,并在博客园发表了自己的第一篇博客 ...

  4. asp.net core 2.0 Microsoft.Extensions.Logging 文本文件日志扩展

    asp.net core微软官方为日志提供了原生支持,有如下实现 Console Debug EventLog AzureAppServices TraceSource EventSource 并且在 ...

  5. DotNetCore跨平台~一起聊聊Microsoft.Extensions.DependencyInjection

    写这篇文章的心情:激动 Microsoft.Extensions.DependencyInjection在github上同样是开源的,它在dotnetcore里被广泛的使用,比起之前的autofac, ...

  6. 将 WPF、UWP 以及其他各种类型的旧 csproj 迁移成基于 Microsoft.NET.Sdk 的新 csproj

    原文 将 WPF.UWP 以及其他各种类型的旧 csproj 迁移成基于 Microsoft.NET.Sdk 的新 csproj 写过 .NET Standard 类库或者 .NET Core 程序的 ...

  7. Microsoft.Extensions.DependencyInjection 之三:展开测试

    目录 前文回顾 IServiceCallSite CallSiteFactory ServiceProviderEngine CompiledServiceProviderEngine Dynamic ...

  8. Microsoft.Extensions.DependencyInjection 之三:反射可以一战(附源代码)

    目录 前文回顾 IServiceCallSite CallSiteFactory ServiceProviderEngine CompiledServiceProviderEngine Dynamic ...

  9. 2018-12-6-Roslyn-如何基于-Microsoft.NET.Sdk-制作源代码包

    title author date CreateTime categories Roslyn 如何基于 Microsoft.NET.Sdk 制作源代码包 lindexi 2018-12-06 16:2 ...

  10. paip.lucene 4.3 中文语义搜索最佳实践

    paip.lucene 4.3 中文语义搜索最佳实践 首先一个问题是要不要使用lucene 自带的分词器...我觉得最好不使用哪自带的分词器.效果还凑火,就是不好控制... 先使用ik,ict,mms ...

随机推荐

  1. 【微软】微软程序注册(zfile自建API)

    Zfile支持设置自己的回调地址,怎么设置呢? 参考:https://docs.zfile.vip/advanced/onedrive-api/ 上面文档写的很清楚了,我提醒两点 1.进入 https ...

  2. qemu/kvm

    <domain type="kvm"> <name>win7</name> <uuid>e31c1621-b3c3-42ed-be3 ...

  3. IDEA和GIT关于文件中LF和CRLF问题

    问题描述:项目软件安装shell脚本上git仓库管理,但拉取后,上linux运行报错. 问题思考:根据描述信息可以查看到\r字样,初步判别为换行符导致 1.将脚本文件移动至notepad++中,通过视 ...

  4. kubernetes上报Pod已用内存不准问题分析

    1.问题描述: 经常有业务反馈在使用容器云平台过程中监控展示的业务使用内存不准,分析了下kubernetes采集Pod内存使用的实现原理以及相应的解决思路 2.问题分析: 2.1 问题排查: 监控数据 ...

  5. Qt编写的项目作品33-斗图神器(雨田哥作品)

    一.功能特点 支持HTTP,HTTPS网络表情图片下载,本地缓存. 采用MV模式,支持大量图片表情预览查看. 采用多线程异步下载图片刷新. 图片搜索功能(因网络提供API无信息字段提供,占搜索不了.但 ...

  6. CentOS 集群初始化设置

    0. 前置操作 centos-7.9.2009-isos-x86_64安装包下载_开源镜像站-阿里云 下载CentOS-7-x86_64-DVD-2009.iso即可 1. 配置静态网络 1.1 查看 ...

  7. SINE:上下文示例驱动,打造真正的通用分割模型 | NeurIPS'24

    来源:晓飞的算法工程笔记 公众号,转载请注明出处 论文: A Simple Image Segmentation Framework via In-Context Examples 论文地址:http ...

  8. biancheng-socket编程

    http://c.biancheng.net/socket/ 网络编程就是编写程序使两台联网的计算机相互交换数据.这就是全部内容了吗?是的!网络编程要比想象中的简单许多.那么,这两台计算机之间用什么传 ...

  9. ReactNative开发总结

    https://www.jianshu.com/u/b09c3959ab3b ReactNative之项目结构介绍 一.初始化ReactNative工程 自动创建iOS和安卓工程,和对应的JS文件,i ...

  10. shell脚本中的循环(for循环,while循环)及break、continue的用法示例

    Shell脚本中也算是一门简易的编程语言了,当然循环是不能缺少的.常用到的循环有for循环和while循环.下面就分别介绍一下两种循环的结构. [for循环]: Shell脚本中的for循环示例: # ...