原文:towardsdatascience.com/build-and-deploy-a-multi-file-multi-format-rag-app-to-the-web-910b7ac5eb6d

开发应用程序

这是两篇系列文章中的第一篇。在本部分(第一部分)中,我将向您展示如何开发一个有用的 Web 应用程序,该应用程序可以上传和读取许多不同类型的文件,例如 PDF、TXT、DOCX 等。然后我们将使用 AI 和 RAG 来分析文件并回答有关它们的问题。

在第二部分中,我将向您展示如何使用 Hugging Face Spaces 将您的应用程序部署到 Web 上,这样全世界都可以欣赏到您的伟大。

PS. 如果你想提前看看部署在 Hugging Face Spaces 上的应用程序,请点击这个链接

毫无疑问,从 AI 和大型语言模型中涌现出的最大增长领域之一是检索增强生成(RAG)领域。RAG 是一种微调方法,您向 LLM 提供其训练数据中未访问到的特定信息。

如果你之前从未听说过 RAG,不要担心,它并不复杂。典型的 RAG 管道包括读取一个或多个(通常是 PDF 格式)文档,但它们可以是 CSV、TXT 或任何其他格式。将这些文档分割成更小的文本块,将每个块中的标记(有点像单个单词,但可以更小或更大)编码成数值,并将这些数值数据存储在数据库中。

当用户就文档提出问题,对其问题的处理过程也类似。问题被分割成单个标记,每个标记都使用与原始文件文本相同的编码过程分配一个数值。用户问题中标记的数值与原始文档块中标记的数值进行比较。它们越接近,文档块与用户问题相关的可能性就越大。然后 LLM 将使用这一事实来缩小其可能的答案列表,并在向用户显示最可能的响应之前。

正是这个过程使得 RAG 变得如此重要。

例如,使用 RAG 可以使公司能够访问自动化系统,以调查和查询其内部文档中包含的大量信息。这种自动化也可以通过公司内部网络提供给员工,甚至可以通过集成到外部网站中的自动化帮助台功能提供给客户。所有这些都可以为公司带来价值。

在本文的其余部分,我们将构建一个 Web 应用程序的最小可行产品,该产品将对上传到其中的文档执行 RAG 操作。

我们的应用程序将能够处理多个文件上传,并且能够混合和匹配不同的文件格式,包括 Microsoft EXCEL 和 Word、PDF 和文本。

我们将使用**Gradio作为 GUI,Groq作为我们与 LLM 的接口,以及LlamaIndex**作为我们的 RAG 代理。

我之前写过关于GroqLlamaIndexGradio的文章,所以如果你需要回顾它们的内容,请查看这些链接。

获取 GROQ API 密钥

我们将需要免费的 GROQ API 密钥来开发我们的代码。点击这个链接并按照要求登录或注册。

在屏幕的左侧,点击API Keys链接,然后点击出现的Create API Key按钮。之后,为你的密钥输入一个名称,点击Submit,Groq 将为你创建一个密钥。注意这个密钥,因为你稍后会需要它。如果你忘记了,当需要时只需创建另一个即可。

设置开发环境

我将在 Linux(Ubuntu)上的 Jupyter 笔记本中编写应用程序。如果你是 Windows 用户,我建议安装 WSL2 Ubuntu。

查看以下链接,了解我在 Windows 上安装 WSL2 Ubuntu 的全面教程。

为 Windows 安装 WSL2 Ubuntu

在我们开始编写新项目时,最好设置一个单独的开发环境。这将使我们的项目保持隔离,并有助于确保我们设置的不同版本的 Python 或外部库不会“交叉污染”其他项目。

我使用 conda 来完成这个目的,但可以使用任何适合的方法。

如果你想走 conda 路线,而你还没有安装它,你将首先需要安装 Miniconda(推荐)或 Anaconda。

你可以从这里下载 MiniConda。

环境创建完成后,使用activate命令切换到该环境,然后我们可以安装 Jupyter 和所需的 Python 库。

# create our dev environment
(base) $ conda create -n gradio_rag python=3.11

# switch to it
(base) $ conda activate gradio_rag

