开始使用语义内核 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)。
先决条件
如要完成本教程,您必须具备以下条件:
设置环境
您必须首先为本教程设置环境。 要设置环境,请完成以下步骤。
安装依赖项。
在终端中,运行以下命令以安装本教程的软件包。
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
或更高访问权限。
步骤
在笔记本中,运行以下代码以连接您的 Atlas 集群并创建 VectorSearch 类型的索引。此索引定义指定对以下字段进行索引:
embedding
字段作为向量类型。embedding
字段包含使用 OpenAI 的text-embedding-ada-002
嵌入模型创建的嵌入。 索引定义指定了1536
向量维度,并使用cosine
来衡量相似性。
# Connect to your Atlas cluster and specify the collection client = MongoClient(ATLAS_CONNECTION_STRING) collection = client["semantic_kernel_db"]["test"] # Create your index model, then create the search index search_index_model = SearchIndexModel( definition={ "fields": [ { "type": "vector", "path": "embedding", "numDimensions": 1536, "similarity": "cosine" } ] }, name="vector_index", type="vectorSearch" ) collection.create_search_index(model=search_index_model)
构建索引大约需要一分钟时间。在建立索引时,索引处于初始同步状态。 构建完成后,您可以开始查询集合中的数据。
运行向量搜索查询
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 还提供以下开发者资源: