Spaces:
Sleeping
Sleeping
File size: 6,611 Bytes
31f8e67 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
"""
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)
|