在Semantic Kernel中使用Qdrant向量数据库

2024-03-26 17:04

本文主要是介绍在Semantic Kernel中使用Qdrant向量数据库,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文将介绍如何在Semantic Kernel中使用Qdrant向量数据库,并演示如何在Semantic Kernel中进行向量更新和查询操作。

1. 背景

在前一篇文章《Qdrant 向量数据库的部署以及如何在 .NET 中使用 TLS 安全访问》中,我们介绍了如何使用 Docker 部署 Qdrant 向量数据库,以及其相关的安全配置,并演示了如何使用 .NET 通过 TLS 安全访问 Qdrant 向量数据库。现在,我们将在Semantic Kernel中使用Qdrant向量数据库,并演示如何进行向量更新和查询操作。

Semantic Kernel是一个开源的语义内核 SDK,它提供了一种高效的方式让用户可以在自己的应用程序中集成大语言模型 (LLM) 的强大功能。Semantic Kernel提供了多种向量数据库的连接器,可以与各种向量数据库集成,从而提供高效的向量查询和更新功能。

2. 在Semantic Kernel中使用Qdrant

在我们的大语言模型 (LLM) 应用程序中,我们通常会需要构建短期和长期记忆的方式,以赋予更智能的应用程序更大的能力。这个时候,我们就需要使用向量数据库来存储和查询向量数据。Qdrant 是一个高性能的向量数据库,它提供了高效的向量查询和更新功能,可以满足我们的需求。

2.1 安装Semantic Kernel SDK

在Semantic Kernel中使用Qdrant向量数据库,我们首先需要安装Semantic Kernel SDK,以及 Semantic Kernel 的 Memory 插件和 Qdrant 连接器:

dotnet add package Microsoft.SemanticKernel --version 1.6.3
dotnet add package Microsoft.SemanticKernel.Plugins.Memory --version 1.6.3-alpha
dotnet add package Microsoft.SemanticKernel.Connectors.Qdrant --version 1.6.3-alpha

通过上面的 alpha 标识,我们可以看到 Semantic Kernel 的 Memory 插件和 Qdrant 连接器还处于预览阶段,后续相关方法可能会有所变化,我们需要注意这一点。

在安装好 Semantic Kernel SDK 和相关插件后,我们就可以在我们的应用程序中使用 Qdrant 向量数据库了。接下来我会进行一个一个简单的代码示例,修改自 Github 的 notebook 《Building Semantic Memory with Embeddings》,这里我们更改了存储方式,将VolatileMemoryStore 改为使用 Qdrant 向量数据库的方式。

2.2 引入 Embedding 服务

完成了基础的类库安装,我们就可以引入相关的命名空间了:

using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.SemanticKernel.Connectors.Qdrant;
using Microsoft.SemanticKernel.Memory;

接下来,我们需要创建一个 MemoryBuilder 对象,这里需要注意的是,因为功能是实验性的,所以我们需要禁用一些警告:

#pragma warning disable SKEXP0001, SKEXP0010, SKEXP0050
var memoryBuilder = new MemoryBuilder();

非常重要的是,这里我们需要选择一个 Embedding 服务,用来将文本转换为向量。这里我们使用的是 Azure AI 的 text-embedding-ada-002 服务,需要在 Azure OpenAI Studio 中完成该模型的部署:

在这里插入图片描述

memoryBuilder.WithAzureOpenAITextEmbeddingGeneration("text-embedding-ada-002", "AZURE_ENDPOINT ", "AZURE_OPENAI_KEY");

2.3 连接 Qdrant 向量数据库

接下来我们使用 Semantic Kernel 提供的连接器,将 MemoryBuilder 与 Qdrant 向量数据库连接起来,这里使用的通讯方式不是我们上一篇文章中官方客户端使用的 GRPC,而是使用的 HTTP:

HttpClient httpClient = new HttpClient(new CustomQdrantHandler("<certificate thumbprint>", "client.pfx", "password"));
#pragma warning disable SKEXP0020
memoryBuilder.WithQdrantMemoryStore(httpClient,  1536 , "https://localhost:6333");
var memory = memoryBuilder.Build();

这里需要注意的是,因为我们从官方样例的 VolatileMemoryStore 改为了 Qdrant 向量数据库,所以这里我们需要使用 WithQdrantMemoryStore 方法,这个方法需要提供所使用的 Embedding 的维度。

另外,因为我们使用的是自签名证书,所以我们需要对 HttpClient 进行一些配置,这里我们使用了一个自定义的 CustomQdrantHandler 类,用来处理证书的验证,并提供客户端证书进行双向认证。

