Spaces:
Sleeping
Sleeping
Upload 4 files
Browse files- app.py +149 -0
- prompt_combined.txt +17 -0
- question-answer.pdf +0 -0
- requirements.txt +10 -0
app.py
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ________ .__ __
|
| 2 |
+
# \______ \ ____ ______ | | ____ ___.__. _____ ____ _____/ |_
|
| 3 |
+
# | | \_/ __ \\____ \| | / _ < | |/ \_/ __ \ / \ __\
|
| 4 |
+
# | ` \ ___/| |_> > |_( <_> )___ | Y Y \ ___/| | \ |
|
| 5 |
+
# /_______ /\___ > __/|____/\____// ____|__|_| /\___ >___| /__|
|
| 6 |
+
# \/ \/|__| \/ \/ \/ \/
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
# Load package
|
| 10 |
+
import streamlit as st
|
| 11 |
+
#rom dotenv import load_dotenv
|
| 12 |
+
from langchain.text_splitter import CharacterTextSplitter, RecursiveCharacterTextSplitter
|
| 13 |
+
from langchain.embeddings import OpenAIEmbeddings
|
| 14 |
+
from langchain.vectorstores import FAISS
|
| 15 |
+
from langchain.chat_models import ChatOpenAI
|
| 16 |
+
from langchain.memory import ConversationBufferMemory
|
| 17 |
+
from langchain.chains import ConversationalRetrievalChain
|
| 18 |
+
from langchain.prompts import PromptTemplate
|
| 19 |
+
from langchain.document_loaders import PyPDFLoader, DataFrameLoader
|
| 20 |
+
import pandas as pd
|
| 21 |
+
import openai
|
| 22 |
+
import os
|
| 23 |
+
import keyboard
|
| 24 |
+
import time
|
| 25 |
+
|
| 26 |
+
# Load .env
|
| 27 |
+
#load_dotenv()
|
| 28 |
+
|
| 29 |
+
# Inisialisasi api key
|
| 30 |
+
#KEY = os.getenv("MY_KEY")
|
| 31 |
+
|
| 32 |
+
# Masukan api key
|
| 33 |
+
#openai.api_key = KEY
|
| 34 |
+
|
| 35 |
+
# Buat object embedding
|
| 36 |
+
embedding = OpenAIEmbeddings(openai_api_key='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')
|
| 37 |
+
|
| 38 |
+
# Model
|
| 39 |
+
llm = ChatOpenAI(model="gpt-4", openai_api_key='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', temperature=0)
|
| 40 |
+
|
| 41 |
+
# Load data csv used car
|
| 42 |
+
df = pd.read_csv(r'clean_usedcar_data.csv')
|
| 43 |
+
|
| 44 |
+
# Load data csv FAQ
|
| 45 |
+
loader = PyPDFLoader(r"question-answer.pdf")
|
| 46 |
+
data_faq = loader.load()
|
| 47 |
+
|
| 48 |
+
# Buat page seperti pdf dari used car data
|
| 49 |
+
loader = DataFrameLoader(df, page_content_column="combined_info")
|
| 50 |
+
data_car = loader.load()
|
| 51 |
+
|
| 52 |
+
# Memotong karakter pada pdf per 1000 karakter
|
| 53 |
+
text_spliter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=0,
|
| 54 |
+
separators=[",","\n\n", "\n", "(?<=\. )", " "],
|
| 55 |
+
length_function=len)
|
| 56 |
+
|
| 57 |
+
# Proses chunk
|
| 58 |
+
text_chunk_recom = text_spliter.split_documents(data_car)
|
| 59 |
+
text_chunk_faq = text_spliter.split_documents(data_faq)
|
| 60 |
+
|
| 61 |
+
# Vector DB data used car
|
| 62 |
+
vectorStore_recom = FAISS.from_documents(text_chunk_recom, embedding)
|
| 63 |
+
vectorStore_faq = FAISS.from_documents(text_chunk_faq, embedding)
|
| 64 |
+
|
| 65 |
+
# Merge vectorestore
|
| 66 |
+
vectorStore_recom.merge_from(vectorStore_faq)
|
| 67 |
+
|
| 68 |
+
# Mmbuka file prompt
|
| 69 |
+
with open(r'prompt_combined.txt', 'r') as file:
|
| 70 |
+
prompt_template = file.read()
|
| 71 |
+
|
| 72 |
+
# Membuat objek retriever
|
| 73 |
+
retrieve = vectorStore_recom.as_retriever(search_type="similarity", search_kwargs={"k": 3})
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
# _________ __ .__ .__ __
|
| 77 |
+
# / _____// |________ ____ _____ _____ | | |__|/ |_
|
| 78 |
+
# \_____ \\ __\_ __ \_/ __ \\__ \ / \| | | \ __\
|
| 79 |
+
# / \| | | | \/\ ___/ / __ \| Y Y \ |_| || |
|
| 80 |
+
# /_______ /|__| |__| \___ >____ /__|_| /____/__||__|
|
| 81 |
+
# \/ \/ \/ \/
|
| 82 |
+
|
| 83 |
+
class BotCRC:
|
| 84 |
+
|
| 85 |
+
def __init__(self):
|
| 86 |
+
global prompt_template
|
| 87 |
+
global retrieve
|
| 88 |
+
self.prompt = PromptTemplate(input_variables=["context", "question", "chat_history"], template=prompt_template)
|
| 89 |
+
self.memory = ConversationBufferMemory(memory_key="chat_history", input_key="question", return_messages=True)
|
| 90 |
+
self.qa_chain = ConversationalRetrievalChain.from_llm(llm=llm, retriever=retrieve, memory=self.memory,
|
| 91 |
+
combine_docs_chain_kwargs={'prompt': self.prompt})
|
| 92 |
+
|
| 93 |
+
# Fungsi untuk berinteraksi dengan bot recommendation
|
| 94 |
+
def conversation(self, user_input):
|
| 95 |
+
result = self.qa_chain({"question": user_input})
|
| 96 |
+
response = result["answer"]
|
| 97 |
+
return response
|
| 98 |
+
|
| 99 |
+
# Fungsi interface
|
| 100 |
+
def chatbot_chain(self):
|
| 101 |
+
USER = "user"
|
| 102 |
+
ASSISTANT = "assistant"
|
| 103 |
+
|
| 104 |
+
initial_context = "Anda adalah asisten dari Carsome, platform jual beli mobil bekas. Anda memiliki dua tugas utama: menjawab pertanyaan pelanggan dan memberikan rekomendasi mobil berdasarkan preferensi mereka."
|
| 105 |
+
# self.memory.chat_memory.add_user_message(initial_context)
|
| 106 |
+
self.memory.chat_memory.add_ai_message(
|
| 107 |
+
"Halo! Saya adalah asisten dari Carsome. Bagaimana saya bisa membantu Anda hari ini?")
|
| 108 |
+
|
| 109 |
+
exit_input = ['keluar', 'sampai jumpa lagi', 'sampai jumpa kembali', 'bye']
|
| 110 |
+
|
| 111 |
+
|
| 112 |
+
# Interface dengan streamlit
|
| 113 |
+
st.title("AutoBuddy")
|
| 114 |
+
st.write("Carsome Assistant Chatbot")
|
| 115 |
+
# Initialize chat history
|
| 116 |
+
if "messages" not in st.session_state:
|
| 117 |
+
st.session_state.messages = []
|
| 118 |
+
|
| 119 |
+
if 'chat_history' not in st.session_state:
|
| 120 |
+
st.session_state.chat_history = self.memory.chat_memory
|
| 121 |
+
else:
|
| 122 |
+
self.memory.chat_memory = st.session_state.chat_history
|
| 123 |
+
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
user_input = st.chat_input("Masukkan pesan yang ingin kamu tulis.", key="chat_input")
|
| 129 |
+
if user_input:
|
| 130 |
+
st.session_state.messages.append({"role": "user", "content": user_input})
|
| 131 |
+
if any(word in user_input.lower() for word in exit_input):
|
| 132 |
+
st.session_state.messages.append({"role": "user", "content": user_input})
|
| 133 |
+
st.chat_message(ASSISTANT).write("Sampai jumpa lagi..", key="chat_output")
|
| 134 |
+
time.sleep(2.5)
|
| 135 |
+
keyboard.press_and_release('ctrl+w')
|
| 136 |
+
else:
|
| 137 |
+
result = self.conversation(user_input)
|
| 138 |
+
# st.session_state.messages.append({"role": "user", "content": user_input})
|
| 139 |
+
# output = st.chat_message(ASSISTANT).write(result, key="chat_output")
|
| 140 |
+
|
| 141 |
+
st.session_state.messages.append({"role": "assistant", "content": result})
|
| 142 |
+
|
| 143 |
+
# Display chat messages from history on app rerun
|
| 144 |
+
for message in st.session_state.messages:
|
| 145 |
+
with st.chat_message(message["role"]):
|
| 146 |
+
st.markdown(message["content"])
|
| 147 |
+
|
| 148 |
+
chat = BotCRC()
|
| 149 |
+
chat.chatbot_chain()
|
prompt_combined.txt
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Prompt template
|
| 2 |
+
prompt_template = """
|
| 3 |
+
You are a friendly and conversational online used car buying and selling platform assistant from Carsome. Your name is Autobuddy.
|
| 4 |
+
You have two jobs:
|
| 5 |
+
1. A customer representative at Carsome, responsible for giving accurate and detailed answers to customer questions.
|
| 6 |
+
2. A recommender at Carsome, responsible for helping customers find and recommend cars at Carsome that match their preferences.
|
| 7 |
+
From the following context and chat history, assist customers in finding what they are looking for based on their input.
|
| 8 |
+
All responses should be in Indonesian and based on data that was already given to you. Your responses should be polite, professional, and helpful. Don’t answer any questions or inquiries that are not related to Carsome and don't make up any answer.
|
| 9 |
+
If you don't know the answer based on the data already given to you, just say that you don't know, don't try to make up an answer.
|
| 10 |
+
|
| 11 |
+
{context}
|
| 12 |
+
|
| 13 |
+
chat history: {chat_history}
|
| 14 |
+
|
| 15 |
+
input: {question}
|
| 16 |
+
Your Response:
|
| 17 |
+
"""
|
question-answer.pdf
ADDED
|
Binary file (159 kB). View file
|
|
|
requirements.txt
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
faiss-cpu
|
| 2 |
+
streamlit
|
| 3 |
+
langchain
|
| 4 |
+
langchain-community
|
| 5 |
+
pandas
|
| 6 |
+
openai
|
| 7 |
+
keyboard
|
| 8 |
+
python-dotenv==0.20.0
|
| 9 |
+
pypdf
|
| 10 |
+
tiktoken
|