AI 에이전트의 경우: 문서 인덱스는 https://www.mongodb.com/ko-kr/docs/llms.txt에서 사용할 수 있으며, 모든 페이지의 마크다운 버전은 어떤 URL 경로에 .md를 추가하여 사용할 수 있습니다.
Docs Menu

Semantic Kernel C# 통합 시작하기

참고

이 튜토리얼에서는 시맨틱 커널 C# 라이브러리를 사용합니다. Python 라이브러리를 사용하는 튜토리얼은 시맨틱 커널 Python 통합 시작하기를 참조하세요.

MongoDB Vector Search를 Microsoft 시맨틱 커널과 통합하여 AI 애플리케이션을 빌드 하고 RAG(검색 강화 생성)를 구현 수 있습니다. 이 튜토리얼에서는 시맨틱 커널과 함께 MongoDB 벡터 검색을 사용하여 데이터에서 시맨틱 검색 수행하고 RAG 구현 빌드 방법을 보여 줍니다. 구체적으로 다음 조치를 수행합니다.

  1. 환경을 설정합니다.

  2. 사용자 지정 데이터를 MongoDB 에 저장합니다.

  3. 데이터에 MongoDB Vector Search 인덱스 생성합니다.

  4. 데이터에 대해 시맨틱 검색 쿼리를 실행합니다.

  5. MongoDB Vector Search를 사용하여 데이터에 대한 질문에 답변 RAG를 구현합니다.

Semantic Kernel은 다양한 AI 서비스와 플러그인을 애플리케이션과 결합할 수 있게 해주는 오픈 소스 SDK입니다. RAG를 포함한 다양한 AI 사용 사례에 Semantic Kernel을 사용할 수 있습니다.

MongoDB Vector Search를 시맨틱 커널과 통합하면 MongoDB 벡터 데이터베이스 로 사용하고 MongoDB Vector Search를 사용하여 데이터에서 의미적으로 유사한 문서를 검색하여 RAG 를 구현 . RAG에 대해 자세히 학습하려면 RAG, MongoDB 사용한 검색-증강 생성(RAG)을 참조하세요.

이 튜토리얼을 완료하려면 다음 조건을 충족해야 합니다.

먼저 이 튜토리얼을 진행하려면 환경을 설정해야 합니다. 환경을 설정하려면 다음 단계를 완료하세요.

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 cluster의 SRV 연결 문자열 과 OpenAI API 키를 환경에 추가합니다.

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

참고

<connection-string>을 Atlas 클러스터 또는 로컬 Atlas 배포서버의 연결 문자열로 교체합니다.

연결 문자열은 다음 형식을 사용해야 합니다.

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

자세한 학습은 클라이언트 라이브러리를 통해 클러스터에 연결을 참조하세요.

연결 문자열은 다음 형식을 사용해야 합니다.

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

학습 내용은 연결 문자열을 참조하세요.

이 섹션에서는 애플리케이션의 서비스 및 플러그인을 관리 데 사용되는 기본 인터페이스인 커널을 초기화합니다. 커널을 통해 AI 서비스를 구성하고, MongoDB 벡터 데이터베이스 (메모리 저장 라고도 함)로 인스턴스화하고, 사용자 지정 데이터를 MongoDB cluster 에 로드합니다.

다음 코드를 복사하여 애플리케이션의 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: 문자열 항목을 가져와서 문자열에 대한 임베딩을 생성하고, 해당 레코드를 만든 다음 해당 레코드를 Atlas cluster 의 컬렉션 에 업서트 메서드입니다.

  • MongoDB 컬렉션 에 저장된 문서의 구조를 정의하는 DataModel 클래스를 만듭니다.

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 사용하는 경우 semantic_kernel_db.test Atlas UI 의 네임스페이스 로이동하여 벡터 임베딩을 확인할 수 있습니다.

벡터 임베딩을 만든 후에는 데이터에 대해 벡터 검색 쿼리를 실행 수 있습니다.

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 벡터 검색 및 시맨틱 커널을 사용한 RAG 구현 예시 보여줍니다. 이제 MongoDB Vector Search를 사용하여 의미적으로 유사한 문서를 조회 했으므로, Program.csProgram 클래스 끝에 다음 코드 예시 붙여넣어 LLM 이 해당 문서를 기반으로 질문에 답변 하도록 프롬프트를 표시합니다.

이 코드는 다음 작업을 수행합니다.

  • OpenAI의 gpt-4o 를 채팅 모델로 사용하여 새 커널을 생성하여 응답을 생성합니다.

  • 벡터 저장 사용하여 새 텍스트 검색 인스턴스 만듭니다.

  • 채팅 모델에 질문할 질문을 정의하고 벡터 저장 의 컨텍스트를 보유하기 위해 변수 retrievedContext 를 초기화합니다.

  • 질문 When did I start using MongoDB? 에 대해 recordCollection 에서 시맨틱 검색 수행하고 가장 관련성이 높은 검색 결과를 반환합니다.

  • 검색된 컨텍스트를 기반으로만 질문에 답변 하도록 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는 다음과 같은 개발자 리소스도 제공합니다.