基于 Langchain 和 Streamlit,构建多 PDF RAG 聊天机器人

节前,我们组织了一场算法岗技术&面试讨论会,邀请了一些互联网大厂朋友、今年参加社招和校招面试的同学。

针对大模型技术趋势、算法项目落地经验分享、新手如何入门算法岗、该如何准备面试攻略、面试常考点等热门话题进行了深入的讨论。

总结链接如下:

《大模型面试宝典》(2024版) 发布!

在这里插入图片描述

喜欢本文记得收藏、关注、点赞。更多实战和面试交流,也欢迎与我们交流


与 PDF 互动是很酷的。你可以与你的笔记、书籍和文档等进行聊天。

本文将帮助你构建一个基于 Multi RAG Streamlit 的 Web 应用程序,通过对话 AI 聊天机器人来读取、处理和互动PDF数据。

在这里插入图片描述

以下是该应用程序的工作步骤,用简单的语言进行说明。

配置必要的工具

该应用程序首先导入了各种强大的库:

  • Streamlit:用于创建Web界面。
  • PyPDF2:用于读取PDF文件的工具。
  • Langchain:用于自然语言处理和创建对话AI的一套工具。
  • FAISS:用于高效相似性搜索的向量库,在大数据集中快速查找信息非常有用。
import streamlit as st
from PyPDF2 import PdfReader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_core.prompts import ChatPromptTemplate
from langchain_community.embeddings.spacy_embeddings import SpacyEmbeddings
from langchain_community.vectorstores import FAISS
from langchain.tools.retriever import create_retriever_tool
from dotenv import load_dotenv
from langchain_anthropic import ChatAnthropic
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain.agents import AgentExecutor, create_tool_calling_agent

import os
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"

读取和处理PDF文件

应用程序的第一个主要功能是读取PDF文件:

  • PDF阅读器:当用户上传一个或多个PDF文件时,应用程序读取这些文档的每一页并提取文本,将其合并为一个连续的字符串。

一旦提取文本,它将被分割成可管理的块:

  • 文本分割器:使用Langchain库,将文本分割成每块1000个字符。这种分割有助于更高效地处理和分析文本。
def pdf_read(pdf_doc):
    text = ""
    for pdf in pdf_doc:
        pdf_reader = PdfReader(pdf)
        for page in pdf_reader.pages:
            text += page.extract_text()
    return text

def get_chunks(text):
    text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
    chunks = text_splitter.split_text(text)
    return chunks

创建可搜索的文本数据库和生成嵌入

为了使文本可搜索,应用程序将文本块转换为向量表示:

  • 向量存储:应用程序使用FAISS库将文本块转换为向量,并将这些向量本地保存。这一转换至关重要,因为它允许系统在文本中执行快速高效的搜索。
embeddings = SpacyEmbeddings(model_name="en_core_web_sm")

def vector_store(text_chunks):
    vector_store = FAISS.from_texts(text_chunks, embedding=embeddings)
    vector_store.save_local("faiss_db")

设置对话AI

该应用程序的核心是对话AI,它使用OpenAI的强大模型:

  • AI配置:应用程序使用OpenAI的GPT模型设置对话AI。这个AI设计用于回答基于已处理的PDF内容的问题。
  • 对话链:AI使用一组提示来理解上下文并为用户查询提供准确的响应。如果文本中没有问题的答案,AI会回复“答案不在上下文中”,确保用户不会收到错误信息。
def get_conversational_chain(tools, ques):
    llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
    prompt = ChatPromptTemplate.from_messages([
        ("system", "You are a helpful assistant. Answer the question as detailed as possible from the provided context, make sure to provide all the details, if the answer is not in provided context just say, 'answer is not available in the context', don't provide the wrong answer"),
        ("placeholder", "{chat_history}"),
        ("human", "{input}"),
        ("placeholder", "{agent_scratchpad}"),
    ])
    tool = [tools]
    agent = create_tool_calling_agent(llm, tool, prompt)
    agent_executor = AgentExecutor(agent=agent, tools=tool, verbose=True)
    response = agent_executor.invoke({"input": ques})
    print(response)
    st.write("Reply: ", response['output'])

def user_input(user_question):
    new_db = FAISS.load_local("faiss_db", embeddings, allow_dangerous_deserialization=True)
    retriever = new_db.as_retriever()
    retrieval_chain = create_retriever_tool(retriever, "pdf_extractor", "This tool is to give answer to queries from the pdf")
    get_conversational_chain(retrieval_chain, user_question)

用户互动

