Docs Menu
Docs Home
/
Atlas
/ / /

Get Started with the Semantic Kernel C# Integration

Note

This tutorial uses the Semantic Kernel C# library. For a tutorial that uses the Python library see Get Started with the Semantic Kernel Python Integration.

You can integrate MongoDB Vector Search with Microsoft Semantic Kernel to build AI applications and implement retrieval-augmented generation (RAG). This tutorial demonstrates how to start using MongoDB Vector Search with Semantic Kernel to perform semantic search on your data and build a RAG implementation. Specifically, you perform the following actions:

  1. Set up the environment.

  2. Store custom data in MongoDB.

  3. Create a MongoDB Vector Search index on your data.

  4. Run a semantic search query on your data.

  5. Implement RAG by using MongoDB Vector Search to answer questions on your data.

Semantic Kernel is an open-source SDK that allows you to combine various AI services and plugins with your applications. You can use Semantic Kernel for a variety of AI use cases, including RAG.

By integrating MongoDB Vector Search with Semantic Kernel, you can use MongoDB as a vector database and use MongoDB Vector Search to implement RAG by retrieving semantically similar documents from your data. To learn more about RAG, see Retrieval-Augmented Generation (RAG) with MongoDB.

To complete this tutorial, you must have the following:

  • One of the following MongoDB cluster types:

  • An OpenAI API Key. You must have an OpenAI account with credits available for API requests. To learn more about registering an OpenAI account, see the OpenAI API website.

  • A terminal and code editor to run your .NET application.

  • C#/.NET installed.

You must first set up the environment for this tutorial. To set up your environment, complete the following steps.

1

Run the following commands in your terminal to create a new directory named sk-mongodb and initialize your application:

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

In your terminal, run the following commands to install the packages for this tutorial.

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

In your terminal, run the following commands to add your MongoDB cluster's SRV connection string and OpenAI API Key to your environment.

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

Note

Replace <connection-string> with the connection string for your Atlas cluster or local Atlas deployment.

Your connection string should use the following format:

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

To learn more, see Connect to a Cluster via Drivers.

Your connection string should use the following format:

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

To learn more, see Connection Strings.

In this section, you initialize the kernel, which is the main interface used to manage your application's services and plugins. Through the kernel, you configure your AI services, instantiate MongoDB as a vector database (also called a memory store), and load custom data into your MongoDB cluster.

Copy and paste the following code into your application's Program.cs file.

This code performs the following actions:

  • Imports Semantic Kernel and all the required packages.

  • Connects to your Atlas cluster by retrieving your SRV connection string from the environment.

  • Retrieves your OpenAI API key from the environment and creates an instance of OpenAI's text-embedding-ada-002 embedding model.

  • Instantiates Atlas as a memory store and specifies the following parameters:

    • semantic_kernel_db.records as the collection to store the documents.

    • vector_index as the index to use for querying the memory store.

  • Populates the semantic_kernel_db.records collection with sample documents by calling the CreateCollectionFromListAsync method.

  • Defines a variable recordCollection containing the semantic_kernel_db.records collection.

  • Creates two helper methods to help store and retrieve text in memory:

    • CreateRecord: A factory to create a new DataModel object.

    • CreateCollectionFromListAsync: A method to take string entries, generate embeddings for the strings, create corresponding records, and then upsert those records into a collection in your Atlas cluster.

  • Creates a DataModel class that defines the structure of documents stored in the MongoDB collection.

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; }
}
}

Save the file, then run the following command to load your data into MongoDB:

dotnet run

Tip

After running the sample code, if you're using Atlas, you can verify your vector embeddings by navigating to the semantic_kernel_db.test namespace in the Atlas UI.

Once you've created your vector embeddings, you can run vector search queries on your data.

At the end of the Program class in your Program.cs file, add the following code to perform a basic semantic search for the string What is my job title?. It prints the most relevant document.

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.");

Save the file, then run the following command to see the results of the semantic search:

dotnet run
Answer: I am a developer
Search completed.

This section shows an example RAG implementation with MongoDB Vector Search and Semantic Kernel. Now that you've used MongoDB Vector Search to retrieve semantically similar documents, paste the following code example at the end of the Program class in your Program.cs to prompt the LLM to answer questions based on those documents.

This code performs the following actions:

  • Creates a new kernel using OpenAI's gpt-4o as the chat model to generate responses.

  • Creates a new text search instance using the vector store.

  • Defines a question to ask the chat model and initializes the variable retrievedContext to hold context from the vector store.

  • Performs a semantic search in the recordCollection for the question When did I start using MongoDB? and returns the most relevant search result.

  • Builds a prompt template that instructs the AI model to answer the question based only on the retrieved context.

  • Creates a function named ragFunction from the chat prompt using the kernel's CreateFunctionFromPrompt function.

  • Prepares arguments for the RAG prompt by creating a new object to hold the question and context.

  • Calls the kernel's InvokeAsync function to generate a response from the chat model using the following parameters:

    • The ragFunction that configures the prompt template.

    • The ragArguments that contains the question and context.

  • Prints the question and generated response.

// 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 ---

Save the file, then run the following command to generate a response:

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

Tip

You can add your own data and replace the following part of the code to generate responses on a different question:

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

MongoDB also provides the following developer resources:

Back

Python Integration

On this page