hue-portal-backend-v2 / backend /chatbot /advanced_features.py
davidtran999's picture
Upload backend/chatbot/advanced_features.py with huggingface_hub
31f8e67 verified
"""
Advanced features for chatbot: follow-up suggestions, ambiguity detection, explanations.
"""
from typing import List, Dict, Any, Optional
from hue_portal.core.models import Fine, Procedure, Office, Advisory
def suggest_follow_up_questions(query: str, results: List[Any], intent: str) -> List[str]:
"""
Suggest follow-up questions based on query and results.
Args:
query: Original query.
results: Retrieved results.
intent: Detected intent.
Returns:
List of suggested follow-up questions.
"""
suggestions = []
if intent == "search_fine":
if results:
# Suggest questions about related fines
suggestions.append("Còn mức phạt nào khác không?")
suggestions.append("Điều luật liên quan là gì?")
suggestions.append("Biện pháp khắc phục như thế nào?")
else:
suggestions.append("Bạn có thể cho biết cụ thể loại vi phạm không?")
elif intent == "search_procedure":
if results:
suggestions.append("Hồ sơ cần chuẩn bị gì?")
suggestions.append("Lệ phí là bao nhiêu?")
suggestions.append("Thời hạn xử lý là bao lâu?")
suggestions.append("Nộp hồ sơ ở đâu?")
else:
suggestions.append("Bạn muốn tìm thủ tục nào cụ thể?")
elif intent == "search_office":
if results:
suggestions.append("Số điện thoại liên hệ?")
suggestions.append("Giờ làm việc như thế nào?")
suggestions.append("Địa chỉ cụ thể ở đâu?")
else:
suggestions.append("Bạn muốn tìm đơn vị nào?")
elif intent == "search_advisory":
if results:
suggestions.append("Còn cảnh báo nào khác không?")
suggestions.append("Cách phòng tránh như thế nào?")
else:
suggestions.append("Bạn muốn tìm cảnh báo về chủ đề gì?")
return suggestions[:3] # Return top 3 suggestions
def detect_ambiguity(query: str, results_count: int, confidence: float) -> Tuple[bool, Optional[str]]:
"""
Detect if query is ambiguous.
Args:
query: User query.
results_count: Number of results found.
confidence: Confidence score.
Returns:
Tuple of (is_ambiguous, ambiguity_reason).
"""
query_lower = query.lower()
query_words = query.split()
# Very short queries are often ambiguous
if len(query_words) <= 2:
return (True, "Câu hỏi quá ngắn, cần thêm thông tin")
# Low confidence and many results suggests ambiguity
if results_count > 10 and confidence < 0.5:
return (True, "Kết quả quá nhiều, cần cụ thể hơn")
# Very generic queries
generic_queries = ["thông tin", "tìm kiếm", "hỏi", "giúp"]
if any(gq in query_lower for gq in generic_queries) and len(query_words) <= 3:
return (True, "Câu hỏi chung chung, cần cụ thể hơn")
return (False, None)
def generate_explanation(result: Any, query: str, score: Optional[float] = None) -> str:
"""
Generate explanation for why a result is relevant.
Args:
result: Result object.
result_type: Type of result.
query: Original query.
score: Relevance score.
Returns:
Explanation string.
"""
result_type = type(result).__name__.lower()
explanation_parts = []
if "fine" in result_type:
name = getattr(result, "name", "")
code = getattr(result, "code", "")
explanation_parts.append(f"Kết quả này phù hợp vì:")
if code:
explanation_parts.append(f"- Mã vi phạm: {code}")
if name:
explanation_parts.append(f"- Tên vi phạm: {name}")
if score:
explanation_parts.append(f"- Độ phù hợp: {score:.0%}")
elif "procedure" in result_type:
title = getattr(result, "title", "")
explanation_parts.append(f"Kết quả này phù hợp vì:")
if title:
explanation_parts.append(f"- Tên thủ tục: {title}")
if score:
explanation_parts.append(f"- Độ phù hợp: {score:.0%}")
elif "office" in result_type:
unit_name = getattr(result, "unit_name", "")
explanation_parts.append(f"Kết quả này phù hợp vì:")
if unit_name:
explanation_parts.append(f"- Tên đơn vị: {unit_name}")
if score:
explanation_parts.append(f"- Độ phù hợp: {score:.0%}")
elif "advisory" in result_type:
title = getattr(result, "title", "")
explanation_parts.append(f"Kết quả này phù hợp vì:")
if title:
explanation_parts.append(f"- Tiêu đề: {title}")
if score:
explanation_parts.append(f"- Độ phù hợp: {score:.0%}")
return "\n".join(explanation_parts) if explanation_parts else "Kết quả này phù hợp với câu hỏi của bạn."
def compare_results(results: List[Any], result_type: str) -> str:
"""
Compare multiple results and highlight differences.
Args:
results: List of result objects.
result_type: Type of results.
Returns:
Comparison summary string.
"""
if len(results) < 2:
return ""
comparison_parts = ["So sánh các kết quả:"]
if result_type == "fine":
# Compare fine amounts
fine_amounts = []
for result in results[:3]:
if hasattr(result, "min_fine") and hasattr(result, "max_fine"):
if result.min_fine and result.max_fine:
fine_amounts.append(f"{result.name}: {result.min_fine:,.0f} - {result.max_fine:,.0f} VNĐ")
if fine_amounts:
comparison_parts.extend(fine_amounts)
elif result_type == "procedure":
# Compare procedures by domain/level
for result in results[:3]:
title = getattr(result, "title", "")
domain = getattr(result, "domain", "")
level = getattr(result, "level", "")
if title:
comp = f"- {title}"
if domain:
comp += f" ({domain})"
if level:
comp += f" - Cấp {level}"
comparison_parts.append(comp)
return "\n".join(comparison_parts)