查看此演示运行效果!
LlamaIndex是一个开源框架,让您可以构建由大型语言模型(LLMs)如OpenAI的GPT-4驱动的AI应用程序。本应用程序展示了如何从零开始到完全部署的Web应用程序的整个过程。我们将向您展示如何运行此仓库中的所有内容,然后开始根据自己的需求进行定制。
在这个例子中,我们将使用MongoDB作为数据存储和向量存储。我们的后端将是由Flask驱动的Python API,前端将是用Next.js编写的JavaScript Web应用。
该应用将加载一系列推文(从Twitter存档导出加载),然后对其进行索引以回答关于作者及其观点的问题。
此演示的基本步骤是:
您可以将这些说明作为教程,从头开始重建应用程序,或者克隆仓库并将其用作模板。
我们假设您已安装了当前版本的Python(3.11.6或更高版本),以及用于前端的Node.js(20版或更高版本)和用于源代码控制的git。
首先克隆此仓库
git clone git@github.com:run-llama/mongodb-demo.git
我们将使用MongoDB的托管数据库服务MongoDB Atlas。您可以免费注册并获得一个小型免费托管集群:
注册过程将引导您创建集群并确保其配置为您可以访问。一旦集群创建完成,选择"连接",然后选择"连接到您的应用程序"。选择Python,您将看到一个类似这样的连接字符串:
复制连接字符串(确保包含您的密码)并将其放入仓库根目录下名为.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虚拟环境来工作是个好主意。有很多方法可以做到这一点,但我们使用的方法是在仓库根目录下运行以下命令 :
python3 -m venv .venv source .venv/bin/activate
现在我们将使用pip一次性安装所有需要的依赖:
pip install -r requirements.txt
这将安装MongoDB驱动程序、LlamaIndex本身以及一些实用程序库。
现在您已准备好将我们预先准备的数据集导入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
中。
现在是时候创建向量搜索索引,以便您可以查询数据。首先,点击Search标签,然后点击"Create Search Index":
目前还不能使用可视 化编辑器创建向量搜索索引,所以选择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 会要求您检查并确认您的选择,然后您需要等待一两分钟,让它生成索引。如果一切顺利,您应该会看到类似这样的屏幕:
现在您已经准备好查 询您的数据了!
您可以通过运行以下命令来实现:
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 仓库中。所以让我们来做这个:
.git
文件夹)在本教程的其余部分,我们假设您正在您刚刚创建的文件夹中工作,该文件夹与您控制的仓库相关联。
创建 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!" 响应。
设置 Render 账户(我们建议使用您的 GitHub 账户登录,以简化操作)并创建一个新的 Web 服务: