Docs 菜单
Docs 主页
/
MongoDB Atlas
/ /

开始使用 Semantic Kernel Python 集成

在此页面上

  • 背景
  • 先决条件
  • 设置环境
  • 在 Atlas 中存储自定义数据。
  • 创建 Atlas Vector Search 索引
  • 运行向量搜索查询
  • 回答有关数据的问题
  • 后续步骤

注意

本教程使用 Semantic Kernel Python 库。有关使用 C# 库的教程,请参阅语义内核 C# 集成入门

您可以将 Atlas Vector Search 与 Microsoft Semantic Kernel 集成 构建 AI 应用程序并实施检索增强生成 (RAG)。本教程演示如何开始使用带有语义内核的Atlas Vector Search ,对数据执行语义Atlas Search并构建 RAG实施。 具体来说,您执行以下操作:

  1. 设置环境。

  2. 在 Atlas 上存储自定义数据。

  3. 在您的数据上创建一个 Atlas Vector Search 索引。

  4. 对您的数据运行语义搜索查询。

  5. 使用 Atlas Vector Search 来回答有关数据的问题,从而实现 RAG。

Semantic Kernel 是一个开源 SDK,可让您将各种 AI 服务和插件与您的应用程序相结合。 您可以将语义内核用于各种 AI 使用案例,包括RAG

通过将 Atlas Vector Search 与语义内核集成,您可以将 Atlas 用作矢量数据库,并使用 Atlas Vector Search 通过从数据中检索语义相似的文档来实现 RAG。要了解有关 RAG 的更多信息,请参阅使用 Atlas Vector Search 进行检索增强生成 (RAG)

如要完成本教程,您必须具备以下条件:

  • 一个Atlas账户,其集群运行MongoDB 6.0.11、7.0.2 或更高版本(包括 RC)。确保您的IP解决包含在Atlas项目的访问权限列表中。要学习;了解更多信息,请参阅创建集群。

  • 一个 OpenAI API 密钥。您必须拥有付费的 OpenAI 账号,该账号具有可用于 API 请求的信用额度。要了解有关注册 OpenAI 账号的更多信息,请参阅 OpenAI API 网站

  • 运行交互式 Python 笔记本(例如 Colab)的环境。

    注意

    如果使用 Colab,请确保笔记本会话的 IP 地址包含在 Atlas 项目的访问列表中。

为此教程设置环境。通过保存扩展名为 .ipynb 的文件来创建交互式Python笔记本。此 Notebook 允许您单独运行Python代码片段,并且您将使用它来运行本教程中的代码。

要设立笔记本环境,请执行以下操作:

1
  1. 在笔记本中运行以下命令,在您的环境中安装语义内核。

    pip install --quiet --upgrade semantic-kernel openai motor
  2. 运行以下代码,导入所需包:

    import getpass, openai
    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
2

运行以下代码并在出现提示时提供以下内容:

OPENAI_API_KEY = getpass.getpass("OpenAI API Key:")
ATLAS_CONNECTION_STRING = getpass.getpass("MongoDB Atlas SRV Connection String:")

注意

连接字符串应使用以下格式:

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

在本部分中,您将初始化内核,它是用于管理应用程序的服务和插件的主接口。通过内核,您可以配置 AI 服务,将 Atlas 实例化为向量数据库(也称为内存存储),并将自定义数据加载到 Atlas 集群。

要将自定义数据存储在 Atlas 中,请在笔记本中粘贴并运行以下代码片段:

1

运行以下代码以初始化内核。

kernel = sk.Kernel()
2

运行以下代码以配置本教程中使用的 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)
3

运行以下代码,将 Atlas 实例化为内存存储,并将其添加到内核中。 此代码建立与 Atlas 集群的连接并指定以下内容:

  • semantic_kernel_db 作为用于存储文档的 Atlas 数据库。

  • vector_index 作为用于运行语义Atlas Search查询的索引。

它还导入一个名为TextMemoryPlugin插件,其中提供了一群组原生函数来帮助您在内存中存储和检索文本。

mongodb_atlas_memory_store = MongoDBAtlasMemoryStore(
connection_string=ATLAS_CONNECTION_STRING,
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")
4

此代码将定义并运行一个函数,以使用某些示例文档填充 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={}

提示

运行示例代码后,您可以导航到您的集群中的semantic_kernel_db.test collection,在 Atlas 用户界面中查看向量嵌入。

注意

要创建 Atlas Vector Search 索引,您必须对 Atlas 项目具有Project Data Access Admin或更高访问权限。

要在向量存储上启用向量搜索查询,请在semantic_kernel_db.test集合上创建 Atlas Vector Search 索引。

1
  1. 如果尚未显示,请从导航栏上的 Organizations 菜单中选择包含所需项目的组织。

  2. 如果尚未显示,请从导航栏的Projects菜单中选择所需的项目。

  3. 如果尚未出现,请单击侧边栏中的 Clusters(集群)。

    会显示集群页面。

2

您可以从侧边栏、 Data Explorer 或集群详细信息页面转到 Atlas Search 页面。

  1. 在侧边栏中,单击 Services 标题下的 Atlas Search

  2. Select data source 下拉菜单中选择您的集群并单击 Go to Atlas Search

    将显示 Atlas Search 页面。

  1. 单击集群的对应 Browse Collections 按钮。

  2. 展开数据库并选择集合。

  3. 单击该集合的 Search Indexes 标签页。

    将显示 Atlas Search 页面。

  1. 单击集群的名称。

  2. 单击 Atlas Search 标签页。

    将显示 Atlas Search 页面。

3
  1. 单击 Create Search Index(连接)。

  2. Atlas Vector Search下,选择JSON Editor ,然后单击Next

  3. Database and Collection(数据库和集合)部分中找到 semantic_kernel_db 数据库,然后选择 test 集合。

  4. Index Name 字段中输入 vector_index

  5. 将默认定义替换为以下索引定义,然后单击 Next

    此索引定义用于指定在 vectorSearch 类型的索引中对以下字段建立索引:

    • embedding 字段作为向量类型。 embedding字段包含使用 OpenAI 的text-embedding-ada-002嵌入模型创建的嵌入。 索引定义指定了1536向量维度,并使用cosine来衡量相似性。

    1{
    2 "fields": [
    3 {
    4 "type": "vector",
    5 "path": "embedding",
    6 "numDimensions": 1536,
    7 "similarity": "cosine"
    8 }
    9 ]
    10}
4

此时将显示一个模态窗口,让您知道索引正在构建中。

5

构建索引大约需要一分钟时间。在构建时,Status 列显示 Initial Sync。构建完成后,Status 列显示 Active

Atlas构建索引后,您可以对数据运行向量Atlas Search查询。

在 notebook 中,运行以下代码,对字符串 What is my job title? 执行基本语义搜索。它打印最相关的文档以及介于 01 之间的相关性分数

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

本部分展示使用 Atlas Vector Search 和语义内核的RAG实施示例。 现在您已经使用Atlas 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 还提供以下开发者资源:

提示

另请参阅:

后退

语义内核 C#