Davidtran99
commited on
Commit
·
c5e03e2
1
Parent(s):
d320689
Update: Bypass LLM logic và tăng n_ctx lên 8192
Browse files
backend/hue_portal/chatbot/llm_integration.py
CHANGED
|
@@ -464,7 +464,7 @@ class LLMGenerator:
|
|
| 464 |
logger.error("Unable to resolve GGUF model path for llama.cpp")
|
| 465 |
return
|
| 466 |
|
| 467 |
-
n_ctx = int(os.environ.get("LLAMA_CPP_CONTEXT", "
|
| 468 |
n_threads = int(os.environ.get("LLAMA_CPP_THREADS", str(max(1, os.cpu_count() or 2))))
|
| 469 |
n_batch = int(os.environ.get("LLAMA_CPP_BATCH", "512"))
|
| 470 |
n_gpu_layers = int(os.environ.get("LLAMA_CPP_GPU_LAYERS", "0"))
|
|
|
|
| 464 |
logger.error("Unable to resolve GGUF model path for llama.cpp")
|
| 465 |
return
|
| 466 |
|
| 467 |
+
n_ctx = int(os.environ.get("LLAMA_CPP_CONTEXT", "8192"))
|
| 468 |
n_threads = int(os.environ.get("LLAMA_CPP_THREADS", str(max(1, os.cpu_count() or 2))))
|
| 469 |
n_batch = int(os.environ.get("LLAMA_CPP_BATCH", "512"))
|
| 470 |
n_gpu_layers = int(os.environ.get("LLAMA_CPP_GPU_LAYERS", "0"))
|
backend/hue_portal/chatbot/slow_path_handler.py
CHANGED
|
@@ -107,6 +107,82 @@ class SlowPathHandler:
|
|
| 107 |
except Exception as e:
|
| 108 |
logger.warning("[RERANKER] Reranking failed: %s, using original results", e)
|
| 109 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
# Get conversation context if available
|
| 111 |
context = None
|
| 112 |
if session_id:
|
|
@@ -150,11 +226,36 @@ class SlowPathHandler:
|
|
| 150 |
# Fallback to template if LLM not available or failed
|
| 151 |
if not message:
|
| 152 |
if search_result["count"] > 0:
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
else:
|
| 159 |
message = RESPONSE_TEMPLATES["no_results"].format(query=query)
|
| 160 |
|
|
|
|
| 107 |
except Exception as e:
|
| 108 |
logger.warning("[RERANKER] Reranking failed: %s, using original results", e)
|
| 109 |
|
| 110 |
+
# BƯỚC 1: Bypass LLM khi có results tốt (tránh context overflow + tăng tốc 30-40%)
|
| 111 |
+
# Chỉ áp dụng cho legal queries có results với score cao
|
| 112 |
+
if intent == "search_legal" and search_result["count"] > 0:
|
| 113 |
+
top_result = search_result["results"][0]
|
| 114 |
+
top_score = top_result.get("score", 0.0) or 0.0
|
| 115 |
+
top_data = top_result.get("data", {})
|
| 116 |
+
doc_code = (top_data.get("document_code") or "").upper()
|
| 117 |
+
content = top_data.get("content", "") or top_data.get("excerpt", "")
|
| 118 |
+
|
| 119 |
+
# Bypass LLM nếu:
|
| 120 |
+
# 1. Có document code (TT-02-CAND, etc.) và content đủ dài
|
| 121 |
+
# 2. Score >= 0.4 (giảm threshold để dễ trigger hơn)
|
| 122 |
+
# 3. Hoặc có keywords quan trọng (%, hạ bậc, thi đua, tỷ lệ) với score >= 0.3
|
| 123 |
+
should_bypass = False
|
| 124 |
+
query_lower = query.lower()
|
| 125 |
+
has_keywords = any(kw in query_lower for kw in ["%", "phần trăm", "tỷ lệ", "12%", "20%", "10%", "hạ bậc", "thi đua", "xếp loại", "vi phạm", "cán bộ"])
|
| 126 |
+
|
| 127 |
+
# Điều kiện bypass dễ hơn: có doc_code + content đủ dài + score hợp lý
|
| 128 |
+
if doc_code and len(content) > 100:
|
| 129 |
+
if top_score >= 0.4:
|
| 130 |
+
should_bypass = True
|
| 131 |
+
elif has_keywords and top_score >= 0.3:
|
| 132 |
+
should_bypass = True
|
| 133 |
+
# Hoặc có keywords quan trọng + content đủ dài
|
| 134 |
+
elif has_keywords and len(content) > 100 and top_score >= 0.3:
|
| 135 |
+
should_bypass = True
|
| 136 |
+
|
| 137 |
+
if should_bypass:
|
| 138 |
+
# Template trả thẳng cho query về tỷ lệ vi phạm + hạ bậc thi đua
|
| 139 |
+
if any(kw in query_lower for kw in ["12%", "tỷ lệ", "phần trăm", "hạ bậc", "thi đua"]):
|
| 140 |
+
# Query về tỷ lệ vi phạm và hạ bậc thi đua
|
| 141 |
+
section_code = top_data.get("section_code", "")
|
| 142 |
+
section_title = top_data.get("section_title", "")
|
| 143 |
+
doc_title = top_data.get("document_title", "văn bản pháp luật")
|
| 144 |
+
|
| 145 |
+
# Trích xuất đoạn liên quan từ content
|
| 146 |
+
content_preview = content[:600] + "..." if len(content) > 600 else content
|
| 147 |
+
|
| 148 |
+
answer = (
|
| 149 |
+
f"Theo {doc_title} ({doc_code}):\n\n"
|
| 150 |
+
f"{section_code}: {section_title}\n\n"
|
| 151 |
+
f"{content_preview}\n\n"
|
| 152 |
+
f"Nguồn: {section_code}, {doc_title} ({doc_code})"
|
| 153 |
+
)
|
| 154 |
+
else:
|
| 155 |
+
# Template chung cho legal queries
|
| 156 |
+
section_code = top_data.get("section_code", "Điều liên quan")
|
| 157 |
+
section_title = top_data.get("section_title", "")
|
| 158 |
+
doc_title = top_data.get("document_title", "văn bản pháp luật")
|
| 159 |
+
content_preview = content[:500] + "..." if len(content) > 500 else content
|
| 160 |
+
|
| 161 |
+
answer = (
|
| 162 |
+
f"Kết quả chính xác nhất:\n\n"
|
| 163 |
+
f"- Văn bản: {doc_title} ({doc_code})\n"
|
| 164 |
+
f"- Điều khoản: {section_code}" + (f" – {section_title}" if section_title else "") + "\n\n"
|
| 165 |
+
f"{content_preview}\n\n"
|
| 166 |
+
f"Nguồn: {section_code}, {doc_title} ({doc_code})"
|
| 167 |
+
)
|
| 168 |
+
|
| 169 |
+
logger.info(
|
| 170 |
+
"[BYPASS_LLM] Using raw template for legal query (score=%.3f, doc=%s, query='%s')",
|
| 171 |
+
top_score,
|
| 172 |
+
doc_code,
|
| 173 |
+
query[:50]
|
| 174 |
+
)
|
| 175 |
+
|
| 176 |
+
return {
|
| 177 |
+
"message": answer,
|
| 178 |
+
"intent": intent,
|
| 179 |
+
"confidence": min(0.99, top_score + 0.05),
|
| 180 |
+
"results": search_result["results"][:3],
|
| 181 |
+
"count": min(3, search_result["count"]),
|
| 182 |
+
"_source": "raw_template",
|
| 183 |
+
"routing": "raw_template"
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
# Get conversation context if available
|
| 187 |
context = None
|
| 188 |
if session_id:
|
|
|
|
| 226 |
# Fallback to template if LLM not available or failed
|
| 227 |
if not message:
|
| 228 |
if search_result["count"] > 0:
|
| 229 |
+
# Đặc biệt xử lý legal queries: format tốt hơn thay vì dùng template chung
|
| 230 |
+
if intent == "search_legal" and search_result["results"]:
|
| 231 |
+
top_result = search_result["results"][0]
|
| 232 |
+
top_data = top_result.get("data", {})
|
| 233 |
+
doc_code = top_data.get("document_code", "")
|
| 234 |
+
doc_title = top_data.get("document_title", "văn bản pháp luật")
|
| 235 |
+
section_code = top_data.get("section_code", "")
|
| 236 |
+
section_title = top_data.get("section_title", "")
|
| 237 |
+
content = top_data.get("content", "") or top_data.get("excerpt", "")
|
| 238 |
+
|
| 239 |
+
if content and len(content) > 50:
|
| 240 |
+
content_preview = content[:400] + "..." if len(content) > 400 else content
|
| 241 |
+
message = (
|
| 242 |
+
f"Tôi tìm thấy {search_result['count']} điều khoản liên quan đến '{query}':\n\n"
|
| 243 |
+
f"**{section_code}**: {section_title or 'Nội dung liên quan'}\n\n"
|
| 244 |
+
f"{content_preview}\n\n"
|
| 245 |
+
f"Nguồn: {doc_title}" + (f" ({doc_code})" if doc_code else "")
|
| 246 |
+
)
|
| 247 |
+
else:
|
| 248 |
+
template = RESPONSE_TEMPLATES.get(intent, RESPONSE_TEMPLATES["general_query"])
|
| 249 |
+
message = template.format(
|
| 250 |
+
count=search_result["count"],
|
| 251 |
+
query=query
|
| 252 |
+
)
|
| 253 |
+
else:
|
| 254 |
+
template = RESPONSE_TEMPLATES.get(intent, RESPONSE_TEMPLATES["general_query"])
|
| 255 |
+
message = template.format(
|
| 256 |
+
count=search_result["count"],
|
| 257 |
+
query=query
|
| 258 |
+
)
|
| 259 |
else:
|
| 260 |
message = RESPONSE_TEMPLATES["no_results"].format(query=query)
|
| 261 |
|