SiangKai commited on
Commit
6bb244a
·
verified ·
1 Parent(s): a76bb8c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +3 -195
app.py CHANGED
@@ -154,7 +154,7 @@ def batch_find_relevant_tables(api_key: str, sub_queries: list[str], top_k: int
154
  # 為每個子問題找回 20 個最相關的候選表
155
  candidates_per_query = extract_project_names_from_rag_manual_mix(query, db_jb, db_sim, top_k=20)
156
  # test
157
- print(candidates_per_query)
158
 
159
  if candidates_per_query: # 只加入有找到候選表的查詢
160
  query_to_candidates_map[query] = candidates_per_query
@@ -369,43 +369,6 @@ semantic_query_tool = StructuredTool.from_function(
369
  # =======================================================================
370
  # 4. 主要執行流程 (Reflect)
371
  # =======================================================================
372
- # system_reviewer = """
373
- # 你是語意分析專家,請將使用者的複雜問題拆解成具體子問題,並判斷每個子問題的查詢類型。
374
-
375
- # ⚠️ 拆解前請先檢查以下條件:
376
- # 1. 涉及高雄市以外或全國性資料,請直接回傳:「抱歉~我是高雄市查詢機器人,無法查詢高雄以外資料。」
377
- # 2. 未提及明確時間(如112年、113年3月),請回傳:「抱歉~請問查詢的資料時間。」
378
- # 📌 明確時間=出現「具體年份」、「年月」、「季」或「學年」。模糊詞(平均、近年、目前、歷年等)皆視為未指定。
379
-
380
- # 📌 回傳格式(**僅限 JSON 陣列**,不得加上任何文字):
381
- # [
382
- # {
383
- # "sub_query": "子問題內容(不得遺漏任何原始資訊)",
384
- # "type": "direct" 或 "comparison"
385
- # }
386
- # ]
387
-
388
- # 📌 類型說明:
389
- # - 可直接查詢者為 "direct"
390
- # - 涉及比較、推論、排序者為 "comparison"
391
-
392
- # 📍 行政區關鍵詞(出現以下詞應視為涉及全部行政區):
393
- # - 關鍵詞:"各行政區", "所有行政區", "全體行政區", "人口最多", "人口最少"
394
- # - 對應行政區如下:
395
- # kaohsiung_districts = ["鹽埕區", "鼓山區", "左營區", "楠梓區", "三民區", "新興區", "前金區", "苓雅區", "前鎮區", "旗津區", "小港區", "鳳山區", "林園區", "大寮區", "大樹區", "大社區", "仁武區", "鳥松區", "岡山區", "橋頭區", "燕巢區", "田寮區", "阿蓮區", "路竹區", "湖內區", "茄萣區", "永安區", "彌陀區", "梓官區", "旗山區", "美濃區", "六龜區", "甲仙區", "杉林區", "內門區", "茂林區", "桃源區", "那瑪夏區"]
396
-
397
- # 📌 子問題拆解規則:
398
- # - 每個子問題必須包含 1 個「地點」、1 個「時間」、1 個「指標」
399
- # - 若同時包含多個時間、地區或指標,請拆成多筆(如:110-113年、1至3月 都要拆開)
400
- # - 若內容有年齡區間如20-24歲,則不必拆分
401
- # - ⛔ 禁止省略使用者輸入中的任何關鍵詞(例如:「人口數合計」的「合計」也不得省略)
402
-
403
- # 📤 僅允許輸出:
404
- # - JSON 陣列格式,禁止加說明文字
405
- # - 禁用「...」,子問題必須完整列出
406
- # - 回應必須為繁體中文
407
- # """
408
-
409
  system_reviewer = """
410
  你是語意分析專家,請將使用者的複雜問題拆解成具體子問題,並判斷每個子問題的查詢類型。
411
 
@@ -534,165 +497,9 @@ def extract_json(text: str) -> list | dict:
534
  except json.JSONDecodeError as e:
535
  raise ValueError(f"清理後仍然無法解析 JSON。原始錯誤: {e}")
536
 
537
-
538
- # def reflect_post(api_key, api_key2, api_key3, api_key4, user_input):
539
- # """
540
- # API 呼叫總次數固定為 4 次。
541
- # """
542
- # # Step 1:拆解子問題 (API Call #1)
543
- # decomposed_text = reply(api_key, system_reviewer, user_input)
544
- # if "抱歉~" in decomposed_text:
545
- # return "", decomposed_text
546
- # try:
547
- # parsed_list = extract_json(decomposed_text)
548
- # if not isinstance(parsed_list, list): raise ValueError("回傳的不是列表格式")
549
- # except Exception as e:
550
- # return "", f"⚠️ 查詢意圖格式錯誤:{e}"
551
-
552
- # direct_queries = [item for item in parsed_list if item.get("type") == "direct"]
553
- # if not direct_queries:
554
- # return "", "⚠️ 無法從輸入問題中擷取有效查詢項目。"
555
-
556
- # all_querys_summary = "🔹 關鍵查詢:\n" + "\n".join(f"- {q['sub_query']}" for q in direct_queries)
557
-
558
- # sub_query_texts = [q["sub_query"] for q in direct_queries]
559
-
560
- # # Step 2:批次匹配表名 (API Call #2)
561
- # table_map = batch_find_relevant_tables(api_key2, sub_query_texts)
562
- # if not table_map:
563
- # return all_querys_summary, "⚠️ 系統無法為您的查詢匹配到合適的資料表。"
564
-
565
- # # Step 3: 批次解析所有子問題的參數 (API Call #3)
566
- # params_map = batch_parse_sub_queries_with_gemini(api_key3, sub_query_texts)
567
- # if not params_map:
568
- # return all_querys_summary, "⚠️ 系統無法解析您問題中的查詢參數。"
569
-
570
- # # Step 4:逐一執行查詢 (零 API 呼叫)
571
- # context_list = []
572
- # for q in direct_queries:
573
- # sub_query = q["sub_query"]
574
- # table_name = table_map.get(sub_query)
575
- # params = params_map.get(sub_query)
576
-
577
- # if not table_name or not params:
578
- # context_list.append(f"【{sub_query}】\n查詢失敗:未能匹配到資料表或解析參數。")
579
- # continue
580
-
581
- # try:
582
- # # 帶著所有精準參數執行查詢
583
- # result_json = semantic_query_logic(
584
- # time_query=params.get("time_query", ""),
585
- # item_query=params.get("item_query", ""),
586
- # district_query=params.get("district_query", ""),
587
- # project_name=table_name
588
- # )
589
- # result_data = json.loads(result_json)
590
- # if result_data:
591
- # formatted_result = json.dumps(result_data, ensure_ascii=False, indent=2)
592
- # context_list.append(f"【{sub_query}】\n查詢結果:\n{formatted_result}")
593
- # else:
594
- # context_list.append(f"【{sub_query}】\n查無資料。")
595
- # except Exception as e:
596
- # context_list.append(f"【{sub_query}】\n查詢失敗:{e}")
597
-
598
- # combined_context = "\n\n".join(context_list)
599
-
600
- # # Step 5:整合分析 (API Call #4)
601
- # integration_prompt = f"使用者問題:{user_input}\n\n查詢資料如下:\n{combined_context}"
602
- # integration_result = reply(api_key4, system_integration, integration_prompt)
603
- # return all_querys_summary, integration_result
604
-
605
  # =======================================================================
606
  # 5. Gradio Web UI
607
  # =======================================================================
608
-
609
- # def gradio_interface(user_input):
610
- # """Gradio 主要處理函式"""
611
- # api_key = os.getenv('Gemini')
612
- # api_key2 = os.getenv('Gemini2')
613
- # api_key3 = os.getenv('Gemini3')
614
- # api_key4 = os.getenv('Gemini4')
615
-
616
- # if not api_key:
617
- # return "❌ 查詢失敗", "錯誤:未在伺服器環境中設定 'Gemini' API 金鑰。"
618
-
619
- # # 檢查向量資料庫是否成功載入
620
- # if not db_jb or not db_sim:
621
- # return "❌ 系統錯誤", "向量資料庫未成功載入,請檢查伺服器日誌。"
622
-
623
- # try:
624
- # analysis_text, final_result = reflect_post(api_key, api_key2, api_key3, api_key4, user_input)
625
- # return analysis_text, final_result
626
- # except Exception as e:
627
- # # 捕捉預期外的錯誤
628
- # import traceback
629
- # print(traceback.format_exc()) # 在後台印出詳細錯誤
630
- # return "❌ 查詢失敗", f"發生未預期的系統錯誤:{str(e)}"
631
-
632
- # # --- UI 介面定義 ---
633
- # with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="orange")) as demo:
634
- # gr.Markdown(
635
- # """
636
- # # 🤖 高雄市公務統計資料智慧查詢
637
- # 歡迎使用!您可以透過自然語言提出關於高雄市的公務統計問題,系統將盡力為您查找相關資訊。
638
- # 本系統運作於2v cpu & 16 GB RAM 免費資源,系統速度稍慢(產生結果時間依問題複雜度而定,一般為10至15秒)。
639
- # """
640
- # )
641
-
642
- # with gr.Row():
643
- # with gr.Column(scale=1):
644
- # user_input_box = gr.Textbox(
645
- # label="請在此輸入您的問題",
646
- # placeholder="例如:113年底前金區人口數?",
647
- # lines=5
648
- # )
649
- # gr.Examples(
650
- # examples=[
651
- # "113年底前金區人口數?",
652
- # "110-113年高雄市總人口數趨勢?",
653
- # "110-113年失業率情形",
654
- # "113學年國小一年級學生人數",
655
- # "113年底鹽埕區、三民區、前鎮區、林園區及美濃區人口數",
656
- # "107年勞工教育班數",
657
- # "112年路竹區門診體驗人數",
658
- # "113學年國立大學教師數",
659
- # "105年公共污水下水道當年接管戶數",
660
- # "113年三民區人口數及該區身心障礙人數"
661
- # ],
662
- # inputs=user_input_box,
663
- # label="💡 範例問題"
664
- # )
665
- # with gr.Row():
666
- # btn_clear = gr.ClearButton(value="清除")
667
- # btn_submit = gr.Button("送出查詢", variant="primary")
668
-
669
- # with gr.Column(scale=1):
670
- # output_analysis = gr.Textbox(
671
- # label="🌟 問題分析",
672
- # interactive=False,
673
- # lines=6,
674
- # visible=False,
675
- # )
676
- # output_result = gr.Textbox(
677
- # label="🧐 查詢結果",
678
- # interactive=False,
679
- # lines=10,
680
- # )
681
-
682
- # gr.Markdown(
683
- # """
684
- # ---
685
- # *資料來源:[高雄市政府主計處](https://kcgdg.kcg.gov.tw/StatWebRWD/Page/Default.aspx)*
686
- # *本工具由 AI 驅動,查詢結果僅供參考。*
687
- # """
688
- # )
689
-
690
- # # --- 事件���定 ---
691
- # outputs_list = [output_analysis, output_result]
692
- # btn_submit.click(fn=gradio_interface, inputs=user_input_box, outputs=outputs_list)
693
- # user_input_box.submit(fn=gradio_interface, inputs=user_input_box, outputs=outputs_list)
694
- # btn_clear.add([user_input_box] + outputs_list)
695
-
696
  def gradio_interface(user_input):
697
  """Gradio 主要處理函式"""
698
  api_key = os.getenv('Gemini')
@@ -838,7 +645,8 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="orange"),
838
  "112年路竹區門診體驗人數",
839
  "113學年國立大學教師數",
840
  "105年公共污水下水道當年接管戶數",
841
- "113年三民區人口數及該區身心障礙人數"
 
842
  ],
