Project Icon

mongodb-demo

LlamaIndex和MongoDB构建智能问答系统实践

本项目展示了利用LlamaIndex和MongoDB构建智能问答系统的完整流程。从数据导入到索引创建,再到API开发和前端部署,涵盖了系统构建的各个环节。结合OpenAI语言模型和MongoDB向量搜索,实现了对特定数据集的复杂查询和智能回答。项目提供了一个端到端的工作流程,可供开发者参考创建AI驱动的应用。

使用MongoDB、Flask和Next.js的LlamaIndex检索增强生成

使用MongoDB、Flask和Next.js

查看此演示运行效果!

这是什么?

LlamaIndex是一个开源框架,让您可以构建由大型语言模型(LLMs)如OpenAI的GPT-4驱动的AI应用程序。本应用程序展示了如何从零开始到完全部署的Web应用程序的整个过程。我们将向您展示如何运行此仓库中的所有内容,然后开始根据自己的需求进行定制。

在这个例子中,我们将使用MongoDB作为数据存储和向量存储。我们的后端将是由Flask驱动的Python API,前端将是用Next.js编写的JavaScript Web应用。

该应用将加载一系列推文(从Twitter存档导出加载),然后对其进行索引以回答关于作者及其观点的问题。

我们将要做什么

此演示的基本步骤是:

  • 将JSON文件中的数据导入MongoDB数据库(如果您已经在Mongo中有数据,可以跳过此步骤)
  • 使用LlamaIndex对数据进行索引。这将在底层使用OpenAI的gpt-3.5-turbo,并将您的文本转换为向量嵌入,因此您需要一个OpenAI API密钥,根据数据量的多少,这可能需要一些时间
  • 将嵌入数据存回MongoDB。LlamaIndex将自动为您完成这一步
  • 在MongoDB中创建向量搜索索引。这是您需要在MongoDB UI中手动执行的步骤
  • 查询数据!这将证明数据现在是可查询的。然后您可能想在此基础上构建一个应用程序
  • 设置一个Python Flask API来回答关于数据的问题,托管在Render
  • 设置一个JavaScript编写的Next.js前端,同样托管在Render上。这将接受用户问题,将它们传递给API,并显示结果

说明

您可以将这些说明作为教程,从头开始重建应用程序,或者克隆仓库并将其用作模板。

开始之前

我们假设您已安装了当前版本的Python(3.11.6或更高版本),以及用于前端的Node.js(20版或更高版本)和用于源代码控制的git。

获取代码

首先克隆此仓库

git clone git@github.com:run-llama/mongodb-demo.git

注册MongoDB Atlas

我们将使用MongoDB的托管数据库服务MongoDB Atlas。您可以免费注册并获得一个小型免费托管集群:

MongoDB Atlas注册

注册过程将引导您创建集群并确保其配置为您可以访问。一旦集群创建完成,选择"连接",然后选择"连接到您的应用程序"。选择Python,您将看到一个类似这样的连接字符串:

MongoDB Atlas连接字符串

设置环境变量

复制连接字符串(确保包含您的密码)并将其放入仓库根目录下名为.env的文件中。它应该看起来像这样:

MONGODB_URI=mongodb+srv://seldo:xxxxxxxxxxx@llamaindexdemocluster.xfrdhpz.mongodb.net/?retryWrites=true&w=majority

您还需要为数据库和存储推文的集合选择名称,并将它们包含在.env文件中。它们可以是任何字符串,但我们使用的是:

MONGODB_DATABASE=tiny_tweets_db
MONGODB_COLLECTION=tiny_tweets_collection

设置Python虚拟环境并安装依赖

为避免与其他Python依赖冲突,创建一个Python虚拟环境来工作是个好主意。有很多方法可以做到这一点,但我们使用的方法是在仓库根目录下运行以下命令:

python3 -m venv .venv
source .venv/bin/activate

现在我们将使用pip一次性安装所有需要的依赖:

pip install -r requirements.txt

这将安装MongoDB驱动程序、LlamaIndex本身以及一些实用程序库。

将推文导入MongoDB

现在您已准备好将我们预先准备的数据集导入Mongo。这是文件tinytweets.json,包含了大约1000条来自@seldo在2019年中期的Twitter推文。设置好环境后,您可以通过运行以下命令来完成导入:

python 1_import.py

如果您感兴趣,代码如下。如果您不想使用推文,可以用任何其他JSON对象数组替换json_file,但您需要稍后修改一些代码以确保正确的字段被索引。这里没有LlamaIndex特定的代码;您可以用任何想要的方式将数据加载到Mongo中。

json_file = 'tinytweets.json'

# 从本地.env文件加载环境变量
from dotenv import load_dotenv
load_dotenv()

import os
import json
from pymongo.mongo_client import MongoClient
from pymongo.server_api import ServerApi

# 从本地文件加载推文
with open(json_file, 'r') as f:
    tweets = json.load(f)

