Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -231,7 +231,7 @@ class TextToSQLSystem:
|
|
| 231 |
output = self.llm(
|
| 232 |
prompt,
|
| 233 |
max_tokens=150,
|
| 234 |
-
temperature=0.
|
| 235 |
top_p=0.9,
|
| 236 |
echo=False,
|
| 237 |
# --- 將 stop 參數加回來 ---
|
|
@@ -240,13 +240,25 @@ class TextToSQLSystem:
|
|
| 240 |
|
| 241 |
self._log(f"🧠 模型原始輸出 (Raw Output): {output}", "DEBUG")
|
| 242 |
|
|
|
|
| 243 |
if output and "choices" in output and len(output["choices"]) > 0:
|
| 244 |
-
generated_text = output["choices"][
|
| 245 |
self._log(f"📝 提取出的生成文本: {generated_text.strip()}", "DEBUG")
|
| 246 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 247 |
else:
|
| 248 |
self._log("❌ 模型的原始輸出格式不正確或為空。", "ERROR")
|
| 249 |
-
return ""
|
| 250 |
|
| 251 |
except Exception as e:
|
| 252 |
self._log(f"❌ 模型生成過程中發生嚴重錯誤: {e}", "CRITICAL")
|
|
@@ -693,11 +705,10 @@ class TextToSQLSystem:
|
|
| 693 |
|
| 694 |
# 使用強分隔符和清晰的標題來構建 prompt
|
| 695 |
prompt = f"""### INSTRUCTIONS ###
|
| 696 |
-
You are a SQLite
|
| 697 |
-
-
|
| 698 |
-
-
|
| 699 |
-
- The
|
| 700 |
-
- Your output MUST be ONLY the SQL query inside a ```sql code block.
|
| 701 |
|
| 702 |
### SCHEMA ###
|
| 703 |
{schema_str}
|
|
@@ -771,30 +782,46 @@ SQL:
|
|
| 771 |
self.log_history = []
|
| 772 |
self._log(f"⏰ 處理問題: {question}")
|
| 773 |
|
| 774 |
-
# 1. 檢索相似範例
|
| 775 |
-
self._log("🔍 尋找相似範例...")
|
| 776 |
-
examples = self.find_most_similar(question, FEW_SHOT_EXAMPLES_COUNT)
|
| 777 |
-
if examples: self._log(f"✅ 找到 {len(examples)} 個相似範例")
|
| 778 |
|
| 779 |
-
# 2
|
| 780 |
-
|
| 781 |
-
prompt = self._build_prompt(question, examples)
|
| 782 |
|
| 783 |
-
|
| 784 |
-
|
| 785 |
-
|
|
|
|
|
|
|
| 786 |
|
| 787 |
-
|
| 788 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 789 |
|
| 790 |
-
if final_sql:
|
| 791 |
-
result = (final_sql, status_message)
|
| 792 |
-
else:
|
| 793 |
-
result = (status_message, "生成失敗")
|
| 794 |
|
| 795 |
-
|
| 796 |
-
|
| 797 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 798 |
|
| 799 |
# ==================== Gradio 介面 ====================
|
| 800 |
text_to_sql_system = TextToSQLSystem()
|
|
|
|
| 231 |
output = self.llm(
|
| 232 |
prompt,
|
| 233 |
max_tokens=150,
|
| 234 |
+
temperature=0.05,
|
| 235 |
top_p=0.9,
|
| 236 |
echo=False,
|
| 237 |
# --- 將 stop 參數加回來 ---
|
|
|
|
| 240 |
|
| 241 |
self._log(f"🧠 模型原始輸出 (Raw Output): {output}", "DEBUG")
|
| 242 |
|
| 243 |
+
|
| 244 |
if output and "choices" in output and len(output["choices"]) > 0:
|
| 245 |
+
generated_text = output["choices"]["text"]
|
| 246 |
self._log(f"📝 提取出的生成文本: {generated_text.strip()}", "DEBUG")
|
| 247 |
+
|
| 248 |
+
# --- 新增的清理邏輯 ---
|
| 249 |
+
lines = generated_text.strip().split('\n')
|
| 250 |
+
# 過濾掉所有以 '--' 開頭的註解行
|
| 251 |
+
non_comment_lines = [line for line in lines if not line.strip().startswith('--')]
|
| 252 |
+
cleaned_text = "\n".join(non_comment_lines).strip()
|
| 253 |
+
|
| 254 |
+
if cleaned_text != generated_text.strip():
|
| 255 |
+
self._log(f"🧹 清理掉註解後的文本: {cleaned_text}", "DEBUG")
|
| 256 |
+
|
| 257 |
+
return cleaned_text # <-- 返回清理後的文本
|
| 258 |
+
# --- 清理邏輯結束 ---
|
| 259 |
else:
|
| 260 |
self._log("❌ 模型的原始輸出格式不正確或為空。", "ERROR")
|
| 261 |
+
return ""
|
| 262 |
|
| 263 |
except Exception as e:
|
| 264 |
self._log(f"❌ 模型生成過程中發生嚴重錯誤: {e}", "CRITICAL")
|
|
|
|
| 705 |
|
| 706 |
# 使用強分隔符和清晰的標題來構建 prompt
|
| 707 |
prompt = f"""### INSTRUCTIONS ###
|
| 708 |
+
You are a SQLite code generation machine. Your SOLE PURPOSE is to generate a single, valid SQLite query.
|
| 709 |
+
- DO NOT provide any explanations, comments, or introductory text.
|
| 710 |
+
- Your response MUST start directly with ```sql and end with ```.
|
| 711 |
+
- The output must be ONLY the SQL code. Any other text is a failure.
|
|
|
|
| 712 |
|
| 713 |
### SCHEMA ###
|
| 714 |
{schema_str}
|
|
|
|
| 782 |
self.log_history = []
|
| 783 |
self._log(f"⏰ 處理問題: {question}")
|
| 784 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 785 |
|
| 786 |
+
for attempt in range(2): # --- 新增:最多嘗試 2 次 ---
|
| 787 |
+
self._log(f"🚀 開始第 {attempt + 1} 次嘗試...")
|
|
|
|
| 788 |
|
| 789 |
+
# 1. 檢索相似範例 (第二次嘗試時不再重複)
|
| 790 |
+
if attempt == 0:
|
| 791 |
+
self._log("🔍 尋找相似範例...")
|
| 792 |
+
examples = self.find_most_similar(question, FEW_SHOT_EXAMPLES_COUNT)
|
| 793 |
+
if examples: self._log(f"✅ 找到 {len(examples)} 個相似範例")
|
| 794 |
|
| 795 |
+
# 2. 建立提示詞
|
| 796 |
+
self._log("📝 建立 Prompt...")
|
| 797 |
+
prompt = self._build_prompt(question, examples)
|
| 798 |
+
|
| 799 |
+
# --- 新增:如果是第二次嘗試,加入修正指令 ---
|
| 800 |
+
if attempt > 0:
|
| 801 |
+
correction_prompt = "\nYour previous attempt failed because you did not provide a valid SQL query. REMEMBER: ONLY output the SQL code inside a ```sql block. DO NOT write comments or explanations.\nSQL:\n```sql\n"
|
| 802 |
+
# 將原本 prompt 的結尾替換成我們的修正指令
|
| 803 |
+
prompt = prompt.rsplit("SQL:\n```sql", 1)[0] + correction_prompt
|
| 804 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 805 |
|
| 806 |
+
# 3. 生成 AI 回應
|
| 807 |
+
self._log("🧠 開始生成 AI 回應...")
|
| 808 |
+
response = self.huggingface_api_call(prompt)
|
| 809 |
+
|
| 810 |
+
# 4. 驗證與生成
|
| 811 |
+
final_sql, status_message = self._validate_and_fix_sql(question, response)
|
| 812 |
+
|
| 813 |
+
if final_sql:
|
| 814 |
+
self._log(f"✅ 在第 {attempt + 1} 次嘗試成功!", "INFO")
|
| 815 |
+
result = (final_sql, status_message)
|
| 816 |
+
self.query_cache[question] = result # 緩存成功結果
|
| 817 |
+
return result
|
| 818 |
+
|
| 819 |
+
self._log(f"❌ 第 {attempt + 1} 次嘗試失敗。原因: {status_message}", "WARNING")
|
| 820 |
+
|
| 821 |
+
# --- 如果兩次都失敗 ---
|
| 822 |
+
self._log("❌ 所有嘗試均失敗,返回錯誤訊息。", "ERROR")
|
| 823 |
+
final_fallback_message = "模型多次嘗試後仍無法生成有效的SQL。"
|
| 824 |
+
return (final_fallback_message, "生成失敗")
|
| 825 |
|
| 826 |
# ==================== Gradio 介面 ====================
|
| 827 |
text_to_sql_system = TextToSQLSystem()
|