Docs Menu
Docs Home
/ /

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를 구현합니다.

시맨틱 커널은 다양한 AI 서비스 및 플러그인을 애플리케이션과 결합할 수 있는 오픈 소스 SDK입니다. 시맨틱 커널은 RAG 를 포함한 다양한 AI 사용 사례에 사용할 수 있습니다.

MongoDB Vector Search를 시맨틱 커널과 통합하면 MongoDB 벡터 데이터베이스로 사용하고 MongoDB Vector Search를 사용하여 데이터에서 의미적으로 유사한 문서를 검색하여 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는 다음과 같은 개발자 리소스도 제공합니다.

돌아가기

Python 통합

이 페이지의 내용