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)