Spaces:
Runtime error
Runtime error
Upload app.py
Browse files
app.py
CHANGED
@@ -15,6 +15,7 @@ from langchain.prompts import PromptTemplate
|
|
15 |
from langchain.schema import Document
|
16 |
import gradio as gr
|
17 |
import re
|
|
|
18 |
|
19 |
def initialize_llm(api_key):
|
20 |
return ChatGroq(
|
@@ -55,9 +56,9 @@ sources = [
|
|
55 |
"HouseTaxAct1130103.txt",
|
56 |
"VehicleLicenseTaxAct1101230.txt",
|
57 |
"TaxCollectionAct1101217.txt",
|
58 |
-
"AmusementTaxAct960523.txt",
|
59 |
"StampTaxAct910515.txt",
|
60 |
-
"DeedTaxAct990505.txt"
|
|
|
61 |
]
|
62 |
|
63 |
documents = load_documents(sources)
|
@@ -65,7 +66,7 @@ print(f"\n成功載入 {len(documents)} 個網址或檔案")
|
|
65 |
|
66 |
text_splitter = RecursiveCharacterTextSplitter(
|
67 |
chunk_size=512,
|
68 |
-
chunk_overlap=
|
69 |
length_function=len,
|
70 |
is_separator_regex=False,
|
71 |
separators=["\n\n\n","\n\n", "\n", "。"]
|
@@ -146,6 +147,7 @@ def generate_insight_questions(query, api_key):
|
|
146 |
|
147 |
def answer_question(query, api_key):
|
148 |
try:
|
|
|
149 |
llm = initialize_llm(api_key)
|
150 |
chain = create_chain(llm)
|
151 |
result = chain.invoke({"query": query})
|
@@ -183,55 +185,66 @@ def convert_punctuation(text):
|
|
183 |
return text.replace('?', '?').replace(',', ',').replace('!', '!').replace(' ', ' ')
|
184 |
|
185 |
def handle_interaction(query, api_key, state):
|
|
|
|
|
186 |
if state is None:
|
187 |
state = {"history": []}
|
188 |
if not api_key:
|
189 |
-
api_key = os.getenv("
|
190 |
query = convert_punctuation(query)
|
191 |
answer, insight_questions = answer_multiple_questions(query, api_key)
|
192 |
state["history"].append((query, answer))
|
193 |
while len(insight_questions) < 3:
|
194 |
insight_questions.append("提供更多地方稅資訊")
|
|
|
|
|
195 |
return answer, insight_questions[0], insight_questions[1], insight_questions[2], state, query
|
196 |
|
197 |
custom_css = """
|
198 |
-
|
199 |
-
background-color: #
|
|
|
|
|
|
|
200 |
}
|
201 |
-
|
202 |
font-size: 18px !important;
|
203 |
background-color: #ffffff;
|
204 |
-
border: 1px solid #
|
205 |
border-radius: 8px;
|
206 |
}
|
207 |
-
.
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
background-color: #c8e6c9 !important;
|
213 |
-
border-radius: 15px !important;
|
214 |
-
padding: 20px !important;
|
215 |
-
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1) !important;
|
216 |
}
|
217 |
-
.
|
218 |
-
|
219 |
-
|
220 |
-
border
|
221 |
-
|
222 |
-
font-weight: bold !important;
|
223 |
}
|
224 |
-
.
|
225 |
-
|
226 |
-
|
|
|
|
|
227 |
}
|
228 |
#submit-btn {
|
|
|
229 |
background-color: #ff4081 !important;
|
|
|
|
|
|
|
|
|
230 |
}
|
231 |
#submit-btn:hover {
|
232 |
background-color: #f50057 !important;
|
|
|
233 |
}
|
234 |
.insight-btn {
|
|
|
235 |
background-color: #00bcd4 !important;
|
236 |
}
|
237 |
.insight-btn:hover {
|
@@ -243,24 +256,42 @@ body {
|
|
243 |
border-radius: 10px !important;
|
244 |
}
|
245 |
.api-key-input {
|
246 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
247 |
}
|
248 |
"""
|
249 |
|
250 |
with gr.Blocks(theme=gr.themes.Monochrome(), css=custom_css) as iface:
|
251 |
-
gr.Markdown("
|
252 |
-
|
|
|
|
|
253 |
with gr.Row():
|
254 |
-
query_input = gr.Textbox(
|
255 |
-
api_key_input = gr.Textbox(
|
256 |
-
answer_output = gr.Textbox(
|
257 |
with gr.Row():
|
258 |
insight_q1 = gr.Button("洞察問題 1", visible=False, elem_classes=["insight-btn"])
|
259 |
insight_q2 = gr.Button("洞察問題 2", visible=False, elem_classes=["insight-btn"])
|
260 |
insight_q3 = gr.Button("洞察問題 3", visible=False, elem_classes=["insight-btn"])
|
261 |
state = gr.State()
|
262 |
current_question = gr.Textbox(lines=2, label="當前問題", visible=False)
|
263 |
-
|
|
|
|
|
264 |
def update_ui(answer, q1, q2, q3, state, current_q):
|
265 |
return [
|
266 |
answer,
|
@@ -285,9 +316,16 @@ with gr.Blocks(theme=gr.themes.Monochrome(), css=custom_css) as iface:
|
|
285 |
inputs=[btn],
|
286 |
outputs=[query_input]
|
287 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
288 |
|
289 |
if __name__ == "__main__":
|
290 |
if "SPACE_ID" in os.environ:
|
291 |
iface.launch()
|
292 |
else:
|
293 |
-
iface.launch(share=True)
|
|
|
15 |
from langchain.schema import Document
|
16 |
import gradio as gr
|
17 |
import re
|
18 |
+
import time
|
19 |
|
20 |
def initialize_llm(api_key):
|
21 |
return ChatGroq(
|
|
|
56 |
"HouseTaxAct1130103.txt",
|
57 |
"VehicleLicenseTaxAct1101230.txt",
|
58 |
"TaxCollectionAct1101217.txt",
|
|
|
59 |
"StampTaxAct910515.txt",
|
60 |
+
"DeedTaxAct990505.txt",
|
61 |
+
"AmusementTaxAct960523.txt"
|
62 |
]
|
63 |
|
64 |
documents = load_documents(sources)
|
|
|
66 |
|
67 |
text_splitter = RecursiveCharacterTextSplitter(
|
68 |
chunk_size=512,
|
69 |
+
chunk_overlap=52,
|
70 |
length_function=len,
|
71 |
is_separator_regex=False,
|
72 |
separators=["\n\n\n","\n\n", "\n", "。"]
|
|
|
147 |
|
148 |
def answer_question(query, api_key):
|
149 |
try:
|
150 |
+
gr.Info("檢索地方稅知識庫中,請稍待片刻......")
|
151 |
llm = initialize_llm(api_key)
|
152 |
chain = create_chain(llm)
|
153 |
result = chain.invoke({"query": query})
|
|
|
185 |
return text.replace('?', '?').replace(',', ',').replace('!', '!').replace(' ', ' ')
|
186 |
|
187 |
def handle_interaction(query, api_key, state):
|
188 |
+
gr.Info("開始處理問題,請稍待片刻......")
|
189 |
+
start_time = time.time()
|
190 |
if state is None:
|
191 |
state = {"history": []}
|
192 |
if not api_key:
|
193 |
+
api_key = os.getenv("YOUR_API_KEY")
|
194 |
query = convert_punctuation(query)
|
195 |
answer, insight_questions = answer_multiple_questions(query, api_key)
|
196 |
state["history"].append((query, answer))
|
197 |
while len(insight_questions) < 3:
|
198 |
insight_questions.append("提供更多地方稅資訊")
|
199 |
+
end_time = time.time()
|
200 |
+
gr.Info(f"Model 已完成回覆,總執行時間: {(end_time - start_time):.2f} 秒。")
|
201 |
return answer, insight_questions[0], insight_questions[1], insight_questions[2], state, query
|
202 |
|
203 |
custom_css = """
|
204 |
+
.query-input {
|
205 |
+
background-color: #B7E0FF !important;
|
206 |
+
padding: 15px !important;
|
207 |
+
border-radius: 10px !important;
|
208 |
+
margin: 0 !important;
|
209 |
}
|
210 |
+
.query-input textarea {
|
211 |
font-size: 18px !important;
|
212 |
background-color: #ffffff;
|
213 |
+
border: 1px solid #f0f8ff;
|
214 |
border-radius: 8px;
|
215 |
}
|
216 |
+
.answer-box {
|
217 |
+
background-color: #FFF5CD !important;
|
218 |
+
padding: 10px !important;
|
219 |
+
border-radius: 10px !important;
|
220 |
+
margin: 0 !important;
|
|
|
|
|
|
|
|
|
221 |
}
|
222 |
+
.answer-box textarea {
|
223 |
+
font-size: 18px !important;
|
224 |
+
background-color: #ffffff;
|
225 |
+
border: 1px solid #f0f8ff;
|
226 |
+
border-radius: 8px;
|
|
|
227 |
}
|
228 |
+
.center-text {
|
229 |
+
text-align: center !important;
|
230 |
+
color: #ff4081;
|
231 |
+
text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
|
232 |
+
margin-bottom: 0 !important;
|
233 |
}
|
234 |
#submit-btn {
|
235 |
+
border-radius: 10px !important;
|
236 |
background-color: #ff4081 !important;
|
237 |
+
color: white !important;
|
238 |
+
font-weight: bold !important;
|
239 |
+
transition: all 0.3s ease !important;
|
240 |
+
margin: 0 !important;
|
241 |
}
|
242 |
#submit-btn:hover {
|
243 |
background-color: #f50057 !important;
|
244 |
+
transform: scale(1.05);
|
245 |
}
|
246 |
.insight-btn {
|
247 |
+
border-radius: 10px !important;
|
248 |
background-color: #00bcd4 !important;
|
249 |
}
|
250 |
.insight-btn:hover {
|
|
|
256 |
border-radius: 10px !important;
|
257 |
}
|
258 |
.api-key-input {
|
259 |
+
background-color: #FFCFB3 !important;
|
260 |
+
padding: 15px !important;
|
261 |
+
border-radius: 10px !important;
|
262 |
+
margin: 0 !important;
|
263 |
+
}
|
264 |
+
.clear-button {
|
265 |
+
color: white !important;
|
266 |
+
background-color: #000000 !important;
|
267 |
+
padding: 5px !important;
|
268 |
+
border-radius: 10px !important;
|
269 |
+
margin: 0 !important;
|
270 |
+
}
|
271 |
+
.clear-button:hover {
|
272 |
+
background-color: #000000 !important;
|
273 |
+
transform: scale(1.05);
|
274 |
}
|
275 |
"""
|
276 |
|
277 |
with gr.Blocks(theme=gr.themes.Monochrome(), css=custom_css) as iface:
|
278 |
+
gr.Markdown("""
|
279 |
+
# 地方稅知識庫系統 - 財政部財政資訊中心
|
280 |
+
> ### **※ RAG-based 系統部署:江信宗,LLM:Llama-3.1-70B,以地方稅極少知識資料示範,僅供參考,準確資訊請依據地方稅稽徵機關回覆為準。**
|
281 |
+
""", elem_classes="center-text")
|
282 |
with gr.Row():
|
283 |
+
query_input = gr.Textbox(label="輸入您的問題,系統將基於學習到的知識資料提供相關答案。", placeholder="請輸入您的問題(支援同時輸入多個問題,例如:問題1?問題2?)", scale=3, elem_classes="query-input")
|
284 |
+
api_key_input = gr.Textbox(label="請輸入您的 API Key", type="password", placeholder="API authentication key", scale=1, elem_classes="api-key-input")
|
285 |
+
answer_output = gr.Textbox(label="答案:", max_lines=40, elem_classes="answer-box")
|
286 |
with gr.Row():
|
287 |
insight_q1 = gr.Button("洞察問題 1", visible=False, elem_classes=["insight-btn"])
|
288 |
insight_q2 = gr.Button("洞察問題 2", visible=False, elem_classes=["insight-btn"])
|
289 |
insight_q3 = gr.Button("洞察問題 3", visible=False, elem_classes=["insight-btn"])
|
290 |
state = gr.State()
|
291 |
current_question = gr.Textbox(lines=2, label="當前問題", visible=False)
|
292 |
+
with gr.Row():
|
293 |
+
submit_btn = gr.Button("傳送", variant="primary", scale=3, elem_id="submit-btn")
|
294 |
+
clear_button = gr.Button("清除", variant="secondary", scale=1, elem_classes="clear-button")
|
295 |
def update_ui(answer, q1, q2, q3, state, current_q):
|
296 |
return [
|
297 |
answer,
|
|
|
316 |
inputs=[btn],
|
317 |
outputs=[query_input]
|
318 |
)
|
319 |
+
def clear_outputs():
|
320 |
+
return "", ""
|
321 |
+
clear_button.click(
|
322 |
+
fn=clear_outputs,
|
323 |
+
inputs=[],
|
324 |
+
outputs=[query_input, answer_output]
|
325 |
+
)
|
326 |
|
327 |
if __name__ == "__main__":
|
328 |
if "SPACE_ID" in os.environ:
|
329 |
iface.launch()
|
330 |
else:
|
331 |
+
iface.launch(share=True, show_api=False)
|