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 Atlas Vector Search with Microsoft Semantic Kernel to build AI applications and implement retrieval-augmented generation (RAG). This tutorial demonstrates how to start using Atlas 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 on Atlas.

  3. Create an Atlas Vector Search index on your data.

  4. Run a semantic search query on your data.

  5. Implement RAG by using Atlas 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 Atlas Vector Search with Semantic Kernel, you can use Atlas as a vector database and use Atlas Vector Search to implement RAG by retrieving semantically similar documents from your data. To learn more about RAG, see Retrieval-Augmented Generation (RAG) with Atlas Vector Search.

To complete this tutorial, you must have the following:

  • An Atlas account with a cluster running MongoDB version 6.0.11, 7.0.2, or later (including RCs). Ensure that your IP address is included in your Atlas project's access list. To learn more, see Create a Cluster.

  • 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 Atlas cluster's SRV connection string and OpenAI API Key to your environment.

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

Note

Your connection string should use the following format:

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

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 Atlas as a vector database (also called a memory store), and load custom data into your Atlas 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("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 OpenAIClient(openAIKey)
.GetEmbeddingClient("text-embedding-ada-002")
.AsIEmbeddingGenerator();
// Instantiate Atlas 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 Atlas:

dotnet run

Tip

After running the sample code, you can view your vector embeddings and index in the Atlas UI by navigating to the semantic_kernel_db.test collection in your cluster.

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 Atlas Vector Search and Semantic Kernel. Now that you've used Atlas 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