nurqoneah commited on
Commit
e6c404c
·
verified ·
1 Parent(s): 6db4b42

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +159 -94
app.py CHANGED
@@ -1,112 +1,177 @@
1
- import os
2
  import streamlit as st
3
- from langchain.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate
4
- from langchain_community.llms import HuggingFaceHub
5
  from langchain_huggingface import HuggingFaceEmbeddings
6
  from langchain_community.vectorstores import Chroma
7
- from langchain.memory import ConversationBufferMemory
8
- from langchain.chains import ConversationalRetrievalChain
9
  from langchain.prompts import PromptTemplate
10
-
11
- # Environment
12
- os.environ["HUGGINGFACEHUB_API_TOKEN"] = os.getenv("HUGGINGFACEHUB_API_TOKEN")
13
- EMBEDDING_MODEL_NAME = "sentence-transformers/all-MiniLM-L6-v2"
14
-
15
- @st.cache_resource
16
- def get_response(question):
17
- result = st.session_state.conversational_chain({"question": question})
18
- response_text = result.get("answer", "Maaf, saya tidak mengetahui jawaban itu.")
19
-
20
- # Membersihkan jawaban dari teks yang tidak diperlukan
21
- if "Answer:" in response_text:
22
- response_text = response_text.split("Answer:")[1].strip()
23
- return response_text
24
-
25
-
26
- def setup_vectorstore():
27
- persist_directory = "./vector_db_dir"
28
- embeddings = HuggingFaceEmbeddings(model_name=EMBEDDING_MODEL_NAME)
29
- return Chroma(persist_directory=persist_directory, embedding_function=embeddings)
30
-
31
- def chat_chain(vectorstore):
32
- hf_hub_llm = HuggingFaceHub(
33
- repo_id="SeaLLMs/SeaLLMs-v3-7B-Chat",
34
- model_kwargs={"temperature": 1, "max_new_tokens": 1024},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  )
36
 
37
- prompt_template = """
38
- You are an assistant specialized in women's health. Use the retrieved documents to answer the user's question.
39
- If you don't know the answer or the information is not in the documents, reply with: "I'm sorry, I don't know."
40
-
41
- Chat History:
42
- {chat_history}
43
 
44
- Question:
45
- {question}
46
 
47
- Answer:"""
48
- prompt = PromptTemplate(input_variables=["chat_history", "question"], template=prompt_template)
49
 
 
50
 
51
- # qa_prompt = ChatPromptTemplate.from_messages(messages)
 
 
 
 
 
 
52
 
53
- retriever = vectorstore.as_retriever(
54
- search_type="similarity",
55
- search_kwargs={"k": 2}
56
- )
57
 
 
 
58
  memory = ConversationBufferMemory(
59
- llm=hf_hub_llm,
60
- output_key="answer",
61
  memory_key="chat_history",
62
- return_messages=True
 
63
  )
64
-
65
- chain = ConversationalRetrievalChain.from_llm(
66
- llm=hf_hub_llm,
67
- retriever=retriever,
68
- chain_type="stuff",
 
 
 
 
 
 
 
69
  memory=memory,
70
- verbose=True,
71
- combine_docs_chain_kwargs={"prompt": prompt},
 
72
  )
73
- return chain
74
-
75
- # Streamlit App
76
- st.set_page_config(
77
- page_title="Asisten Kesehatan Wanita",
78
- page_icon="💊",
79
- layout="centered"
80
- )
81
-
82
- st.title("💊 Asisten Kesehatan Wanita")
83
-
84
- if "chat_history" not in st.session_state:
85
- st.session_state.chat_history = []
86
-
87
- if "vectorstore" not in st.session_state:
88
- st.session_state.vectorstore = setup_vectorstore()
89
-
90
- if "conversational_chain" not in st.session_state:
91
- st.session_state.conversational_chain = chat_chain(st.session_state.vectorstore)
92
-
93
- # Display Chat History
94
- for message in st.session_state.chat_history:
95
- with st.chat_message(message["role"]):
96
- st.markdown(message["content"])
97
-
98
- # User Input
99
- user_input = st.chat_input("Tanyakan sesuatu...")
100
 
