构建一个多PDF RAG聊天机器人:使用Langchain和Streamlit及代码

2024/9/20 21:03:30

本文主要是介绍构建一个多PDF RAG聊天机器人:使用Langchain和Streamlit及代码,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

与大型PDF文件对话很酷。你可以与你的笔记、书籍和文档等进行聊天。这篇博客文章将帮助你构建一个基于Streamlit的多RAG web应用,通过对话式AI聊天机器人读取、处理和交互PDF数据。以下是该应用程序如何工作的分步说明,使用简单易懂的语言。

使用必要的工具搭建环境

该应用程序开始时导入了各种强大的库:
- Streamlit: 用于创建网页界面。
- 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, api_key="")  
        prompt = ChatPromptTemplate.from_messages([...])  
        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("回复: ", 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","此工具用于回答来自PDF的查询")  
        get_conversational_chain(retrieval_chain,user_question)
用户交互

在后端准备就绪后,应用程序使用Streamlit创建一个用户友好的界面:
- 用户界面: 用户会看到一个简单的文本输入框,可以在其中输入与PDF内容相关的问题。应用程序会直接在网页上显示AI的回答。
- 文件上传和处理: 用户可以随时上传新的PDF文件。应用程序会实时处理这些文件,并将新的文本更新到数据库中,供AI搜索。

    def main():  
        st.set_page_config("Chat PDF")  
        st.header("基于RAG的PDF聊天")  
        user_question = st.text_input("从PDF文件中提问")  
        if user_question:  
            user_input(user_question)  
        with st.sidebar:  
            pdf_doc = st.file_uploader("上传您的PDF文件并点击提交和处理按钮", accept_multiple_files=True)  
            if st.button("提交并处理"):  
                with st.spinner("处理中..."):  
                    raw_text = pdf_read(pdf_doc)  
                    text_chunks = get_chunks(raw_text)  
                    vector_store(text_chunks)  
                    st.success("完成")
结论

答案流式的流程图

整个代码
    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):  
        #os.environ["ANTHROPIC_API_KEY"]=os.getenv["ANTHROPIC_API_KEY"]  
        #llm = ChatAnthropic(model="claude-3-sonnet-20240229", temperature=0, api_key=os.getenv("ANTHROPIC_API_KEY"),verbose=True)  
        llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0, api_key="")  
        prompt = ChatPromptTemplate.from_messages(  
        [  
            (  
                "system",  
                """您是一个乐于助人的助手。请根据提供的上下文尽可能详细地回答问题,确保提供所有细节。如果答案不在提供的上下文中,请回答“答案不在上下文中”,不要提供错误的答案。""",  
            ),  
            ("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("回复: ", 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","此工具用于回答来自PDF的查询")  
        get_conversational_chain(retrieval_chain,user_question)  

    def main():  
        st.set_page_config("与PDF聊天")  
        st.header("基于RAG的PDF聊天")  

        user_question = st.text_input("从PDF文件中提问")  

        if user_question:  
            user_input(user_question)  

        with st.sidebar:  
            st.title("菜单:")  
            pdf_doc = st.file_uploader("上传您的PDF文件并点击提交和处理按钮", accept_multiple_files=True)  
            if st.button("提交并处理"):  
                with st.spinner("处理中..."):  
                    raw_text = pdf_read(pdf_doc)  
                    text_chunks = get_chunks(raw_text)  
                    vector_store(text_chunks)  
                    st.success("完成")  

    if __name__ == "__main__":  
        main()

通过将其保存为 app.py 然后运行来启动应用程序。

执行 streamlit run app.py

输出:

看起来是这样的!

如果你喜欢这篇博客,也应该看看我在 Instagram 上发布的视频:https://www.instagram.com/parasmadan.in/

如有任何疑问,欢迎通过 hello@parasmadan.in 联系我。



这篇关于构建一个多PDF RAG聊天机器人:使用Langchain和Streamlit及代码的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程