참고
이 튜토리얼에서는 시맨틱 커널 Python 라이브러리를 사용합니다. C# 라이브러리를 사용하는 튜토리얼은 시맨틱 커널 C# 통합 시작하기를 참조하세요.
MongoDB Vector Search를 Microsoft 시맨틱 커널과 통합하여 AI 애플리케이션을 빌드 하고 RAG(검색 강화 생성)를 구현 수 있습니다. 이 튜토리얼에서는 시맨틱 커널과 함께 MongoDB 벡터 검색을 사용하여 데이터에 시맨틱 검색 수행하고 RAG 구현 빌드 방법을 보여 줍니다. 구체적으로 다음 조치를 수행합니다.
환경을 설정합니다.
사용자 지정 데이터를 MongoDB 에 저장합니다.
데이터에 MongoDB Vector Search 인덱스 생성합니다.
데이터에 대해 시맨틱 검색 쿼리를 실행합니다.
MongoDB Vector Search를 사용하여 데이터에 대한 질문에 답변 RAG를 구현합니다.
이 튜토리얼의 실행 가능한 버전을 Python 노트북으로 사용합니다.
배경
시맨틱 커널은 다양한 AI 서비스 및 플러그인을 애플리케이션과 결합할 수 있는 오픈 소스 SDK입니다. 시맨틱 커널은 RAG 를 포함한 다양한 AI 사용 사례에 사용할 수 있습니다.
MongoDB Vector Search를 시맨틱 커널과 통합하면 MongoDB 벡터 데이터베이스로 사용하고 MongoDB Vector Search를 사용하여 데이터에서 의미적으로 유사한 문서를 검색하여 RAG 를 구현. RAG에 대해 자세히 학습 MongoDB 사용한 검색-증강 생성(RAG)을 참조하세요.
전제 조건
이 튜토리얼을 완료하려면 다음 조건을 충족해야 합니다.
다음 MongoDB cluster 유형 중 하나입니다.
MongoDB 버전 6.0.11을 실행하는 Atlas 클러스터 7.0.2 또는 그 이상. IP 주소가 Atlas 프로젝트의 액세스 목록에 포함되어 있는지 확인하세요.
Atlas CLI 사용하여 생성된 로컬 Atlas 배포서버 입니다. 자세히 학습 로컬 Atlas 배포 만들기를 참조하세요.
검색 및 벡터 검색이 설치된 MongoDB Community 또는 Enterprise 클러스터.
OpenAI API 키입니다. API 요청에 사용할 수 있는 크레딧이 있는 OpenAI 계정이 있어야 합니다. OpenAI 계정 등록에 대해 자세히 학습하려면 OpenAI API 웹사이트를 참조하세요.
Colab과같은 대화형 Python 노트북을 실행 수 있는 환경입니다.
환경 설정
이 튜토리얼의 환경을 설정합니다. 확장자가 .ipynb 인 파일 저장하여 대화형 Python 노트북을 만듭니다. 이 노트북을 사용하면 Python 코드 스니펫을 개별적으로 실행 수 있으며, 이 튜토리얼에서는 이를 사용하여 코드를 실행 .
노트북 환경을 설정하다 하려면 다음을 수행합니다.
종속성을 설치하고 가져옵니다.
노트북에서 다음 명령을 실행하여 환경에 시맨틱 커널을 설치합니다.
pip install --quiet --upgrade semantic-kernel openai motor 다음 코드를 실행하여 필요한 패키지를 가져옵니다.
import semantic_kernel as sk from semantic_kernel.connectors.ai.open_ai import (OpenAIChatCompletion, OpenAITextEmbedding) from semantic_kernel.connectors.memory.mongodb_atlas import MongoDBAtlasMemoryStore from semantic_kernel.core_plugins.text_memory_plugin import TextMemoryPlugin from semantic_kernel.memory.semantic_text_memory import SemanticTextMemory from semantic_kernel.prompt_template.input_variable import InputVariable from semantic_kernel.prompt_template.prompt_template_config import PromptTemplateConfig from pymongo import MongoClient from pymongo.operations import SearchIndexModel
환경 변수를 정의합니다.
다음 코드를 실행하고 자리 표시자를 다음 값으로 대체합니다.
사용자의 OpenAI API 키.
MongoDB 클러스터의 연결 문자열.
참고
<connection-string>을 Atlas 클러스터 또는 로컬 Atlas 배포서버의 연결 문자열로 교체합니다.
연결 문자열은 다음 형식을 사용해야 합니다.
mongodb+srv://<db_username>:<db_password>@<clusterName>.<hostname>.mongodb.net
자세한 학습은 드라이버를 통해 클러스터에 연결을 참조하세요.
연결 문자열은 다음 형식을 사용해야 합니다.
mongodb://localhost:<port-number>/?directConnection=true
학습 내용은 연결 문자열을 참조하세요.
MongoDB 에 사용자 지정 데이터 저장
이 섹션에서는 애플리케이션의 서비스 및 플러그인을 관리 데 사용되는 기본 인터페이스인 커널을 초기화합니다. 커널을 통해 AI 서비스를 구성하고, MongoDB 벡터 데이터베이스 (메모리 저장 라고도 함)로 인스턴스화하고, 사용자 지정 데이터를 MongoDB cluster 에 로드합니다.
사용자 지정 데이터를 MongoDB 에 저장 하려면 노트북에 다음 코드 스니펫을 붙여넣고 실행 .
커널에 AI 서비스를 추가합니다.
다음 코드를 실행하여 이 튜토리얼에 사용된 OpenAI 임베딩 모델 및 채팅 모델을 구성하고 이러한 서비스를 커널에 추가합니다. 이 코드는 다음을 지정합니다:
텍스트를 벡터 임베딩으로 변환하는 데 사용되는 임베딩 모델인 OpenAI의
text-embedding-ada-002.응답 생성에 사용되는 채팅 모델인 OpenAI의
gpt-3.5-turbo.
chat_service = OpenAIChatCompletion( service_id="chat", ai_model_id="gpt-3.5-turbo", api_key=OPENAI_API_KEY ) embedding_service = OpenAITextEmbedding( ai_model_id="text-embedding-ada-002", api_key=OPENAI_API_KEY ) kernel.add_service(chat_service) kernel.add_service(embedding_service)
Atlas를 메모리 저장소로 인스턴스화합니다.
다음 코드를 실행하여 Atlas를 메모리 저장소로 인스턴스화하고 커널에 추가합니다. 이 코드는 Atlas 클러스터에 대한 연결을 설정하고 다음을 지정합니다.
semantic_kernel_db- 문서를 저장하는 데 사용되는 Atlas 데이터베이스.vector_index시맨틱 Atlas Search 쿼리를 실행하는 데 사용되는 인덱스로 사용됩니다.
또한 메모리에 텍스트를 저장하고 조회하는 데 도움이 되는 네이티브 함수 그룹을 제공하는 TextMemoryPlugin이라는 플러그인을 가져옵니다.
mongodb_atlas_memory_store = MongoDBAtlasMemoryStore( connection_string=MONGODB_URI, database_name="semantic_kernel_db", index_name="vector_index" ) memory = SemanticTextMemory( storage=mongodb_atlas_memory_store, embeddings_generator=embedding_service ) kernel.add_plugin(TextMemoryPlugin(memory), "TextMemoryPlugin")
Atlas cluster에 샘플 데이터를 로드합니다.
이 코드는 semantic_kernel_db.test 컬렉션에 샘플 문서를 채우기 위해 함수를 정의하고 실행합니다. 이러한 문서에는 LLM이 원래 접근할 수 없었던 개인화된 데이터가 포함되어 있습니다.
async def populate_memory(kernel: sk.Kernel) -> None: await memory.save_information( collection="test", id="1", text="I am a developer" ) await memory.save_information( collection="test", id="2", text="I started using MongoDB two years ago" ) await memory.save_information( collection="test", id="3", text="I'm using MongoDB Vector Search with Semantic Kernel to implement RAG" ) await memory.save_information( collection="test", id="4", text="I like coffee" ) print("Populating memory...") await populate_memory(kernel) print(kernel)
Populating memory... plugins=KernelPluginCollection(plugins={'TextMemoryPlugin': KernelPlugin(name='TextMemoryPlugin', description=None, functions={'recall': KernelFunctionFromMethod(metadata=KernelFunctionMetadata(name='recall', plugin_name='TextMemoryPlugin', description='Recall a fact from the long term memory', parameters=[KernelParameterMetadata(name='ask', description='The information to retrieve', default_value=None, type_='str', is_required=True, type_object=<class 'str'>), KernelParameterMetadata(name='collection', description='The collection to search for information.', default_value='generic', type_='str', is_required=False, type_object=<class 'str'>), KernelParameterMetadata(name='relevance', description='The relevance score, from 0.0 to 1.0; 1.0 means perfect match', default_value=0.75, type_='float', is_required=False, type_object=<class 'float'>), KernelParameterMetadata(name='limit', description='The maximum number of relevant memories to recall.', default_value=1, type_='int', is_required=False, type_object=<class 'int'>)], is_prompt=False, is_asynchronous=True, return_parameter=KernelParameterMetadata(name='return', description='', default_value=None, type_='str', is_required=True, type_object=None)), method=<bound method TextMemoryPlugin.recall of TextMemoryPlugin(memory=SemanticTextMemory())>, stream_method=None), 'save': KernelFunctionFromMethod(metadata=KernelFunctionMetadata(name='save', plugin_name='TextMemoryPlugin', description='Save information to semantic memory', parameters=[KernelParameterMetadata(name='text', description='The information to save.', default_value=None, type_='str', is_required=True, type_object=<class 'str'>), KernelParameterMetadata(name='key', description='The unique key to associate with the information.', default_value=None, type_='str', is_required=True, type_object=<class 'str'>), KernelParameterMetadata(name='collection', description='The collection to save the information.', default_value='generic', type_='str', is_required=False, type_object=<class 'str'>)], is_prompt=False, is_asynchronous=True, return_parameter=KernelParameterMetadata(name='return', description='', default_value=None, type_='', is_required=True, type_object=None)), method=<bound method TextMemoryPlugin.save of TextMemoryPlugin(memory=SemanticTextMemory())>, stream_method=None)})}) services={'chat': OpenAIChatCompletion(ai_model_id='gpt-3.5-turbo', service_id='chat', client=<openai.AsyncOpenAI object at 0x7999971c8fa0>, ai_model_type=<OpenAIModelTypes.CHAT: 'chat'>, prompt_tokens=0, completion_tokens=0, total_tokens=0), 'text-embedding-ada-002': OpenAITextEmbedding(ai_model_id='text-embedding-ada-002', service_id='text-embedding-ada-002', client=<openai.AsyncOpenAI object at 0x7999971c8fd0>, ai_model_type=<OpenAIModelTypes.EMBEDDING: 'embedding'>, prompt_tokens=32, completion_tokens=0, total_tokens=32)} ai_service_selector=<semantic_kernel.services.ai_service_selector.AIServiceSelector object at 0x7999971cad70> retry_mechanism=PassThroughWithoutRetry() function_invoking_handlers={} function_invoked_handlers={}
팁
샘플 코드를 실행 후 Atlas 사용하는 경우 semantic_kernel_db.test Atlas UI 의 네임스페이스 로이동하여 벡터 임베딩을 확인할 수 있습니다.
MongoDB Vector Search 인덱스 만들기
벡터 저장 에서 벡터 검색 쿼리를 활성화 하려면 노트북에서 다음 코드를 실행 semantic_kernel_db.test 컬렉션 에 MongoDB Vector Search 인덱스 만듭니다.
# Connect to your MongoDB cluster and specify the collection client = MongoClient(MONGODB_URI) collection = client["semantic_kernel_db"]["test"] # Create your index model, then create the search index search_index_model = SearchIndexModel( definition={ "fields": [ { "type": "vector", "path": "embedding", "numDimensions": 1536, "similarity": "cosine" } ] }, name="vector_index", type="vectorSearch" ) collection.create_search_index(model=search_index_model)
인덱스 정의는 embedding 필드를 벡터 유형으로 인덱싱합니다. embedding 필드에는 OpenAI의 text-embedding-ada-002 임베딩 모델을 사용하여 생성된 임베딩이 포함되어 있습니다. 인덱스 정의는 1536 벡터 차원을 지정하고 cosine을 사용하여 유사성을 측정합니다.
Vector Search 쿼리 실행
MongoDB 인덱스 빌드하면 데이터에 대해 벡터 검색 쿼리를 실행 수 있습니다.
노트북에서 다음 코드를 실행하여 문자열 What is my job title?에 대한 기본 시맨틱 검색을 수행합니다. 가장 관련성 있는 문서와 0 및 1 사이의 관련성 점수를 출력합니다.
result = await memory.search("test", "What is my job title?") print(f"Retrieved document: {result[0].text}, {result[0].relevance}")
Retrieved document: I am a developer, 0.8991971015930176
데이터에 대한 질문에 답변
이 섹션에서는 MongoDB 벡터 검색 및 시맨틱 커널을 사용한 RAG 구현 예시 보여줍니다. 이제 MongoDB Vector Search를 사용하여 의미적으로 유사한 문서를 조회 했으므로, 다음 코드 예시 실행 LLM이 해당 문서를 기반으로 질문에 답변 하도록 프롬프트를 표시합니다.
다음 코드는 조회된 문서 쿼리 의 컨텍스트로 사용하도록 LLM에 지시하는 프롬프트를 정의합니다. 이 예시 에서는 샘플 쿼리 When did I start using MongoDB?를 사용하여 LLM에 프롬프트를 표시합니다. 사용자 지정 데이터로 LLM의 지식 기반을 보강했기 때문에 채팅 모델은 보다 정확하고 상황을 인식하는 응답을 생성할 수 있습니다.
service_id = "chat" settings = kernel.get_service(service_id).instantiate_prompt_execution_settings( service_id=service_id ) prompt_template = """ Answer the following question based on the given context. Question: {{$input}} Context: {{$context}} """ chat_prompt_template_config = PromptTemplateConfig( execution_settings=settings, input_variables=[ InputVariable(name="input"), InputVariable(name="context") ], template=prompt_template ) prompt = kernel.add_function( function_name="RAG", plugin_name="TextMemoryPlugin", prompt_template_config=chat_prompt_template_config, ) question = "When did I start using MongoDB?" results = await memory.search("test", question) retrieved_document = results[0].text answer = await prompt.invoke( kernel=kernel, input=question, context=retrieved_document ) print(answer)
You started using MongoDB two years ago.
다음 단계
MongoDB는 다음과 같은 개발자 리소스도 제공합니다.