rag-chatbot
/
app.py
115 строк · 3.8 Кб
1# Import necessary libraries
2import databutton as db3import streamlit as st4import openai5from brain import get_index_for_pdf6from langchain.chains import RetrievalQA7from langchain.chat_models import ChatOpenAI8import os9
10# Set the title for the Streamlit app
11st.title("RAG enhanced Chatbot")12
13# Set up the OpenAI API key from databutton secrets
14os.environ["OPENAI_API_KEY"] = db.secrets.get("OPENAI_API_KEY")15openai.api_key = db.secrets.get("OPENAI_API_KEY")16
17
18# Cached function to create a vectordb for the provided PDF files
19@st.cache_data20def create_vectordb(files, filenames):21# Show a spinner while creating the vectordb22with st.spinner("Vector database"):23vectordb = get_index_for_pdf(24[file.getvalue() for file in files], filenames, openai.api_key25)26return vectordb27
28
29# Upload PDF files using Streamlit's file uploader
30pdf_files = st.file_uploader("", type="pdf", accept_multiple_files=True)31
32# If PDF files are uploaded, create the vectordb and store it in the session state
33if pdf_files:34pdf_file_names = [file.name for file in pdf_files]35st.session_state["vectordb"] = create_vectordb(pdf_files, pdf_file_names)36
37# Define the template for the chatbot prompt
38prompt_template = """39You are a helpful Assistant who answers to users questions based on multiple contexts given to you.
40
41Keep your answer short and to the point.
42
43The evidence are the context of the pdf extract with metadata.
44
45Carefully focus on the metadata specially 'filename' and 'page' whenever answering.
46
47Make sure to add filename and page number at the end of sentence you are citing to.
48
49Reply "Not applicable" if text is irrelevant.
50
51The PDF content is:
52{pdf_extract}
53"""
54
55# Get the current prompt from the session state or set a default value
56prompt = st.session_state.get("prompt", [{"role": "system", "content": "none"}])57
58# Display previous chat messages
59for message in prompt:60if message["role"] != "system":61with st.chat_message(message["role"]):62st.write(message["content"])63
64# Get the user's question using Streamlit's chat input
65question = st.chat_input("Ask anything")66
67# Handle the user's question
68if question:69vectordb = st.session_state.get("vectordb", None)70if not vectordb:71with st.message("assistant"):72st.write("You need to provide a PDF")73st.stop()74
75# Search the vectordb for similar content to the user's question76search_results = vectordb.similarity_search(question, k=3)77# search_results78pdf_extract = "/n ".join([result.page_content for result in search_results])79
80# Update the prompt with the pdf extract81prompt[0] = {82"role": "system",83"content": prompt_template.format(pdf_extract=pdf_extract),84}85
86# Add the user's question to the prompt and display it87prompt.append({"role": "user", "content": question})88with st.chat_message("user"):89st.write(question)90
91# Display an empty assistant message while waiting for the response92with st.chat_message("assistant"):93botmsg = st.empty()94
95# Call ChatGPT with streaming and display the response as it comes96response = []97result = ""98for chunk in openai.ChatCompletion.create(99model="gpt-3.5-turbo", messages=prompt, stream=True100):101text = chunk.choices[0].get("delta", {}).get("content")102if text is not None:103response.append(text)104result = "".join(response).strip()105botmsg.write(result)106
107# Add the assistant's response to the prompt108prompt.append({"role": "assistant", "content": result})109
110# Store the updated prompt in the session state111st.session_state["prompt"] = prompt112prompt.append({"role": "assistant", "content": result})113
114# Store the updated prompt in the session state115st.session_state["prompt"] = prompt116