yvannn commited on
Commit
f7ad9e4
Β·
1 Parent(s): 7469860

Add PromptTemplate for better response accuracy

Browse files
Files changed (2) hide show
  1. requirements.txt +0 -0
  2. src/chatbot_csv.py +29 -37
requirements.txt CHANGED
Binary files a/requirements.txt and b/requirements.txt differ
 
src/chatbot_csv.py CHANGED
@@ -5,23 +5,21 @@ import tempfile
5
  import pandas as pd
6
  import asyncio
7
 
8
- # Import modules needed for building the chatbot application
9
  from streamlit_chat import message
10
  from langchain.embeddings.openai import OpenAIEmbeddings
11
  from langchain.chat_models import ChatOpenAI
12
  from langchain.chains import ConversationalRetrievalChain
13
  from langchain.document_loaders.csv_loader import CSVLoader
14
  from langchain.vectorstores import FAISS
 
 
15
 
16
- # Set the Streamlit page configuration, including the layout and page title/icon
17
  st.set_page_config(layout="wide", page_icon="πŸ’¬", page_title="ChatBot-CSV")
18
 
19
- # Display the header for the application using HTML markdown
20
  st.markdown(
21
  "<h1 style='text-align: center;'>ChatBot-CSV, Talk with your csv-data ! πŸ’¬</h1>",
22
  unsafe_allow_html=True)
23
 
