使用Langchain、ChatGPT和Streamlit构建多PDF RAG聊天机器人

2024年06月13日 由 alex 发表 198 0

与大型 PDF 对话很酷。你可以与你的笔记、书籍和文档等聊天。本文将帮助你构建一个基于 Multi RAG Streamlit 的网络应用程序,通过对话式人工智能聊天机器人读取、处理 PDF 数据并与之交互。下面将使用简单的语言逐步介绍该应用程序的工作原理,以便于理解。


2


使用必要的工具搭建舞台


应用程序首先要导入各种功能强大的库:

  • Streamlit: 用于创建网络界面。
  • PyPDF2:读取 PDF 文件的工具。
  • Langchain: 一套用于自然语言处理和创建对话式人工智能的工具。
  • 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")


设置对话式人工智能


本应用程序的核心是对话式人工智能,它使用 OpenAI 的强大模型:

  • 人工智能配置: 该应用程序使用 OpenAI 的 GPT 模型设置对话式人工智能。该人工智能旨在根据其处理过的 PDF 内容回答问题。
  • 对话链: 人工智能使用一组提示来理解上下文,并对用户的询问做出准确的回答。如果文本中没有问题的答案,人工智能会以 "上下文中没有答案 "的方式进行回复,确保用户不会收到错误的信息。


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("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 内容相关的问题。然后,应用程序会将人工智能的回复直接显示在网页上。
  • 文件上传和处理: 用户可以随时上传新的 PDF 文件。应用程序会即时处理这些文件,更新数据库中的新文本,供人工智能搜索。


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):
    #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",
            """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


输出:


3

文章来源:https://blog.gopenai.com/building-a-multi-pdf-rag-chatbot-langchain-streamlit-with-code-d21d0a1cf9e5
欢迎关注ATYUN官方公众号
商务合作及内容投稿请联系邮箱:bd@atyun.com
评论 登录
热门职位
Maluuba
20000~40000/月
Cisco
25000~30000/月 深圳市
PilotAILabs
30000~60000/年 深圳市
写评论取消
回复取消