843
  inputs=user_input_box,
844
  label="💡 範例問題"
 
154
  # 為每個子問題找回 20 個最相關的候選表
155
  candidates_per_query = extract_project_names_from_rag_manual_mix(query, db_jb, db_sim, top_k=20)
156
  # test
157
+ # print(candidates_per_query)
158
 
159
  if candidates_per_query: # 只加入有找到候選表的查詢
160
  query_to_candidates_map[query] = candidates_per_query
 
369
  # =======================================================================
370
  # 4. 主要執行流程 (Reflect)
371
  # =======================================================================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
372
  system_reviewer = """
373
  你是語意分析專家,請將使用者的複雜問題拆解成具體子問題,並判斷每個子問題的查詢類型。
374
 
 
497
  except json.JSONDecodeError as e:
498
  raise ValueError(f"清理後仍然無法解析 JSON。原始錯誤: {e}")
499
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
500
  # =======================================================================
501
  # 5. Gradio Web UI
502
  # =======================================================================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
503
  def gradio_interface(user_input):
504
  """Gradio 主要處理函式"""
505
  api_key = os.getenv('Gemini')
 
645
  "112年路竹區門診體驗人數",
646
  "113學年國立大學教師數",
647
  "105年公共污水下水道當年接管戶數",
648
+ "113年三民區人口數及該區身心障礙人數",
649
+ "113年高雄市各行政區中哪一區人口最多"
650
  ],
651
  inputs=user_input_box,
652
  label="💡 範例問題"