在后端准备就绪后,应用程序使用Streamlit创建一个用户友好的界面:

  • 用户界面:用户看到一个简单的文本输入框,他们可以在其中输入与PDF内容相关的问题。应用程序会直接在网页上显示AI的响应。
  • 文件上传和处理:用户可以随时上传新的PDF文件。应用程序会即时处理这些文件,更新AI搜索的新文本数据库。
def main():
    st.set_page_config("Chat PDF")
    st.header("RAG based Chat with PDF")
    user_question = st.text_input("Ask a Question from the PDF Files")
    if user_question:
        user_input(user_question)
    with st.sidebar:
        pdf_doc = st.file_uploader("Upload your PDF Files and Click on the Submit & Process Button", accept_multiple_files=True)
        if st.button("Submit & Process"):
            with st.spinner("Processing..."):
                raw_text = pdf_read(pdf_doc)
                text_chunks = get_chunks(raw_text)
                vector_store(text_chunks)
                st.success("Done")

结论

完整代码

import streamlit as st
from PyPDF2 import PdfReader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_core.prompts import ChatPromptTemplate
from langchain_community.embeddings.spacy_embeddings import SpacyEmbeddings
from langchain_community.vectorstores import FAISS
from langchain.tools.retriever import create_retriever_tool
from dotenv import load_dotenv
from langchain_anthropic import ChatAnthropic
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain.agents import AgentExecutor, create_tool_calling_agent

import os
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"

embeddings = SpacyEmbeddings(model_name="en_core_web_sm")
def pdf_read(pdf_doc):
    text = ""
    for pdf in pdf_doc:
        pdf_reader = PdfReader(pdf)
        for page in pdf_reader.pages:
            text += page.extract_text()
    return text



def get_chunks(text):
    text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
    chunks = text_splitter.split_text(text)
    return chunks


def vector_store(text_chunks):
    
    vector_store = FAISS.from_texts(text_chunks, embedding=embeddings)
    vector_store.save_local("faiss_db")


def get_conversational_chain(tools,ques):

    llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0, apikey)
    prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            """You are a helpful assistant. Answer the question as detailed as possible from the provided context, make sure to provide all the details, if the answer is not in
    provided context just say, "answer is not available in the context", don't provide the wrong answer""",
        ),
        ("placeholder", "{chat_history}"),
        ("human", "{input}"),
        ("placeholder", "{agent_scratchpad}"),
    ]
)
    tool=[tools]
    agent = create_tool_calling_agent(llm, tool, prompt)

    agent_executor = AgentExecutor(agent=agent, tools=tool, verbose=True)
    response=agent_executor.invoke({"input": ques})
    print(response)
    st.write("Reply: ", response['output'])



def user_input(user_question):
    
    
    
    new_db = FAISS.load_local("faiss_db", embeddings,allow_dangerous_deserialization=True)
    
    retriever=new_db.as_retriever()
    retrieval_chain= create_retriever_tool(retriever,"pdf_extractor","This tool is to give answer to queries from the pdf")
    get_conversational_chain(retrieval_chain,user_question)





def main():
    st.set_page_config("Chat PDF")
    st.header("RAG based Chat with PDF")

    user_question = st.text_input("Ask a Question from the PDF Files")

    if user_question:
        user_input(user_question)

    with st.sidebar:
        st.title("Menu:")
        pdf_doc = st.file_uploader("Upload your PDF Files and Click on the Submit & Process Button", accept_multiple_files=True)
        if st.button("Submit & Process"):
            with st.spinner("Processing..."):
                raw_text = pdf_read(pdf_doc)
                text_chunks = get_chunks(raw_text)
                vector_store(text_chunks)
                st.success("Done")

if __name__ == "__main__":
    main()

通过将应用程序保存为 app.py,然后使用

streamlit run app.py

在这里插入图片描述

技术交流

前沿技术资讯、算法交流、求职内推、算法竞赛、面试交流(校招、社招、实习)等、与 10000+来自港科大、北大、清华、中科院、CMU、腾讯、百度等名校名企开发者互动交流~

我们建了算法岗面试与技术交流群, 想要进交流群、需要源码&资料、提升技术的同学,可以直接加微信号:mlc2040。加的时候备注一下:研究方向 +学校/公司+CSDN,即可。然后就可以拉你进群了。

方式①、微信搜索公众号:机器学习社区,后台回复:技术交流
方式②、添加微信号:mlc2040,备注:技术交流+CSDN

用通俗易懂的方式讲解系列

  • 11
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值