# 创建新客户端并连接到服务器
client = MongoClient(os.getenv('MONGODB_URI'), server_api=ServerApi('1'))
db = client[os.getenv("MONGODB_DATABASE")]
collection = db[os.getenv("MONGODB_COLLECTION")]

# 将推文插入mongo
collection.insert_many(tweets)

加载和索引数据

现在我们准备索引数据。为此,LlamaIndex将从Mongo中提取文本,将其分割成块,然后将这些块发送给OpenAI转换为向量嵌入。然后,嵌入将存储在Mongo的新集合中。这个过程可能需要一些时间,取决于您有多少文本,但好消息是一旦完成,您将能够快速查询,而无需重新索引。

我们将使用OpenAI进行嵌入,所以现在是时候生成OpenAI API密钥(如果您还没有的话),并将其添加到您的.env文件中,如下所示:

OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

您还需要为存储嵌入的新集合选择一个名称,并将其添加到.env文件中,同时还要添加向量搜索索引的名称(我们将在下一步创建这个索引,在您索引数据之后):

MONGODB_VECTORS=tiny_tweets_vectors
MONGODB_VECTOR_INDEX=tiny_tweets_vector_index

如果您正在索引我们提供的推文数据,您现在就可以开始了:

python 2_load_and_index.py

您可以查看此脚本的完整源代码,但让我们强调几个重要部分:

query_dict = {}
reader = SimpleMongoReader(uri=os.getenv("MONGODB_URI"))
documents = reader.load_data(
    os.getenv("MONGODB_DATABASE"),
    os.getenv("MONGODB_COLLECTION"),
    field_names=["full_text"],
    query_dict=query_dict
)

在这里,您创建了一个Reader,它从指定的集合和数据库中加载数据。它在每个对象的特定键集中查找文本。在这种情况下,我们只给了它一个键:"full_text"。最后一个参数是一个mongo 查询文档,这是一个JSON对象,您可以用它来将对象过滤到一个子集。我们将其留空,因为我们想要集合中的所有推文。

# 创建新客户端并连接到服务器
client = MongoClient(os.getenv("MONGODB_URI"), server_api=ServerApi('1'))

# 创建Atlas作为向量存储
store = MongoDBAtlasVectorSearch(
    client,
    db_name=os.getenv('MONGODB_DATABASE'),
    collection_name=os.getenv('MONGODB_VECTORS'),
    index_name=os.getenv('MONGODB_VECTOR_INDEX')
)

现在您正在为Mongo创建一个向量搜索客户端。除了MongoDB客户端对象外,您还要再次告诉它所有内容所在的数据库。这次您给它提供了存储向量嵌入的集合名称,以及下一步将创建的向量搜索索引的名称。

这个过程可能需要一段时间,所以当我们开始时,我们将show_progress参数设置为True,这会打印一个方便的小进度条:

storage_context = StorageContext.from_defaults(vector_store=store)
index = VectorStoreIndex.from_documents(
    documents, storage_context=storage_context,
    show_progress=True
)

创建向量搜索索引

如果一切顺利,您现在应该能够登录Mongo Atlas UI,并在数据库中看到两个集合:原始数据在tiny_tweets_collection中,向量嵌入在tiny_tweets_vectors中。

MongoDB Atlas集合

现在是时候创建向量搜索索引,以便您可以查询数据。首先,点击Search标签,然后点击"Create Search Index":

MongoDB Atlas创建搜索索引

目前还不能使用可视化编辑器创建向量搜索索引,所以选择JSON编辑器:

MongoDB Atlas JSON编辑器

现在在"database and collection"下选择tiny_tweets_db,然后在其中选择tiny_tweets_vectors。然后在"Index name"下输入tiny_tweets_vector_index(或您在.env中为MONGODB_VECTOR_INDEX设置的任何值)。在下面,您需要输入这个JSON对象:

{
  "fields": [
    {
      "numDimensions": 1536,
      "path": "embedding",
      "similarity": "cosine",
      "type": "vector"
    }
  ]
}

这告诉Mongo,每个文档(在tiny_tweets_vectors集合中)的embedding字段是一个1536维的向量(这是OpenAI使用的嵌入大小),并且我们想要使用余弦相似度来比较向量。除非您想使用完全不同于OpenAI的LLM,否则您不需要太关心这些值。 UI 会要求您检查并确认您的选择,然后您需要等待一两分钟,让它生成索引。如果一切顺利,您应该会看到类似这样的屏幕:

MongoDB Atlas 索引已创建

现在您已经准备好查询您的数据了!

运行测试查询

您可以通过运行以下命令来实现:

python 3_query.py

这会像 2_load_and_index.py 一样设置与 Atlas 的连接,然后创建一个查询引擎并对其运行查询:

query_engine = index.as_query_engine(similarity_top_k=20)
response = query_engine.query("作者对 Web 框架有什么看法?")
print(response)

如果一切正常,您应该会得到一个关于 Web 框架的细致见解。

设置新的仓库

现在我们有了一种使用 LLM 快速查询数据的方法。但我们需要一个应用程序!为此,我们将设置一个 Python Flask API 作为后端,一个 JavaScript Next.js 应用作为前端。我们将把它们都部署到 Render,为此我们需要将它们放在一个 GitHub 仓库中。所以让我们来做这个:

  1. 创建一个新的公开 GitHub 仓库
  2. 将它克隆到您的本地机器
  3. 将此仓库中的所有文件复制到新仓库(确保不包含 .git 文件夹)
  4. 提交并推送文件到 GitHub

在本教程的其余部分,我们假设您正在您刚刚创建的文件夹中工作,该文件夹与您控制的仓库相关联。

运行 Flask API

创建 Flask 应用的细节超出了本教程的范围,但您可以在仓库的 flask_app 中找到一个已经设置好的应用。它像我们在 3_query.py 中那样设置 Mongo Atlas 客户端,并有一个真正的方法 process_form,它接受一个 query 参数:

@app.route('/process_form', methods=['POST'])
@cross_origin()
def process_form():
    query = request.form.get('query')
    if query is not None:
        # 这里我们自定义了每次查询返回的文档数量为 20,因为推文非常短
        query_engine = index.as_query_engine(similarity_top_k=20)
        response = query_engine.query(query)
        return jsonify({"response": str(response)})
    else:
        return jsonify({"error": "缺少 query 字段"}), 400

@cross_origin() 装饰器是必要的,以允许前端向 API 发出请求。)

您可以通过运行以下命令在本地运行它:

flask run

您可以通过在浏览器中访问 http://127.0.0.1:5000 来检查它是否正在运行。您应该会得到一个 "Hello, world!" 响应。

将 Flask API 部署到 Render

设置 Render 账户(我们建议使用您的 GitHub 账户登录,以简化操作)并创建一个新的 Web 服务:

  1. 选择 "从 GitHub 仓库构建和部署",然后选择您上面创建的仓库。
  2. 给服务一个唯一的名称
  3. 将根目录设置为 flask_app
  4. 将运行时设置为 Python 3
  5. 选择免费套餐

重要:设置 PYTHON_VERSION。您的第一次部署会失败,因为一些包无法找到,要解决这个问题,请将您的 Python 版本设置为与您本地使用的版本相同:

  1. 转到 "Environment"
  2. 选择 "Add environment variable"
  3. key 设置为 PYTHON_VERSION,值设置为 3.11.6(或您本地使用的任何版本)
  4. 点击 "save changes"
  5. 转到右上角的 "Deploy" 按钮,选择 "deploy latest commit"。现在应该可以成功部署了。

将您的 .env 环境变量添加到 Render

以与设置 PYTHON_VERSION 相同的方式,您现在应该在 Render 环境中设置 .env 文件中的所有其他环境变量。您的代码需要知道在哪里连接 Mongo 等。所以它最终应该看起来像这样:

Render 环境变量

将您的应用 IP 添加到 MongoDB Atlas

为了允许您的 API 连接到 MongoDB,您需要将其 IP 地址添加到 Mongo 允许连接的 IP 列表中。您可以在 Render 右上角的 "Connect" 按钮中找到这些 IP。

Render IPs

转到 MongoDB 的 UI,从左侧菜单的 "Security" 下选择 "Network Access"。点击 "Add IP address" 三次,每次添加 Render 提供的一个 IP。

完成所有这些后,您的 API 现在应该已经启动并运行,并且能够连接到 MongoDB。是时候构建前端了!

运行 Next.js 应用

就像 Flask 应用一样,我们已经为您完成了繁重的工作,您可以在 next_app 中找到该应用。要在本地运行它,请在 Next 应用的根目录下运行以下命令:

npm install
npm run dev

这将在 http://127.0.0.1:3000 上给您一个本地服务器。如果您已经运行了 Flask API,您应该能够运行查询了!

将 Next.js 应用部署到 Render

就像 Flask 应用一样,我们将在免费计划上将 Next.js 应用部署到 Render。步骤非常相似:

  1. 选择 "从 GitHub 仓库构建和部署",然后选择您上面创建的仓库。
  2. 给服务一个唯一的名称
  3. 将根目录设置为 next_app
  4. 将运行时设置为 Node.js
  5. 选择免费套餐

为 Next.js 设置环境变量

就像 Python 一样,您需要设置一个名为 NODE_VERSION 的环境变量,将其设置为 20,并重新构建您的第一次部署。

您还需要告诉它在哪里找到 Flask API。为此,创建一个名为 NEXT_PUBLIC_API_HOST 的环境变量,并将其设置为 Render 上 Flask API 的主机名(在我们的例子中,是 https://mongodb-demo-zpxu.onrender.com/)。

您不需要设置任何其他环境变量,只有您的 Flask API 需要知道如何连接到 Mongo。

重新部署您的 Next.js 应用。

庆祝!

如果一切顺利,您现在应该有一个像我们一样的演示应用了!您可以开始根据您的用例进行自定义了。

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号