与大型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文件的:
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,它使用了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 联系我。