101
- if user_input:
102
- st.session_state.chat_history.append({"role": "user", "content": user_input})
103
-
104
- with st.chat_message("user"):
105
- st.markdown(user_input)
106
-
107
-
108
- with st.chat_message("assistant"):
109
- response = st.session_state.conversational_chain({"question": user_input})
110
- assistant_response = response["answer"]
111
- st.markdown(assistant_response)
112
- st.session_state.chat_history.append({"role": "assistant", "content": assistant_response})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
 
 
2
  from langchain_huggingface import HuggingFaceEmbeddings
3
  from langchain_community.vectorstores import Chroma
4
+ from langchain_community.llms import HuggingFaceHub
 
5
  from langchain.prompts import PromptTemplate
6
+ from langchain.chains import RetrievalQA, ConversationalRetrievalChain
7
+ from langchain.memory import ConversationBufferMemory
8
+ import warnings
9
+ import os
10
+ from dotenv import load_dotenv
11
+
12
+ warnings.filterwarnings("ignore")
13
+ load_dotenv()
14
+
15
+ # Constants and configurations
16
+ APP_TITLE = "💊 Asisten Kesehatan Feminacare"
17
+ INITIAL_MESSAGE = """Halo! 👋 Saya adalah asisten kesehatan feminacare yang siap membantu Anda dengan informasi seputar kesehatan wanita.
18
+ Silakan ajukan pertanyaan apa saja dan saya akan membantu Anda dengan informasi yang akurat."""
19
+
20
+ # Model configurations
21
+ MODEL_NAME = "meta-llama/Meta-Llama-3-8B-Instruct"
22
+ EMBEDDING_MODEL = "sentence-transformers/all-MiniLM-L6-v2"
23
+ TOP_K_DOCS = 5
24
+
25
+ def initialize_models():
26
+ """Initialize the embedding model and vector store"""
27
+ data_directory = os.path.join(os.path.dirname(__file__), "vector_db_dir")
28
+ embedding_model = HuggingFaceEmbeddings(model_name=EMBEDDING_MODEL)
29
+ vector_store = Chroma(
30
+ embedding_function=embedding_model,
31
+ persist_directory=data_directory
32
+ )
33
+ return vector_store
34
+
35
+ def create_llm():
36
+ """Initialize the language model with optimized parameters"""
37
+ return HuggingFaceHub(
38
+ repo_id=MODEL_NAME,
39
+ model_kwargs={
40
+ "temperature": 0.7, # Balanced between creativity and accuracy
41
+ "max_new_tokens": 1024,
42
+ "top_p": 0.9,
43
+ "frequency_penalty": 0.5
44
+ }
45
  )
46
 
47
+ # Improved prompt template with better context handling and response structure
48
+ PROMPT_TEMPLATE = """
49
+ Anda adalah asisten kesehatan profesional dengan nama Feminacare.
50
+ Berikan informasi yang akurat, jelas, dan bermanfaat berdasarkan konteks yang tersedia.
 
 
51
 
52
+ Context yang tersedia:
53
+ {context}
54
 
55
+ Chat historyt:
56
+ {chat_history}
57
 
58
+ Question: {question}
59
 
60
+ Instruksi untuk menjawab:
61
+ 1. Berikan jawaban yang LENGKAP dan TERSTRUKTUR
62
+ 2. Selalu sertakan SUMBER informasi dari konteks yang diberikan
63
+ 3. Jika informasi tidak tersedia dalam konteks, katakan: "Maaf, saya tidak memiliki informasi yang cukup untuk menjawab pertanyaan tersebut secara akurat. Silakan konsultasi dengan tenaga kesehatan untuk informasi lebih lanjut."
64
+ 4. Gunakan bahasa yang mudah dipahami
65
+ 5. Jika relevan, berikan poin-poin penting menggunakan format yang rapi
66
+ 6. Akhiri dengan anjuran untuk konsultasi dengan tenaga kesehatan jika diperlukan
67
 
68
+ Answer:
69
+ """
 
 
70
 