# install extra libraries required
(gradio_rag) $ pip install gradio groq jupyter  
(gradio_rag) $ pip install llama-index-llms-groq llama_index 
(gradio_rag) $ pip install llama-index-embeddings-huggingface

现在在命令提示符中输入jupyter notebook。你应该会在浏览器中看到一个 Jupyter Notebook。如果它没有自动打开,你可能会在jupyter notebook命令后看到一屏的信息。在该输出的底部附近,将有一个 URL,你应该将其复制并粘贴到浏览器中以启动 Jupyter Notebook。

你的 URL 将与我不同,但它应该看起来像这样:-

http://127.0.0.1:8888/tree?token=3b9f7bd07b6966b41b68e2350721b2d0b6f388d248cc69da

GUI 界面

我们应用程序的 Gradio 网络界面将非常简单,只包含 6 个小部件。

屏幕上半部分有两个主要组件,左边的一个允许你从本地文件系统**选择要加载的文件(你也可以将文件拖放到这里)。一旦完成,你点击标有加载文档**的大按钮。这会启动 RAG 过程。一旦完成,你将在“加载状态”信息框中看到一个确认消息,显示哪些文件已被加载和处理。

之后,你可以在“输入你的问题”输入框中输入你的查询,按回车键,答案将出现在屏幕底部的较大“聊天机器人”显示框中。

最后一个组件是一个简单的**清除**按钮,它做的是它所说的。

代码

1/ 导入所需的库

import os
import warnings
import gradio as gr
imprt groq
import asyncio
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
from llama_index.llms.groq import Groq
from llama_index.embeddings.huggingface import HuggingFaceEmbedding

2/ 初始化

# A warning may appear which doesn't 
# affect the operation of the code
# Suppress it with this code
warnings.filterwarnings("ignore", message=".*clean_up_tokenization_spaces.*")

# Global variables
index = None
query_engine = None

# Set up Groq API key
os.environ["GROQ_API_KEY"] = "YOUR_GROQ_API_KEY"

# Initialize Groq LLM and ensure it is used
llm = Groq(model="mixtral-8x7b-32768")
Settings.llm = llm  # Ensure Groq is the LLM being used

# Initialize our chosen embedding model
embed_model = HuggingFaceEmbedding(model_name="sentence-transformers/all-MiniLM-L6-v2")

3/ RAG 函数

# These are our RAG fucntions, called in response to user
# initiated events e.g clicking the Load Documents button
# on the GUI
#
def load_documents(file_objs):
    global index, query_engine
    try:
        if not file_objs:
            return "Error: No files selected."

        documents = []
        document_names = []
        for file_obj in file_objs:
            document_names.append(file_obj.name)
            loaded_docs = SimpleDirectoryReader(input_files=[file_obj.name]).load_data()
            documents.extend(loaded_docs)

        if not documents:
            return "No documents found in the selected files."

        # Create index from documents using Groq LLM and HuggingFace Embeddings
        index = VectorStoreIndex.from_documents(
            documents,
            llm=llm,  # Ensure Groq is used here
            embed_model=embed_model
        )

        # Create query engine
        query_engine = index.as_query_engine()

        return f"Successfully loaded {len(documents)} documents from the files: {', '.join(document_names)}"
    except Exception as e:
        return f"Error loading documents: {str(e)}"

async def perform_rag(query, history):
    global query_engine
    if query_engine is None:
        return history + [("Please load documents first.", None)]
    try:
        response = await asyncio.to_thread(query_engine.query, query)
        return history + [(query, str(response))]
    except Exception as e:
        return history + [(query, f"Error processing query: {str(e)}")]

def clear_all():
    global index, query_engine
    index = None
    query_engine = None
    return None, "", [], ""  # Reset file input, load output, chatbot, and message input to default states

4/ Gradio 界面

# Create the Gradio interface
with gr.Blocks(theme=gr.themes.Soft()) as demo:
    gr.Markdown("# RAG Multi-file Chat Application")

    with gr.Row():
        file_input = gr.File(label="Select files to load", file_count="multiple")
        load_btn = gr.Button("Load Documents")

    load_output = gr.Textbox(label="Load Status")

    msg = gr.Textbox(label="Enter your question")
    chatbot = gr.Chatbot()  
    clear = gr.Button("Clear")

    # Set up event handlers
    load_btn.click(load_documents, inputs=[file_input], outputs=[load_output])
    msg.submit(perform_rag, inputs=[msg, chatbot], outputs=[chatbot])
    clear.click(clear_all, outputs=[file_input, load_output, chatbot, msg], queue=False)

5/ 最后我们可以调用应用

# Run the app
if __name__ == "__main__":
    demo.queue()
    demo.launch()

当前应用可以处理 PDF、CSV 和 TXT 文档。要读取其他文件类型,你可能需要安装额外的库。例如,当我第一次尝试加载 Microsoft Word 文档文件时,我收到了这个错误。

Error loading documents: docx2txt is required to read Microsoft 
Word files: `pip install docx2txt`

当我按照指示执行 pip 命令时,应用能够读取.docx 文件并对其中的问题进行回答。

要读取 Excel 文件,请使用 pip 安装 openpyxl。

pip install openpyxl

测试驾驶

让我们试一试。我有一个 PDF 文件、一个文本文件和一个 Excel 文档,如果你喜欢,可以在 Dropbox 上查看。

A Text file about Elephants
===========================
https://www.dropbox.com/scl/fi/mjtaqfhz5g3bdob8ob9c0/storm_gen_article_polished.txt?rlkey=bhbnjrm6ejolri35drgln8llt&st=o6lpox18&dl=0

The Introduction to DropBox PDF
===============================
https://www.dropbox.com/scl/fi/z3fne9w9x6ujy0hkv0r2l/Get-Started-with-Dropbox.pdf?rlkey=jsngq3g91bvv4lffcuf8otvg5&st=mhqz60j0&dl=0

Fake sales data in XL format
============================
https://www.dropbox.com/scl/fi/3yp85yn375sze5n1ovnhf/sales_data.xlsx?rlkey=thm8l60739xi5kxon0zpoe1cx&st=g8w49f9p&dl=0 

这里是从三个文件中摘录的一小段。

大象文本文件样本

...
...

# Etymology

The term "elephant" is derived from the Latin "elephas" (genitive "elephantis")
, which originates from the Greek word "ἐλέφας" (elephas, genitive "ἐλέφαντος"
(elephantos)), with a meaning that has been variously interpreted as 'ivory' 
or 'elephant'. Historical linguistic studies ...
...

销售文件样本

order_id order_dat customer customer product_i product_n category quantity price total
0 1/7/2023 588 Customer 202 Desk Office 5 323.59 1617.95
1 4/17/2023 630 Customer 202 Desk Office 3 280.16 840.47
2 9/25/2023 230 Customer 207 Pen Office 4 491.93 1967.72
3 3/8/2023 318 Customer 206 Paper Office 8 477.71 3821.64
4 1/10/2023 383 Customer 207 Pen Office 1 81.06 81.06
5 4/24/2023 126 Customer 200 Laptop Electronic 4 250.64 1002.58
6 9/20/2023 641 Customer 203 Chair Office 3 548.67 1646.01
7 8/24/2023 166 Customer 203 Chair Office 6 377.07 2262.44
8 ######## 769 Customer 203 Chair Office 4 99.12 396.48
9 8/5/2023 902 Customer 206 Paper Office 8 254.36 2034.89
10 1/13/2023 549 Customer 203 Chair Office 10 569.41 5694.13
...
...

Dropbox PDF 样本简介

...
...

Send Large Files

Need to send a file? Just add it to your Dropbox, share a link 
to it, and you're done. No matter how large the file is, anyone 
with the link can view or download a copy - even if they 
don't have a Dropbox account. 
On dropbox.com
1\. Sign in to dropbox.com, and find the file or folder you'd like to share.
2\. Hover over the file or folder, and click the Share button that appears. 
3\. Enter the email addresses of the people you want share a file with, 
and click Send. Or click Create a link to share with anyone, even 
if they don't use Dropbox. You can copy and paste the link into an 
email, instant message, or wherever you'd like people to access it. 
...
... 

当运行应用时,它应该看起来像这样。点击左上角的按钮来包含你想要分析的文件(或者将它们拖放到框中)。文件可以是文本、PDF、DOCX 或 XLSX 的混合。接下来,点击“加载文档”按钮。当文件被处理时,“加载状态”信息框将更新。然后你可以输入你想要回答的问题,按回车键,答案应该会在聊天机器人窗口中显示。

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/11afca270f70860a19dd46ca098223a2.png