24
- # Allow the user to enter their OpenAI API key
25
  user_api_key = st.sidebar.text_input(
26
  label="#### Your OpenAI API key πŸ‘‡",
27
  placeholder="Paste your openAI API key, sk-",
@@ -29,22 +27,17 @@ user_api_key = st.sidebar.text_input(
29
 
30
  async def main():
31
 
32
- # Check if the user has entered an OpenAI API key
33
  if user_api_key == "":
34
 
35
- # Display a message asking the user to enter their API key
36
  st.markdown(
37
  "<div style='text-align: center;'><h4>Enter your OpenAI API key to start chatting πŸ˜‰</h4></div>",
38
  unsafe_allow_html=True)
39
 
40
  else:
41
- # Set the OpenAI API key as an environment variable
42
  os.environ["OPENAI_API_KEY"] = user_api_key
43
 
44
- # Allow the user to upload a CSV file
45
  uploaded_file = st.sidebar.file_uploader("upload", type="csv", label_visibility="hidden")
46
 
47
- # If the user has uploaded a file, display it in an expander
48
  if uploaded_file is not None:
49
  def show_user_file(uploaded_file):
50
  file_container = st.expander("Your CSV file :")
@@ -54,7 +47,6 @@ async def main():
54
 
55
  show_user_file(uploaded_file)
56
 
57
- # If the user has not uploaded a file, display a message asking them to do so
58
  else :
59
  st.sidebar.info(
60
  "πŸ‘† Upload your CSV file to get started, "
@@ -63,7 +55,6 @@ async def main():
63
 
64
  if uploaded_file :
65
  try :
66
- # Define an asynchronous function for storing document embeddings using Langchain and FAISS
67
  async def storeDocEmbeds(file, filename):
68
 
69
  # Write the uploaded file to a temporary file
@@ -75,33 +66,26 @@ async def main():
75
  loader = CSVLoader(file_path=tmp_file_path, encoding="utf-8")
76
  data = loader.load()
77
 
78
- # Create an embeddings object using Langchain
79
  embeddings = OpenAIEmbeddings()
80
 
81
- # Store the embeddings vectors using FAISS
82
  vectors = FAISS.from_documents(data, embeddings)
83
  os.remove(tmp_file_path)
84
 
85
- # Save the vectors to a pickle file
86
  with open(filename + ".pkl", "wb") as f:
87
  pickle.dump(vectors, f)
88
 
89
- # Define an asynchronous function for retrieving document embeddings
90
  async def getDocEmbeds(file, filename):
91
 
92
- # Check if embeddings vectors have already been stored in a pickle file
93
  if not os.path.isfile(filename + ".pkl"):
94
  # If not, store the vectors using the storeDocEmbeds function
95
  await storeDocEmbeds(file, filename)
96
 
97
- # Load the vectors from the pickle file
98
  with open(filename + ".pkl", "rb") as f:
99
  #global vectors
100
  vectors = pickle.load(f)
101
 
102
  return vectors
103
 
104
- # Define an asynchronous function for conducting conversational chat using Langchain
105
  async def conversational_chat(query):
106
 
107
  # Use the Langchain ConversationalRetrievalChain to generate a response to the user's query
@@ -110,9 +94,9 @@ async def main():
110
  # Add the user's query and the chatbot's response to the chat history
111
  st.session_state['history'].append((query, result["answer"]))
112
 
113
- # Print the chat history for debugging purposes
114
- print("Log: ")
115
- print(st.session_state['history'])
116
 
117
  return result["answer"]
118
 
@@ -126,39 +110,52 @@ async def main():
126
  # Allow the user to select a chatbot model to use
127
  MODEL = st.selectbox(label='Model', options=['gpt-3.5-turbo','gpt-4'])
128
 
129
- # If the chat history has not yet been initialized, do so now
130
  if 'history' not in st.session_state:
131
  st.session_state['history'] = []
132
 
133
- # If the chatbot is not yet ready to chat, set the "ready" flag to False
134
  if 'ready' not in st.session_state:
135
  st.session_state['ready'] = False
136
 
137
- # If the "reset_chat" flag has not been set, set it to False
138
  if 'reset_chat' not in st.session_state:
139
  st.session_state['reset_chat'] = False
140
 
141
- # If a CSV file has been uploaded
142
  if uploaded_file is not None:
143
 
144
  # Display a spinner while processing the file
145
  with st.spinner("Processing..."):
146
 
147
- # Read the uploaded CSV file
148
  uploaded_file.seek(0)
149
  file = uploaded_file.read()
150
 
151
  # Generate embeddings vectors for the file
152
  vectors = await getDocEmbeds(file, uploaded_file.name)
153
 
154
- # Use the Langchain ConversationalRetrievalChain to set up the chatbot
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  chain = ConversationalRetrievalChain.from_llm(llm = ChatOpenAI(temperature=0.0,model_name=MODEL),
156
- retriever=vectors.as_retriever())
157
 
158
  # Set the "ready" flag to True now that the chatbot is ready to chat
159
  st.session_state['ready'] = True
160
 
161
- # If the chatbot is ready to chat
162
  if st.session_state['ready']:
163
 
164
  # If the chat history has not yet been initialized, initialize it now
@@ -168,10 +165,10 @@ async def main():
168
  if 'past' not in st.session_state:
169
  st.session_state['past'] = ["Hey ! πŸ‘‹"]
170
 
171
- # Create a container for displaying the chat history
172
  response_container = st.container()
173
 
174
- # Create a container for the user's text input
175
  container = st.container()
176
 
177
  with container:
@@ -191,7 +188,6 @@ async def main():
191
  response_container.empty()
192
  st.session_state['reset_chat'] = False
193
 
194
- # If the user has submitted a query
195
  if submit_button and user_input:
196
 
197
  # Generate a response using the Langchain ConversationalRetrievalChain
@@ -201,7 +197,6 @@ async def main():
201
  st.session_state['past'].append(user_input)
202
  st.session_state['generated'].append(output)
203
 
204
- # If there are generated messages to display
205
  if st.session_state['generated']:
206
 
207
  # Display the chat history
@@ -210,15 +205,12 @@ async def main():
210
  for i in range(len(st.session_state['generated'])):
211
  message(st.session_state["past"][i], is_user=True, key=str(i) + '_user', avatar_style="big-smile")
212
  message(st.session_state["generated"][i], key=str(i), avatar_style="thumbs")
213
- #st.write(chain)
214
 
215
  except Exception as e:
216
  st.error(f"Error: {str(e)}")
217
 
218
- # Create an expander for the "About" section
219
  about = st.sidebar.expander("About πŸ€–")
220
-
221
- # Write information about the chatbot in the "About" section
222
  about.write("#### ChatBot-CSV is an AI chatbot featuring conversational memory, designed to enable users to discuss their CSV data in a more intuitive manner. πŸ“„")
223
  about.write("#### He employs large language models to provide users with seamless, context-aware natural language interactions for a better understanding of their CSV data. 🌐")
224
  about.write("#### Powered by [Langchain](https://github.com/hwchase17/langchain), [OpenAI](https://platform.openai.com/docs/models/gpt-3-5) and [Streamlit](https://github.com/streamlit/streamlit) ⚑")
 
5
  import pandas as pd
6
  import asyncio
7
 
 
8
  from streamlit_chat import message
9
  from langchain.embeddings.openai import OpenAIEmbeddings
10
  from langchain.chat_models import ChatOpenAI
11
  from langchain.chains import ConversationalRetrievalChain
12
  from langchain.document_loaders.csv_loader import CSVLoader
13
  from langchain.vectorstores import FAISS
14
+ from langchain.prompts.prompt import PromptTemplate
15
+
16
 
 
17
  st.set_page_config(layout="wide", page_icon="πŸ’¬", page_title="ChatBot-CSV")
18
 
 
19
  st.markdown(
20
  "<h1 style='text-align: center;'>ChatBot-CSV, Talk with your csv-data ! πŸ’¬</h1>",
21
  unsafe_allow_html=True)
22
 
 
23
  user_api_key = st.sidebar.text_input(
24
  label="#### Your OpenAI API key πŸ‘‡",
25
  placeholder="Paste your openAI API key, sk-",
 
27
 
28
  async def main():
29
 
 
30
  if user_api_key == "":
31
 
 
32
  st.markdown(
33
  "<div style='text-align: center;'><h4>Enter your OpenAI API key to start chatting πŸ˜‰</h4></div>",
34
  unsafe_allow_html=True)
35
 
36
  else:
 
37
  os.environ["OPENAI_API_KEY"] = user_api_key
38
 
 
39
  uploaded_file = st.sidebar.file_uploader("upload", type="csv", label_visibility="hidden")
40
 
 
41
  if uploaded_file is not None:
42
  def show_user_file(uploaded_file):
43
  file_container = st.expander("Your CSV file :")
 
47
 
48
  show_user_file(uploaded_file)
49
 
 
50
  else :
51
  st.sidebar.info(
52
  "πŸ‘† Upload your CSV file to get started, "
 
55
 
56
  if uploaded_file :
57
  try :
 
58
  async def storeDocEmbeds(file, filename):
59
 
60
  # Write the uploaded file to a temporary file
 
66
  loader = CSVLoader(file_path=tmp_file_path, encoding="utf-8")
67
  data = loader.load()
68
 
 
69
  embeddings = OpenAIEmbeddings()
70
 
 
71
  vectors = FAISS.from_documents(data, embeddings)
72
  os.remove(tmp_file_path)
73
 
 
74
  with open(filename + ".pkl", "wb") as f:
75
  pickle.dump(vectors, f)
76
 
 
77
  async def getDocEmbeds(file, filename):
78
 
 
79
  if not os.path.isfile(filename + ".pkl"):
80
  # If not, store the vectors using the storeDocEmbeds function
81
  await storeDocEmbeds(file, filename)
82
 
 
83
  with open(filename + ".pkl", "rb") as f:
84
  #global vectors
85
  vectors = pickle.load(f)
86
 
87
  return vectors
88
 
 
89
  async def conversational_chat(query):
90
 
91
  # Use the Langchain ConversationalRetrievalChain to generate a response to the user's query
 
94
  # Add the user's query and the chatbot's response to the chat history
95
  st.session_state['history'].append((query, result["answer"]))
96
 
97
+ # You can print the chat history for debugging :
98
+ #print("Log: ")
99
+ #print(st.session_state['history'])
100
 
101
  return result["answer"]
102
 
 
110
  # Allow the user to select a chatbot model to use
111
  MODEL = st.selectbox(label='Model', options=['gpt-3.5-turbo','gpt-4'])
112
 
 
113
  if 'history' not in st.session_state:
114
  st.session_state['history'] = []
115
 
 
116
  if 'ready' not in st.session_state:
117
  st.session_state['ready'] = False
118
 
 
119
  if 'reset_chat' not in st.session_state:
120
  st.session_state['reset_chat'] = False
121
 
 
122
  if uploaded_file is not None:
123
 
124
  # Display a spinner while processing the file
125
  with st.spinner("Processing..."):
126
 
 
127
  uploaded_file.seek(0)
128
  file = uploaded_file.read()
129
 
130
  # Generate embeddings vectors for the file
131
  vectors = await getDocEmbeds(file, uploaded_file.name)
132
 
133
+ _template = """Given the following conversation and a follow-up question, rephrase the follow-up question to be a stand-alone question.
134
+ You can assume that the question is about the information in a CSV file.
135
+ Chat History:
136
+ {chat_history}
137
+ Follow-up entry: {question}
138
+ Standalone question:"""
139
+ CONDENSE_QUESTION_PROMPT = PromptTemplate.from_template(_template)
140
+
141
+ qa_template = """"You are an AI conversational assistant to answer questions based on information from a csv file.
142
+ You are given data from a csv file and a question, you must help the user find the information they need.
143
+ Only give responses for information you know about. Don't try to make up an answer.
144
+ Your answers should be short and friendly.
145
+ Respond to the user in the same language they are speaking to you in.
146
+ question: {question}
147
+ =========
148
+ {context}
149
+ =======
150
+ """
151
+ QA_PROMPT = PromptTemplate(template=qa_template, input_variables=["question", "context"])
152
+
153
  chain = ConversationalRetrievalChain.from_llm(llm = ChatOpenAI(temperature=0.0,model_name=MODEL),
154
+ condense_question_prompt=CONDENSE_QUESTION_PROMPT,qa_prompt=QA_PROMPT,retriever=vectors.as_retriever())
155
 
156
  # Set the "ready" flag to True now that the chatbot is ready to chat
157
  st.session_state['ready'] = True
158
 
 
159
  if st.session_state['ready']:
160
 
161
  # If the chat history has not yet been initialized, initialize it now
 
165
  if 'past' not in st.session_state:
166
  st.session_state['past'] = ["Hey ! πŸ‘‹"]
167
 
168
+ #container for displaying the chat history
169
  response_container = st.container()
170
 
171
+ #container for the user's text input
172
  container = st.container()
173
 
174
  with container:
 
188
  response_container.empty()
189
  st.session_state['reset_chat'] = False
190
 
 
191
  if submit_button and user_input:
192
 
193
  # Generate a response using the Langchain ConversationalRetrievalChain
 
197
  st.session_state['past'].append(user_input)
198
  st.session_state['generated'].append(output)
199
 
 
200
  if st.session_state['generated']:
201
 
202
  # Display the chat history
 
205
  for i in range(len(st.session_state['generated'])):
206
  message(st.session_state["past"][i], is_user=True, key=str(i) + '_user', avatar_style="big-smile")
207
  message(st.session_state["generated"][i], key=str(i), avatar_style="thumbs")
208
+
209
 
210
  except Exception as e:
211
  st.error(f"Error: {str(e)}")
212
 
 
213
  about = st.sidebar.expander("About πŸ€–")
 
 
214
  about.write("#### ChatBot-CSV is an AI chatbot featuring conversational memory, designed to enable users to discuss their CSV data in a more intuitive manner. πŸ“„")
215
  about.write("#### He employs large language models to provide users with seamless, context-aware natural language interactions for a better understanding of their CSV data. 🌐")
216
  about.write("#### Powered by [Langchain](https://github.com/hwchase17/langchain), [OpenAI](https://platform.openai.com/docs/models/gpt-3-5) and [Streamlit](https://github.com/streamlit/streamlit) ⚑")