使用OpenAI和LangChain构建PDF互动问答功能

发布时间:2023-06-25

在当今数字时代,高效的信息检索和交互界面对于简化工作流程至关重要。在本教程中,我们将探讨如何构建一个Streamlit应用程序,利用OpenAI的语言模型和LangChain来促进与PDF文档的互动问答。通过本文的学习,您将拥有一个功能齐全的应用程序,可以处理PDF文件,提取相关信息,并回答用户的查询。


步骤1:设置开发环境

在开始编码之前,让我们确保我们已经准备好了所有必要的工具和库。按照以下步骤设置您的开发环境:

  1. 安装Python:Streamlit需要Python,请确保您已经在系统上安装了Python。您可以从官方Python网站下载最新版本。

  2. 安装Streamlit:打开终端或命令提示符,并运行以下命令安装Streamlit:

pip install streamlit
  1. 安装所需库:我们将使用OpenAI的“openai”库和LangChain的“langchain”库。通过执行以下命令进行安装:

pip install openaipip install langchain

最后,我们需要为OpenAI API密钥设置一个环境变量:

set OPENAI_API_KEY=<YOUR_API_KEY>

导入所需的库:

在您的 Python 文件中,导入我们 Streamlit 应用程序所需的必要库。添加以下代码:

from dotenv import load_dotenvimport streamlit as stfrom PyPDF2 import PdfReaderfrom langchain.text_splitter import CharacterTextSplitterfrom langchain.embeddings.openai import OpenAIEmbeddingsfrom langchain.vectorstores import FAISSfrom langchain.chains.question_answering import load_qa_chainfrom langchain.llms import OpenAIfrom langchain.callbacks import get_openai_callbackfrom streamlit.components.v1 import htmlimport streamlit.components.v1 as componentsfrom streamlit_chat import message
  • load_dotenv() 用于加载环境变量,如果存在 .env 文件,可以将敏感信息或配置设置存储其中。

  • st.set_page_config(layout="wide")将 Streamlit 应用程序的布局设置为 "wide",以便显示更宽的内容。

  • col1, col2 = st.columns([1, 2]) 使用 st.columns() 函数创建 UI 的两个列。这些列将并排显示应用程序的不同组件。

  • 当使用文件上传程序上传 PDF 文件时,将执行代码的此部分。它使用 PyPDF2 库读取已上传的 PDF 文件并从每个页面中提取文本内容。然后使用 HTML 组件将提取的文本在 Streamlit 应用程序中显示出来,以进行可视化。

  • 从 PDF 中提取文本后,代码继续使用 LangChain 库的 CharacterTextSplitter 将文本分成较小的块。这有助于提高处理效率,特别是对于较大的 PDF 文档。使用 OpenAI 的语言模型和 LangChain 的 OpenAIEmbeddings 来为文本块创建嵌入。这些嵌入捕获文本的语义信息,这对于准确的问题回答至关重要。

  • 当用户在 Streamlit 应用程序中单击 “Send” 按钮时,将触发此函数。

  • 它首先检查用户输入是否不为空(st.session_state.user != ''),以确保有要处理的提示/问题。

  • 如果存在提示,则继续进行问题回答过程。

  • docs = knowledge_base.similarity_search(prompt) 在知识库 (knowledge_base) 中执行相似度搜索,以检索与用户问题相关的相关文档。

  • 然后初始化 OpenAI 语言模型 (llm = OpenAI()) 并加载问题回答链 (chain = load_qa_chain(llm, chain_type="stuff"))。

  • 在 with get_openai_callback() as cb: 块内,将问题传递给链 (chain.run(input_documents=docs, question=prompt)) 生成响应。

  • 最后,将提示/问题和生成的响应分别附加到 st.session_state.prompts 和 st.session_state.responses 列表中,以维护对话历史记录。

  • 函数定义后的代码块初始化 st.session_state.prompts 和 st.session_state.responses 列表,如果它们不存在于 Streamlit 会话状态中。这些列表将存储用户和应用程序之间的对话历史记录。

if 'prompts' not in st.session_state:
    st.session_state.prompts = []
if 'responses' not in st.session_state:
    st.session_state.responses = []

st.set_page_config(layout="wide")
col1, col2 = st.columns([1,2])

def send_click():
    if st.session_state.user != '':
        prompt = st.session_state.user
        if prompt:
          docs = knowledge_base.similarity_search(prompt)
        llm = OpenAI()
        chain = load_qa_chain(llm, chain_type="stuff")        with get_openai_callback() as cb:
              response = chain.run(input_documents=docs, question=prompt)
        st.session_state.prompts.append(prompt)
        st.session_state.responses.append(response)

load_dotenv()# Left column: Upload PDF textcol1.header("Upload PDF Text")
col1.header("Ask your PDF  ")# upload filepdf = col1.file_uploader("Upload your PDF", type="pdf")# extract the textif pdf is not None:
  pdf_reader = PdfReader(pdf)  text = ""
  for page in pdf_reader.pages:    text += page.extract_text()

  t1=f"""<font color='white'>{text}</fon>"""
  with col2:
      html(t1, height=400, scrolling=True)  # split into chunks
  text_splitter = CharacterTextSplitter(
    separator="\\n",
    chunk_size=1000,
    chunk_overlap=200,
    length_function=len
  )
  chunks = text_splitter.split_text(text)  # create embeddings
  embeddings = OpenAIEmbeddings()
  knowledge_base = FAISS.from_texts(chunks, embeddings)  # show user input
  st.text_input("Ask a question about your PDF:", key="user")
  st.button("Send", on_click=send_click)   # col1.write(response)
  if st.session_state.prompts:    for i in range(len(st.session_state.responses)-1, -1, -1):
        message(st.session_state.responses[i], key=str(i), seed='Milo')
        message(st.session_state.prompts[i], is_user=True, key=str(i) + '_user', seed=83)

恭喜!您已经成功构建了一个Streamlit应用程序,可以与PDF文档进行交互式问答。通过结合Streamlit的强大功能,OpenAI的语言模型和LangChain的文本处理能力,您已经创建了一个直观的界面,促进了从PDF文件中高效地检索信息。可以通过加入其他功能或将其整合到现有工作流程中来进一步增强应用程序。


想了解更多资讯,欢迎前往ChatDZQ官网!

  • OpenAI

相关文章

扫码在手机访问

随时随地
掌握经营技巧

专业顾问
为您解决经营难题

立即咨询

咨询热线

400-8856-200