internal class CustomQdrantHandler : HttpClientHandler{private string _knownHash;private X509Certificate2 _clientCertificate;public CustomQdrantHandler(string knownHash, string certPath, string certPassword) : base(){_knownHash = knownHash;_clientCertificate = new X509Certificate2(certPath, certPassword);this.ClientCertificates.Add(_clientCertificate);this.ServerCertificateCustomValidationCallback = CheckServerCertificate;}private bool CheckServerCertificate(HttpRequestMessage httpRequestMessage, X509Certificate2 certificate, X509Chain chain, SslPolicyErrors errors){using var sha256 = SHA256.Create();var hashBytes = sha256.ComputeHash(certificate.GetPublicKey());var hashString = BitConverter.ToString(hashBytes).Replace("-", "").ToLower();return hashString == _knownHash;}
}

2.4 向量更新和查询

在完成了 MemoryBuilder 的构建后,我们就可以使用 Memory 对象进行向量的更新和查询操作了。这里我们使用一个关于“我”的简单介绍的例子,将一些文本转换为向量,并存储到 Qdrant 向量数据库中:

string MemoryCollectionName = "aboutMe";
await memory.SaveInformationAsync(MemoryCollectionName, id: "info1", text: "My name is Andrea");
await memory.SaveInformationAsync(MemoryCollectionName, id: "info2", text: "I currently work as a tourist operator");
await memory.SaveInformationAsync(MemoryCollectionName, id: "info3", text: "I currently live in Seattle and have been living there since 2005");
await memory.SaveInformationAsync(MemoryCollectionName, id: "info4", text: "I visited France and Italy five times since 2015");
await memory.SaveInformationAsync(MemoryCollectionName, id: "info5", text: "My family is from New York");

通过上面的代码,我们将这些文本信息存储到 Qdrant 向量数据库中,SaveInformationAsync 指定了集合名称、文本 ID 和文本内容。

接下来,我们可以定义下面一些问题,然后使用 Memory 对象进行查询操作:

var questions =  new[]
{"what is my name?","where do I live?","where is my family from?","where have I travelled?","what do I do for work?",
};foreach (var q in questions)
{var response = await memory.SearchAsync(MemoryCollectionName, q).FirstOrDefaultAsync();Console.WriteLine("Q: " + q);Console.WriteLine("A: " + response?.Relevance.ToString() + "\t" + response?.Metadata.Text);
}

通过上面的代码,我们搜索并打印了一些问题的答案,这里我们使用的是 SearchAsync 方法,指定了集合名称和问题文本。该方法对问题进行了一些筛选,默认只返回最相关的一个答案,并且要求相关性至少为 0.7。

在这里插入图片描述

在运行后,我们即可在 Qdrant 的 Web 界面上看到相关的向量数据:

在这里插入图片描述

3. 总结

在Semantic Kernel中使用Kernel Memory服务和Qdrant向量数据库可以极大地提高数据的存储和检索效率。通过灵活的数据处理流程和强大的查询功能,可以轻松地在大量的数据中找到最相关的信息。这对于构建高效的AI系统来说,是非常重要的。

这篇关于在Semantic Kernel中使用Qdrant向量数据库的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/849225

相关文章

Spring Boot整合Redis注解实现增删改查功能(Redis注解使用)

《SpringBoot整合Redis注解实现增删改查功能(Redis注解使用)》文章介绍了如何使用SpringBoot整合Redis注解实现增删改查功能,包括配置、实体类、Repository、Se... 目录配置Redis连接定义实体类创建Repository接口增删改查操作示例插入数据查询数据删除数据更

Mysql数据库聚簇索引与非聚簇索引举例详解

《Mysql数据库聚簇索引与非聚簇索引举例详解》在MySQL中聚簇索引和非聚簇索引是两种常见的索引结构,它们的主要区别在于数据的存储方式和索引的组织方式,:本文主要介绍Mysql数据库聚簇索引与非... 目录前言一、核心概念与本质区别二、聚簇索引(Clustered Index)1. 实现原理(以 Inno

使用python生成固定格式序号的方法详解

《使用python生成固定格式序号的方法详解》这篇文章主要为大家详细介绍了如何使用python生成固定格式序号,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下... 目录生成结果验证完整生成代码扩展说明1. 保存到文本文件2. 转换为jsON格式3. 处理特殊序号格式(如带圈数字)4

Java使用Swing生成一个最大公约数计算器

《Java使用Swing生成一个最大公约数计算器》这篇文章主要为大家详细介绍了Java使用Swing生成一个最大公约数计算器的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下... 目录第一步:利用欧几里得算法计算最大公约数欧几里得算法的证明情形 1:b=0情形 2:b>0完成相关代码第二步:加

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

MySQL数据库双机热备的配置方法详解

《MySQL数据库双机热备的配置方法详解》在企业级应用中,数据库的高可用性和数据的安全性是至关重要的,MySQL作为最流行的开源关系型数据库管理系统之一,提供了多种方式来实现高可用性,其中双机热备(M... 目录1. 环境准备1.1 安装mysql1.2 配置MySQL1.2.1 主服务器配置1.2.2 从

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代