开始使用语义内核 C# 集成
注意
本教程使用语义内核 C# 库 。有关使用 Python 库的教程,请参阅 Semantic Kernel Python 集成入门。
您可以将 Atlas Vector Search 与 Microsoft Semantic Kernel 集成 构建 AI 应用程序并实施检索增强生成 (RAG)。本教程演示如何开始使用带有语义内核的Atlas Vector Search ,对数据执行语义Atlas Search并构建 RAG实施。 具体来说,您执行以下操作:
设置环境。
在 Atlas 上存储自定义数据。
在您的数据上创建一个 Atlas Vector Search 索引。
对您的数据运行语义搜索查询。
使用 Atlas Vector Search 来回答有关数据的问题,从而实现 RAG。
背景
Semantic Kernel 是一个开源 SDK,可让您将各种 AI 服务和插件与您的应用程序相结合。 您可以将语义内核用于各种 AI 使用案例,包括RAG 。
通过将 Atlas Vector Search 与语义内核集成,您可以将 Atlas 用作矢量数据库,并使用 Atlas Vector Search 通过从数据中检索语义相似的文档来实现 RAG。要了解有关 RAG 的更多信息,请参阅使用 Atlas Vector Search 进行检索增强生成 (RAG)。
先决条件
如要完成本教程,您必须具备以下条件:
一个Atlas账户,其集群运行MongoDB 6.0.11、7.0.2 或更高版本(包括 RC)。确保您的IP解决包含在Atlas项目的访问权限列表中。要学习;了解更多信息,请参阅创建集群。
一个 OpenAI API 密钥。您必须拥有付费的 OpenAI 账号,该账号具有可用于 API 请求的信用额度。要了解有关注册 OpenAI 账号的更多信息,请参阅 OpenAI API 网站。
用于运行 .NET 应用程序的终端和代码编辑器。
C#/.NET 已安装。
设置环境
您必须首先为本教程设置环境。 要设置环境,请完成以下步骤。
安装依赖项。
在终端中,运行以下命令以安装本教程的软件包。
dotnet add package Microsoft.SemanticKernel dotnet add package Microsoft.SemanticKernel.Connectors.MongoDB --prerelease dotnet add package Microsoft.SemanticKernel.Connectors.OpenAI dotnet add package Microsoft.SemanticKernel.Memory dotnet add package Microsoft.SemanticKernel.Plugins.Memory --prerelease
定义环境变量。
在终端中运行以下命令,将 Atlas 集群的 SRV 连接字符串和 OpenAI API 密钥添加到环境中。
export OPENAI_API_KEY="<Your OpenAI API Key>" export ATLAS_CONNECTION_STRING="<Your MongoDB Atlas SRV Connection String>"
注意
连接字符串应使用以下格式:
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
在 Atlas 中存储自定义数据。
在本部分中,您将初始化内核,它是用于管理应用程序的服务和插件的主接口。通过内核,您可以配置 AI 服务,将 Atlas 实例化为向量数据库(也称为内存存储),并将自定义数据加载到 Atlas 集群。
将以下代码复制并粘贴到应用程序的 Program.cs
文件中。
此代码执行以下操作:
导入 Semantic Kernel 和所有必需的包。
通过从环境中检索 SRV 连接字符串,连接到 Atlas 集群。
从环境中检索 OpenAI API 密钥,并创建 OpenAI
text-embedding-ada-002
嵌入模型的实例。初始化 Kernel,然后将以下 AI 服务添加到 Kernel:
OpenAI 的
gpt-3.5-turbo
作为聊天模型,用于为回答有关数据的问题部分生成响应。
将 Atlas 实例化为内存存储,指定以下参数:
semantic_kernel_db.test
作为用于存储文档的集合。vector_index
作为用于查询内存存储的索引。
初始化一个名为
SemanticTextMemory
的类,该类提供了一组原生方法,可帮助您在内存中存储和检索文本。通过调用
PopulateMemoryAsync
方法在semantic_kernel_db.test
集合中填充示例文档。
// Import Packages using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Connectors.MongoDB; using Microsoft.SemanticKernel.Connectors.OpenAI; using Microsoft.SemanticKernel.Memory; using Microsoft.SemanticKernel.Plugins.Memory; class Program { static async Task Main(string[] args) { // Get connection string and OpenAI API Key var connectionString = Environment.GetEnvironmentVariable("ATLAS_CONNECTION_STRING"); if (connectionString == null) { Console.WriteLine("You must set your 'ATLAS_CONNECTION_STRING' environment variable."); Environment.Exit(0); } var openAIKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY"); if (openAIKey == null) { Console.WriteLine("You must set your 'OPENAPI_KEY' environment variable."); Environment.Exit(0); } // Create new OpenAI API Embedding Model var embeddingGenerator = new OpenAITextEmbeddingGenerationService("text-embedding-ada-002", openAIKey); // Initialize Kernel IKernelBuilder builder = Kernel.CreateBuilder(); // Add OpenAI Chat Completion to Kernel builder.AddOpenAIChatCompletion( modelId: "gpt-3.5-turbo", apiKey: openAIKey ); Kernel kernel = builder.Build(); // Instantiate Atlas as a memory store. MongoDBMemoryStore memoryStore = new(connectionString, "semantic_kernel_db", indexName: "vector_index"); SemanticTextMemory textMemory = new(memoryStore, embeddingGenerator); // Populate memory with sample data async Task PopulateMemoryAsync(Kernel kernel) { await textMemory.SaveInformationAsync(collection: "test", text: "I am a developer", id: "1"); await textMemory.SaveInformationAsync(collection: "test", text: "I started using MongoDB two years ago", id: "2"); await textMemory.SaveInformationAsync(collection: "test", text: "I'm using MongoDB Vector Search with Semantic Kernel to implement RAG", id: "3"); await textMemory.SaveInformationAsync(collection: "test", text: "I like coffee", id: "4"); } await PopulateMemoryAsync(kernel); } }
保存文件,然后运行以下命令将数据加载到 Atlas:
dotnet run
提示
运行示例代码后,您可以导航到您的集群中的semantic_kernel_db.test
collection,在 Atlas 用户界面中查看向量嵌入。
创建 Atlas Vector Search 索引
要在向量存储上启用向量搜索查询,请在semantic_kernel_db.test
集合上创建 Atlas Vector Search 索引。
必需的访问权限
要创建 Atlas Vector Search 索引,您必须对 Atlas 项目具有Project Data Access Admin
或更高访问权限。
步骤
AtlasGoClusters在Atlas中,Go项目的 页面。
如果尚未显示,请从导航栏上的 Organizations 菜单中选择包含所需项目的组织。
如果尚未显示,请从导航栏的Projects菜单中选择所需的项目。
如果尚未出现,请单击侧边栏中的 Clusters(集群)。
会显示集群页面。
转到集群的 Atlas Search 页面。
您可以从侧边栏、 Data Explorer 或集群详细信息页面转到 Atlas Search 页面。
在侧边栏中,单击 Services 标题下的 Atlas Search。
从 Select data source 下拉菜单中选择您的集群并单击 Go to Atlas Search。
将显示 Atlas Search 页面。
单击集群的对应 Browse Collections 按钮。
展开数据库并选择集合。
单击该集合的 Search Indexes 标签页。
将显示 Atlas Search 页面。
单击集群的名称。
单击 Atlas Search 标签页。
将显示 Atlas Search 页面。
定义 Atlas Vector Search 索引。
单击 Create Search Index(连接)。
在Atlas Vector Search下,选择JSON Editor ,然后单击Next 。
在 Database and Collection(数据库和集合)部分中找到
semantic_kernel_db
数据库,然后选择test
集合。在 Index Name 字段中输入
vector_index
。将默认定义替换为以下索引定义,然后单击 Next。
此索引定义用于指定在 vectorSearch 类型的索引中对以下字段建立索引:
embedding
字段作为向量类型。embedding
字段包含使用 OpenAI 的text-embedding-ada-002
嵌入模型创建的嵌入。 索引定义指定了1536
向量维度,并使用cosine
来衡量相似性。
1 { 2 "fields": [ 3 { 4 "type": "vector", 5 "path": "embedding", 6 "numDimensions": 1536, 7 "similarity": "cosine" 8 } 9 ] 10 }
运行向量搜索查询
Atlas构建索引后,您可以对数据运行向量Atlas Search查询。
在 Program.cs
文件的末尾,添加以下代码以对字符串 What is my job title?
执行基本语义搜索。它打印最相关的文档以及介于 0
和 1
之间的相关性分数。
1 var results = textMemory.SearchAsync(collection: "test", query: "What is my job title?"); 2 3 await foreach (var result in results) { 4 Console.WriteLine($"Answer: {result?.Metadata.Text}, {result?.Relevance}"); 5 } 6 Console.WriteLine("Search completed.");
保存文件,然后运行以下命令以查看语义搜索的结果:
dotnet run
Answer: I am a developer, 0.8913083076477051 Search completed.
回答有关数据的问题
本节展示了使用 Atlas Vector Search 和 Semantic Kernel 的 RAG 实现示例。现在您已经使用 Atlas Vector Search 检索语义相似的文档,请将以下代码示例粘贴到 Program.cs
的末尾,以提示 LLM 根据这些文档回答问题。
此代码执行以下操作:
将
TextMemoryPlugin
类的函数导入到内核的textMemory
中。构建一个提示模板,该模板使用
TextMemoryPlugin
类中的recall
函数,对内核的textMemory
执行语义搜索,以查找字符串When did I start using MongoDB?
。使用内核的
CreateFunctionFromPrompt
函数从聊天提示符创建名为settings
的函数。使用以下参数调用内核的
InvokeAsync
函数,以从聊天模型生成响应:配置提示模板和
OpenAIPromptExecutionSettings
的settings
函数。将问题
When did I start using MongoDB?
作为提示模板中{{$input}}
变量的值。semantic_kernel_db.test
作为从中检索信息的集合。
打印问题和生成响应。
1 kernel.ImportPluginFromObject(new TextMemoryPlugin(textMemory)); 2 const string promptTemplate = @" 3 Answer the following question based on the given context. 4 Question: {{$input}} 5 Context: {{recall 'When did I start using MongoDB?'}} 6 "; 7 8 // Create and Invoke function from the prompt template 9 var settings = kernel.CreateFunctionFromPrompt(promptTemplate, new OpenAIPromptExecutionSettings()); 10 var ragResults = await kernel.InvokeAsync(settings, new() 11 { 12 ["When did I start using MongoDB?", ] = 13 ["test" ] = 14 }); 15 16 // Print RAG Search Results 17 Console.WriteLine("Question: When did I start using MongoDB?"); 18 Console.WriteLine($"Answer: {ragResults.GetValue<string>()}");
保存文件,然后运行以下命令以生成响应:
dotnet run
Question: When did I start using MongoDB? Answer: You started using MongoDB two years ago.
提示
您可以添加自己的数据并替换代码的以下部分,以生成对不同问题的响应:
{{recall '<question>'}}
,[TextMemory.InputParam] = "<question>"
,Console.WriteLine("Question: <question>")
.
后续步骤
MongoDB 还提供以下开发者资源: