Docs 菜单
Docs 主页
/ /

开始使用语义内核 C# 集成

注意

本教程使用语义内核 C# 库 。有关使用 Python 库的教程,请参阅 Semantic Kernel Python 集成入门。

您可以将 MongoDB Vector Search 与 Microsoft 语义内核 集成,以构建 AI 应用程序并实现检索增强生成 (RAG)。本教程演示如何开始使用带有语义内核的MongoDB Vector Search 对数据执行语义搜索并构建RAG实施。具体来说,您执行以下操作:

  1. 设置环境。

  2. 在MongoDB中存储自定义数据。

  3. 对数据创建MongoDB Vector Search索引。

  4. 对您的数据运行语义搜索查询。

  5. 使用MongoDB Vector Search 来回答有关数据的问题,从而实施 RAG。

Semantic Kernel 是一个开源 SDK,可让您将各种 AI 服务和插件与您的应用程序相结合。 您可以将语义内核用于各种 AI 使用案例,包括RAG

通过将MongoDB Vector Search 与语义内核集成,您可以将MongoDB用作向量数据库,并使用MongoDB Vector Search 从数据中检索语义相似的文档来实现RAG。要学习;了解有关RAG的更多信息,请参阅使用MongoDB进行检索增强生成 (RAG)

如要完成本教程,您必须具备以下条件:

  • 以下MongoDB 集群类型之一:

  • OpenAI API密钥。您必须拥有一个具有可用于API请求的积分的 OpenAI 帐户。要学习;了解有关注册 OpenAI 帐户的更多信息,请参阅 OpenAI API网站。

  • 用于运行 .NET 应用程序的终端和代码编辑器。

  • 已安装C#/ .NET

您必须首先为本教程设置环境。 要设置环境,请完成以下步骤。

1

在终端中运行以下命令,创建一个名为 sk-mongodb 的新目录,并初始化应用程序:

mkdir sk-mongodb
cd sk-mongodb
dotnet new console
2

在终端中,运行以下命令以安装本教程的软件包。

dotnet add package Microsoft.SemanticKernel
dotnet add package Microsoft.SemanticKernel.Connectors.MongoDB --prerelease
dotnet add package Microsoft.SemanticKernel.Connectors.OpenAI
dotnet add package Microsoft.Extensions.AI
dotnet add package Microsoft.Extensions.AI.OpenAI
dotnet add package Microsoft.Extensions.AI.Abstractions
dotnet add package Microsoft.Extensions.VectorData.Abstractions
dotnet add package SemanticKernelPooling.Connectors.OpenAI
3

在终端中,运行以下命令,将MongoDB集群的SRV连接字符串和 OpenAI API密钥添加到您的环境中。

export OPENAI_API_KEY="<Your OpenAI API Key>"
export MONGODB_URI="<Your MongoDB Atlas SRV Connection String>"

注意

<connection-string> 替换为您的 Atlas 集群或本地部署的连接字符串。

连接字符串应使用以下格式:

mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net

要学习;了解更多信息,请参阅通过驱动程序连接到集群。

连接字符串应使用以下格式:

mongodb://localhost:<port-number>/?directConnection=true

要学习;了解更多信息,请参阅连接字符串。

在本部分中,您将初始化内核,它是用于管理应用程序的服务和插件的主接口。通过内核,您可以配置AI服务,将MongoDB实例化为向量数据库(也称为内存存储),并将自定义数据加载到MongoDB 集群。

将以下代码复制并粘贴到应用程序的 Program.cs 文件中。

此代码执行以下操作:

  • 导入 Semantic Kernel 和所有必需的包。

  • 通过从环境中检索 SRV 连接字符串,连接到 Atlas 集群。

  • 从环境中检索 OpenAI API 密钥,并创建 OpenAI text-embedding-ada-002 嵌入模型的实例。

  • 将 Atlas 实例化为内存存储,指定以下参数:

    • semantic_kernel_db.records 作为用于存储文档的集合。

    • vector_index 作为用于查询内存存储的索引。

  • 通过调用 CreateCollectionFromListAsync 方法在 semantic_kernel_db.records 集合中填充示例文档。

  • 定义包含 semantic_kernel_db.records集合的变量 recordCollection

  • 创建两个辅助方法来帮助在内存中存储和检索文本:

    • CreateRecord:用于创建新 DataModel对象的工厂。

    • CreateCollectionFromListAsync:一种方法,用于获取字符串条目、为字符串生成嵌入、创建相应的记录,然后将这些记录更新或插入(upsert)到Atlas 集群的集合中。

  • 创建一个 DataModel 类,用于定义存储在MongoDB集合中的文档的结构。

using Microsoft.Extensions.AI;
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel.Connectors.MongoDB;
using Microsoft.SemanticKernel.Data;
using MongoDB.Bson;
using MongoDB.Driver;
using OpenAI;
#pragma warning disable SKEXP0001
static class Program
{
static async Task Main(string[] args)
{
// Get connection string and OpenAI API Key
var connectionString = Environment.GetEnvironmentVariable("MONGODB_URI");
if (connectionString == null)
{
Console.WriteLine("You must set your 'MONGODB_URI' 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 OpenAIClient(openAIKey)
.GetEmbeddingClient("text-embedding-ada-002")
.AsIEmbeddingGenerator();
// Instantiate MongoDB as a vector store
var mongoClient = new MongoClient(connectionString);
var options = new MongoVectorStoreOptions { EmbeddingGenerator = embeddingGenerator };
var vectorStore = new MongoVectorStore(mongoClient.GetDatabase("semantic_kernel_db"), options);
// Sample data
string[] lines =
[
"I am a developer",
"I started using MongoDB two years ago",
"I'm using MongoDB Vector Search with Semantic Kernel to implement RAG",
"I like coffee"
];
// Populate database with sample data
await CreateCollectionFromListAsync<string, DataModel>(vectorStore, "records", lines, embeddingGenerator, CreateRecord);
// Get the specific collection from the vector store
var recordCollection = vectorStore.GetCollection<string, DataModel>("records");
}
static DataModel CreateRecord(string text, ReadOnlyMemory<float> embedding)
=> new()
{
Key = ObjectId.GenerateNewId().ToString(),
Text = text,
Embedding = embedding
};
static async Task CreateCollectionFromListAsync<TKey, TRecord>(
this VectorStore vectorStore,
string collectionName,
string[] entries,
IEmbeddingGenerator<string, Embedding<float>> embeddingGenerator,
Func<string, ReadOnlyMemory<float>, TRecord> createRecord)
where TKey : notnull
where TRecord : class
{
// Get and create collection if it doesn't exist
var collection = vectorStore.GetCollection<TKey, TRecord>(collectionName);
await collection.EnsureCollectionExistsAsync().ConfigureAwait(false);
// Create records and generate embeddings for them
var embeddings = await embeddingGenerator.GenerateAsync(entries);
var records = entries.Zip(embeddings, (entry, embedding) => createRecord(entry, embedding.Vector));
// Add them to the database
await collection.UpsertAsync(records).ConfigureAwait(false);
}
internal sealed class DataModel
{
[VectorStoreKey]
[TextSearchResultName]
public required String Key { get; init; }
[VectorStoreData]
[TextSearchResultValue]
public required string Text { get; init; }
[VectorStoreVector(1536)]
public ReadOnlyMemory<float> Embedding { get; init; }
}
}

保存文件,然后运行以下命令将数据加载到MongoDB中:

dotnet run

提示

运行示例代码后,如果您使用的是Atlas ,则可以导航到Atlas 用户界面中的 semantic_kernel_db.test命名空间来验证向量嵌入。

创建向量嵌入后,您可以对数据运行向量搜索查询。

Program.cs文件中 Program 类的末尾添加以下代码,对字符串 What is my job title? 执行基本语义搜索。 它会打印最相关的文档。

1// Create a text search instance using the InMemory vector store.
2var textSearch = new VectorStoreTextSearch<DataModel>(recordCollection, embeddingGenerator);
3
4// Search and return results as TextSearchResult items
5var query = "What is my job title?";
6KernelSearchResults<TextSearchResult> textResults = await textSearch.GetTextSearchResultsAsync(query, new() { Top = 2, Skip = 0 });
7await foreach (TextSearchResult result in textResults.Results)
8{
9 Console.WriteLine($"Answer: {result.Value}");
10}
11Console.WriteLine("Search completed.");

保存文件,然后运行以下命令以查看语义搜索的结果:

dotnet run
Answer: I am a developer
Search completed.

本部分展示使用 MongoDB Vector Search 和语义内核实施RAG 的示例。现在,您已使用MongoDB Vector Search检索语义相似的文档,请将以下代码示例粘贴到 Program 类的末尾 Program.cs 中,以提示 法学硕士 根据这些文档回答问题。

此代码执行以下操作:

  • 使用 OpenAI 的 gpt-4o 创建新内核作为聊天模型以生成响应。

  • 使用向量存储创建新的文本搜索实例。

  • 定义向聊天模型询问的问题,并初始化变量 retrievedContext 以保存向量存储中的上下文。

  • recordCollection 中对问题 When did I start using MongoDB? 执行语义搜索,并返回最相关的搜索结果。

  • 构建提示模板,指示AI模型仅根据检索到的上下文回答问题。

  • 使用内核的 CreateFunctionFromPrompt 函数从聊天提示符创建名为 ragFunction 的函数。

  • 通过创建一个新对象来保存问题和上下文,为 RAG 提示准备参数。

  • 使用以下参数调用内核的 InvokeAsync 函数,以从聊天模型生成响应:

    • 用于配置提示模板的 ragFunction

    • 包含问题和上下文的 ragArguments

  • 打印问题和生成响应。

// Create a kernel with OpenAI chat completion
IKernelBuilder kernelBuilder = Kernel.CreateBuilder();
kernelBuilder.AddOpenAIChatCompletion(
modelId: "gpt-4o",
apiKey: openAIKey);
Kernel kernel = kernelBuilder.Build();
// Create a text search instance using the vector store collection.
var textSearch = new VectorStoreTextSearch<DataModel>(recordCollection, embeddingGenerator);
// --- Modified RAG Section ---
var userQuestion = "When did I start using MongoDB?";
string retrievedContext = "No relevant context found."; // Default
// 1. Perform search to get context
var searchResults = await textSearch.GetTextSearchResultsAsync(userQuestion, new() { Top = 1 }); // Get most relevant result
await foreach (var result in searchResults.Results)
{
if (result.Value != null)
{
retrievedContext = result.Value; // Use the text from the search result as context
break; // Take the most relevant result
}
}
// 2. Define a prompt template that uses the retrieved context
const string ragPromptTemplate = @"
Context:
{{$context}}
Question:
{{$question}}
Based *only* on the context provided, answer the question.
Answer:
";
// 3. Create a function from the RAG prompt template
var ragFunction = kernel.CreateFunctionFromPrompt(ragPromptTemplate);
// 4. Prepare arguments for the RAG prompt
var ragArguments = new KernelArguments
{
["question"] = userQuestion,
["context"] = retrievedContext
};
// 5. Invoke the RAG prompt
var ragResult = await kernel.InvokeAsync(ragFunction, ragArguments);
Console.WriteLine($"Question: {userQuestion}");
Console.WriteLine($"Retrieved Context: {retrievedContext}");
Console.WriteLine($"Answer: {ragResult.GetValue<string>()}");
// --- End of Modified RAG Section ---

保存文件,然后运行以下命令以生成响应:

dotnet run
Question: When did I start using MongoDB?
Retrieved Context: I started using MongoDB two years ago
Answer: Two years ago.

提示

您可以添加自己的数据并替换以下部分代码,以生成对其他问题的回答:

  • var userQuestion = "When did I start using MongoDB?"

MongoDB 还提供以下开发者资源:

后退

Python 集成

在此页面上