71
+ def setup_qa_chain(vector_store):
72
+ """Set up the QA chain with improved configuration"""
73
  memory = ConversationBufferMemory(
 
 
74
  memory_key="chat_history",
75
+ return_messages=True,
76
+ output_key='answer'
77
  )
78
+
79
+ custom_prompt = PromptTemplate(
80
+ template=PROMPT_TEMPLATE,
81
+ input_variables=["context", "question", "chat_history"]
82
+ )
83
+
84
+ return ConversationalRetrievalChain.from_llm(
85
+ llm=create_llm(),
86
+ retriever=vector_store.as_retriever(
87
+ # search_type="mmr", # Maximum Marginal Relevance for better diversity
88
+ # search_kwargs={"k": TOP_K_DOCS}
89
+ ),
90
  memory=memory,
91
+ # combine_docs_chain_kwargs={"prompt": custom_prompt},
92
+ return_source_documents=True,
93
+ # return_generated_question=True,
94
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
 
96
+ def initialize_session_state():
97
+ """Initialize Streamlit session state"""
98
+ if "messages" not in st.session_state:
99
+ st.session_state.messages = [
100
+ {"role": "assistant", "content": INITIAL_MESSAGE}
101
+ ]
102
+ if "qa_chain" not in st.session_state:
103
+ vector_store = initialize_models()
104
+ st.session_state.qa_chain = setup_qa_chain(vector_store)
105
+
106
+ def clear_chat():
107
+ """Clear chat history and memory"""
108
+ st.session_state.messages = [
109
+ {"role": "assistant", "content": INITIAL_MESSAGE}
110
+ ]
111
+ st.session_state.qa_chain.memory.clear()
112
+
113
+ def create_ui():
114
+ """Create the Streamlit UI"""
115
+ st.set_page_config(page_title=APP_TITLE, page_icon="💊")
116
+
117
+ # Custom CSS for better UI
118
+ st.markdown("""
119
+ <style>
120
+ .stApp {
121
+ max-width: 1200px;
122
+ margin: 0 auto;
123
+ }
124
+ .stChat {
125
+ border-radius: 10px;
126
+ padding: 20px;
127
+ margin: 10px 0;
128
+ }
129
+ </style>
130
+ """, unsafe_allow_html=True)
131
+
132
+ st.title(APP_TITLE)
133
+
134
+ # Sidebar
135
+ with st.sidebar:
136
+ st.title("ℹ️ Tentang Aplikasi")
137
+ st.markdown("""
138
+ Asisten digital ini dirancang untuk membantu Anda untuk berkonsultasi tentang kesehatan wanita.
139
+
140
+ _Catatan: Informasi yang diberikan bersifat umum. Selalu konsultasikan dengan tenaga kesehatan untuk saran yang lebih spesifik._
141
+ """)
142
+
143
+ st.button('🗑️ Hapus Riwayat Chat', on_click=clear_chat)
144
+
145
+ def handle_user_input(prompt):
146
+ """Handle user input and generate response"""
147
+ try:
148
+ with st.spinner("Sedang menyiapkan jawaban..."):
149
+ response = st.session_state.qa_chain({"question": prompt})
150
+ return response["answer"]
151
+ except Exception as e:
152
+ st.error("Maaf, terjadi kesalahan dalam memproses pertanyaan Anda. Silakan coba lagi.")
153
+ return None
154
+
155
+ def main():
156
+ initialize_session_state()
157
+ create_ui()
158
+
159
+ # Display chat messages
160
+ for message in st.session_state.messages:
161
+ with st.chat_message(message["role"]):
162
+ st.markdown(message["content"])
163
+
164
+ # Handle user input
165
+ if prompt := st.chat_input("Ketik pertanyaan Anda di sini..."):
166
+ st.session_state.messages.append({"role": "user", "content": prompt})
167
+ with st.chat_message("user"):
168
+ st.markdown(prompt)
169
+
170
+ response = handle_user_input(prompt)
171
+ if response:
172
+ with st.chat_message("assistant"):
173
+ st.markdown(response)
174
+ st.session_state.messages.append({"role": "assistant", "content": response})
175
+
176
+ if __name__ == "__main__":
177
+ main()