Semantic Kernel是一个开源的语义内核 SDK,它供应了一种高效的办法让用户可以在自己的运用程序中集成大措辞模型 (LLM) 的强大功能。Semantic Kernel供应了多种向量数据库的连接器,可以与各种向量数据库集成,从而供应高效的向量查询和更新功能。
2. 在Semantic Kernel中利用Qdrant在我们的大措辞模型 (LLM) 运用程序中,我们常日会须要构建短期和长期影象的办法,以授予更智能的运用程序更大的能力。这个时候,我们就须要利用向量数据库来存储和查询向量数据。Qdrant 是一个高性能的向量数据库,它供应了高效的向量查询和更新功能,可以知足我们的需求。
在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》[2],这里我们变动了存储办法,将VolatileMemoryStore
改为利用 Qdrant 向量数据库的办法。
完成了根本的类库安装,我们就可以引入干系的命名空间了:
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\公众);
接下来我们利用 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;
}
}
在完成了 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 界面上看到干系的向量数据:
在Semantic Kernel中利用Kernel Memory做事和Qdrant向量数据库可以极大地提高数据的存储和检索效率。通过灵巧的数据处理流程和强大的查询功能,可以轻松地在大量的数据中找到最干系的信息。这对付构建高效的AI系统来说,是非常主要的。
References[1]
Semantic Kernel: https://github.com/microsoft/semantic-kernel?wt.mc_id=DT-MVP-5005195[2]
《Building Semantic Memory with Embeddings》: https://github.com/microsoft/semantic-kernel/blob/main/dotnet/notebooks/06-memory-and-embeddings.ipynb?wt.mc_id=DT-MVP-5005195