图片由作者提供

对于我的第一个问题,我针对《大象》的文本文件这样提问。

“Elephant”这个词的词源是什么?

术语“elephant”(大象)源自拉丁语“elephas”(属格“elephantis”),起源于希腊语单词“ἐλέφας”(elephas,属格“ἐλέφαντος”(elephantos)),其含义被解释为“象牙”或“大象”。历史语言学研究表明,这个词通过各种古老语言的形式追溯而来,表明这种动物的名称和其象牙的材料已经紧密相关数千年。古希腊人和罗马人从更早的文明中采用了这个术语,可能通过腓尼基中介,而腓尼基人又从近东或非洲的语言中借用。这一词源之旅反映了人们对大象的广泛着迷以及象牙长途贸易,这种贸易将大陆间的文明连接起来,从非常早期就开始了。单词“elephant”进入英语语言的过程也体现了大象在文化、宗教和经济中的重要性,这在历史上一直存在。在许多文化中,大象被视为智慧、力量和记忆的象征,而“elephant”一词的词源反映了人类对这些雄伟生物的深深尊重和赋予的价值。这个术语的历史语言学路径也揭示了古代全球贸易网络和文化交流,突出了大象对世界各地人类社会的深远影响。

这个答案直接来自上传的文档。非常准确。

接下来的问题是关于查询 PDF。

我该如何使用 Dropbox 发送大文件?

要使用 Dropbox 发送大文件,您可以将文件添加到您的 Dropbox 并分享其链接。这样,任何拥有链接的人都可以查看或下载文件的副本,即使他们没有 Dropbox 账户。为此,您可以按照以下步骤操作:

如果您还没有安装,请安装 Dropbox 桌面应用。

打开您的 Dropbox 文件夹,找到您想要分享的文件或文件夹。

右键单击文件并选择“复制 Dropbox 链接”。链接将自动复制。

只需将链接粘贴到您希望人们访问的地方即可。

或者,您也可以通过 Dropbox 网站分享文件的链接:

登录到 dropbox.com,并找到您想要分享的文件或文件夹。

将鼠标悬停在文件或文件夹上,然后点击出现的“分享”按钮。

点击“创建链接”以与任何人分享,即使他们不使用 Dropbox。您可以将链接复制并粘贴到电子邮件、即时消息或您希望人们访问的地方。

另一个很好的答案。

我的最后一个问题是关于 Excel 文件。在模型能够得到正确答案之前,我必须引用问题中提到的输入文件。

在 sales_data.xlsx 文件中,订单编号 9 的总金额是多少?

订单编号 9 的总销售额为 2034.89。

摘要

在这篇文章中,我展示了如何使用 Gradio、GROQ 和 LlamaIndex 构建一个酷炫的多文件格式检索增强生成(RAG)Web 应用程序。我强调了 RAG 为什么是一个变革者,因为它通过提供它们在最初训练时没有的信息来微调大型语言模型(LLMs)。

我们还学习了如何使用 Conda 设置开发环境,了解外部库的要求以及如何获取 GROQ API 密钥。

然后,我们审视了我们应用程序的不同部分。Gradio 用于前端,而将 GROQ 和 LlamaIndex 连接到后端以进行繁重的工作。

因此,我希望这篇文章能成为任何渴望将 RAG 引入其应用程序的开发者的实用指南,将原因和做法完美地打包在一起。

请期待第二部分,我将逐步展示如何使用 Hugging Face Spaces 将应用程序部署到万维网。

_ 好的,目前就到这里。希望你觉得这篇文章有用。如果你觉得有用,请访问我的个人资料页面这里。从那里,你可以看到我其他发表的故事,关注我或订阅以获取我发布新内容的通知。_

我知道现在经济困难,钱包紧张,但如果你觉得这篇文章真的有价值,请考虑 买给我一小杯威士忌

如果你喜欢这个内容,我相信你会觉得这些文章很有趣。

PySpark 解释:Delta 表时间旅行查询

将 Streamlit 应用部署到网络

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