Spaces:
Runtime error
Runtime error
Commit
·
e332ed5
1
Parent(s):
749ee37
update: extract intent
Browse files- utils/AdvancedLawRetriever.py +82 -149
utils/AdvancedLawRetriever.py
CHANGED
@@ -182,7 +182,7 @@ class AdvancedLawRetriever(BaseRetriever):
|
|
182 |
|
183 |
try:
|
184 |
# Sử dụng câu hỏi đã được viết lại để có ngữ cảnh tốt nhất
|
185 |
-
ranked_results_info = self.reranker.
|
186 |
except Exception as e:
|
187 |
logger.error(f"Failed to re-rank with custom structured content: {e}. Falling back to default re-ranking.")
|
188 |
# Fallback về cách re-rank mặc định nếu có lỗi
|
@@ -213,170 +213,103 @@ class AdvancedLawRetriever(BaseRetriever):
|
|
213 |
info = {"base_filters": {}, "preferred_doc_type": None}
|
214 |
query_lower = query.lower()
|
215 |
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
|
221 |
-
|
222 |
-
if
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
# Xử lý vi phạm
|
238 |
-
"biện pháp khắc phục", "hậu quả vi phạm", "trách nhiệm vi phạm"
|
239 |
-
]):
|
240 |
info["preferred_doc_type"] = "NGHỊ ĐỊNH"
|
241 |
logger.info("Intent detected: Sanction/Penalty -> Preferring 'NGHỊ ĐỊNH'.")
|
242 |
-
|
243 |
-
|
|
|
|
|
244 |
"thủ tục", "hồ sơ", "đăng ký", "cấp phép", "giấy phép", "chứng nhận",
|
245 |
"xin phép", "nộp hồ sơ", "thời hạn giải quyết", "lệ phí", "phí", "thẩm quyền",
|
246 |
-
|
247 |
-
"cơ quan nào", "nộp ở đâu", "ai cấp", "ai quyết định",
|
248 |
-
# Điều kiện và yêu cầu
|
249 |
-
"điều kiện", "yêu cầu", "tiêu chuẩn", "quy trình", "trình tự",
|
250 |
-
"cách thức", "làm thế nào", "how to"
|
251 |
]):
|
252 |
info["preferred_doc_type"] = "THÔNG TƯ"
|
253 |
-
|
254 |
logger.info("Intent detected: Administrative Procedure -> Preferring 'THÔNG TƯ'.")
|
|
|
255 |
|
256 |
-
|
257 |
-
|
258 |
-
]) and any(loc_kw in query_lower for loc_kw in [
|
259 |
-
"tỉnh", "thành phố", "huyện", "xã", "việt nam"
|
260 |
-
]):
|
261 |
-
info["preferred_doc_type"] = "NGHỊ QUYẾT" # Hoặc có thể là một list ['NGHỊ QUYẾT', 'QUYẾT ĐỊNH']
|
262 |
-
logger.info("Intent detected: Specific Factual Data (Area, Population) -> Preferring 'NGHỊ QUYẾT'.")
|
263 |
-
# 3. NGUYÊN TẮC CHUNG, QUYỀN NGHĨA VỤ, CẤU TRÚC NHÀ NƯỚC - Ưu tiên LUẬT
|
264 |
-
elif any(kw in query_lower for kw in [
|
265 |
-
# Nguyên tắc cơ bản
|
266 |
-
"nguyên tắc", "cơ sở", "căn cứ", "tôn chỉ", "mục đích", "ý nghĩa",
|
267 |
-
# Quyền và nghĩa vụ
|
268 |
-
"quyền và nghĩa vụ", "quyền", "nghĩa vụ", "trách nhiệm", "quyền hạn",
|
269 |
-
"quyền lợi", "lợi ích", "bảo vệ quyền", "thực hiện nghĩa vụ",
|
270 |
-
# Định nghĩa và khái niệm
|
271 |
-
"khái niệm", "định nghĩa", "là gì", "hiểu như thế nào", "có nghĩa",
|
272 |
-
"thuật ngữ", "giải thích", "ý nghĩa", "nội dung",
|
273 |
-
# Cấm và cho phép cơ bản
|
274 |
-
"cấm", "được phép", "không được", "nghiêm cấm", "hạn chế",
|
275 |
-
"cho phép", "được quyền", "có thể", "không được phép",
|
276 |
-
# Cấu trúc, phân cấp hành chính cơ bản (thêm mới)
|
277 |
-
"đơn vị hành chính", "cấp hành chính", "bao nhiêu cấp", "phân cấp",
|
278 |
-
"cấu trúc nhà nước", "hệ thống chính quyền", "chính quyền địa phương",
|
279 |
-
"cấp tỉnh", "cấp huyện", "cấp xã", "trung ương", "địa phương"
|
280 |
-
]):
|
281 |
-
info["preferred_doc_type"] = "LUẬT"
|
282 |
-
|
283 |
-
logger.info("Intent detected: General Principle/Definition/Rights/Administrative Structure -> Preferring 'LUẬT'.")
|
284 |
-
|
285 |
-
# 4. TỔ CHỨC BỘ MÁY CỤ THỂ (không phải cấu trúc cơ bản) - Ưu tiên NGHỊ ĐỊNH/QUYẾT ĐỊNH
|
286 |
-
elif any(kw in query_lower for kw in [
|
287 |
-
# Tổ chức bộ máy cụ thể (loại trừ các từ về cấu trúc cơ bản)
|
288 |
-
"bộ máy", "cơ cấu tổ chức", "chức năng", "nhiệm vụ cụ thể",
|
289 |
-
"thành lập", "giải thể", "sáp nhập", "chia tách", "tái cơ cấu",
|
290 |
-
"nhân sự", "bổ nhiệm", "miễn nhiệm", "cán bộ", "công chức",
|
291 |
-
# Nhưng không bao gồm các câu hỏi về cấu trúc hành chính cơ bản
|
292 |
-
]) and not any(basic_kw in query_lower for basic_kw in [
|
293 |
-
"đơn vị hành chính", "cấp hành chính", "bao nhiêu cấp", "phân cấp",
|
294 |
-
"cấu trúc nhà nước", "hệ thống chính quyền"
|
295 |
-
]):
|
296 |
-
info["preferred_doc_type"] = "NGHỊ ĐỊNH"
|
297 |
-
|
298 |
-
logger.info("Intent detected: Organization Structure -> Preferring 'NGHỊ ĐỊNH'.")
|
299 |
-
|
300 |
-
# 5. BIỂU MẪU, DANH MỤC, ĐỊNH MỨC - Ưu tiên THÔNG TƯ
|
301 |
-
elif any(kw in query_lower for kw in [
|
302 |
"biểu mẫu", "mẫu đơn", "form", "danh mục", "bảng biểu", "định mức",
|
303 |
-
"khung", "tiêu chuẩn kỹ thuật", "quy chuẩn", "đơn giá"
|
304 |
-
"template", "format", "pattern"
|
305 |
]):
|
306 |
info["preferred_doc_type"] = "THÔNG TƯ"
|
307 |
-
|
308 |
logger.info("Intent detected: Forms/Standards/Rates -> Preferring 'THÔNG TƯ'.")
|
|
|
309 |
|
310 |
-
#
|
311 |
-
|
312 |
-
|
313 |
-
"
|
314 |
-
"
|
315 |
-
|
316 |
-
info["preferred_doc_type"] = "LUẬT"
|
317 |
-
|
318 |
-
logger.info("Intent detected: Dispute Resolution -> Preferring 'LUẬT'.")
|
319 |
-
|
320 |
-
# 7. BẢO HIỂM, PHÚC LỢI XÃ HỘI - Ưu tiên NGHỊ ĐỊNH
|
321 |
-
elif any(kw in query_lower for kw in [
|
322 |
-
"bảo hiểm", "bhxh", "bhyt", "bhtn", "bảo hiểm xã hội",
|
323 |
-
"lương hưu", "trợ cấp", "phúc lợi", "ốm đau", "thai sản",
|
324 |
-
"tai nạn lao động", "bệnh nghề nghiệp", "mức đóng", "mức hưởng"
|
325 |
-
]):
|
326 |
-
info["preferred_doc_type"] = "NGHỊ ĐỊNH"
|
327 |
-
|
328 |
-
logger.info("Intent detected: Social Insurance/Welfare -> Preferring 'NGHỊ ĐỊNH'.")
|
329 |
-
|
330 |
-
# 8. THUẾ, PHÍ, LỆ PHÍ - Ưu tiên THÔNG TƯ/NGHỊ ĐỊNH
|
331 |
-
elif any(kw in query_lower for kw in [
|
332 |
-
"thuế", "phí", "lệ phí", "thuế suất", "miễn thuế", "giảm thuế",
|
333 |
-
"khai thuế", "nộp thuế", "hoàn thuế", "khấu trừ", "tạm nộp",
|
334 |
-
"thuế thu nhập", "thuế gtgt", "thuế ttđb", "thuế xuất nhập khẩu"
|
335 |
-
]):
|
336 |
-
info["preferred_doc_type"] = "THÔNG TƯ"
|
337 |
-
|
338 |
-
logger.info("Intent detected: Tax/Fee -> Preferring 'THÔNG TƯ'.")
|
339 |
-
|
340 |
-
# 9. ĐẤU THẦU, MUA SẮM CÔNG - Ưu tiên NGHỊ ĐỊNH
|
341 |
-
elif any(kw in query_lower for kw in [
|
342 |
-
"đấu thầu", "mua sắm công", "gói thầu", "hồ sơ mời thầu",
|
343 |
-
"tham gia thầu", "trúng thầu", "loại thầu", "đánh giá thầu",
|
344 |
-
"bảo đảm thầu", "hợp đồng thầu"
|
345 |
-
]):
|
346 |
-
info["preferred_doc_type"] = "NGHỊ ĐỊNH"
|
347 |
-
|
348 |
-
logger.info("Intent detected: Bidding/Public Procurement -> Preferring 'NGHỊ ĐỊNH'.")
|
349 |
-
|
350 |
-
# 10. ĐỊA CHÍNH, ĐẤT ĐAI - Ưu tiên LUẬT/NGHỊ ĐỊNH
|
351 |
-
elif any(kw in query_lower for kw in [
|
352 |
-
"đất đai", "quyền sử dụng đất", "sổ đỏ", "chuyển nhượng đất",
|
353 |
-
"thu hồi đất", "bồi thường đất", "giá đất", "địa chính",
|
354 |
-
"cấp sổ", "thửa đất", "diện tích đất", "mục đích sử dụng"
|
355 |
-
]):
|
356 |
-
info["preferred_doc_type"] = "LUẬT"
|
357 |
-
|
358 |
-
logger.info("Intent detected: Land/Real Estate -> Preferring 'LUẬT'.")
|
359 |
-
|
360 |
-
# 11. LAO ĐỘNG VIỆC LÀM - Ưu tiên BỘ LUẬT/NGHỊ ĐỊNH
|
361 |
-
elif any(kw in query_lower for kw in [
|
362 |
-
"hợp đồng lao động", "chấm dứt hợp đồng", "sa thải", "nghỉ việc",
|
363 |
-
"lương", "thưởng", "phụ cấp", "tăng ca", "nghỉ phép", "thai sản",
|
364 |
-
"thời giờ làm việc", "an toàn lao động", "bảo hộ lao động"
|
365 |
]):
|
366 |
-
info["preferred_doc_type"] = "
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
#
|
371 |
-
|
372 |
-
|
373 |
-
"
|
374 |
-
"
|
375 |
-
"
|
|
|
376 |
]):
|
377 |
info["preferred_doc_type"] = "LUẬT"
|
|
|
|
|
378 |
|
379 |
-
|
380 |
|
381 |
-
|
382 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
182 |
|
183 |
try:
|
184 |
# Sử dụng câu hỏi đã được viết lại để có ngữ cảnh tốt nhất
|
185 |
+
ranked_results_info = self.reranker.predict(rewritten_query, contents_to_rank, return_documents=False, top_k=self.default_k * 2) # Lấy nhiều hơn một chút
|
186 |
except Exception as e:
|
187 |
logger.error(f"Failed to re-rank with custom structured content: {e}. Falling back to default re-ranking.")
|
188 |
# Fallback về cách re-rank mặc định nếu có lỗi
|
|
|
213 |
info = {"base_filters": {}, "preferred_doc_type": None}
|
214 |
query_lower = query.lower()
|
215 |
|
216 |
+
intent_found = False
|
217 |
+
|
218 |
+
# --- Giai đoạn 1: Xác định ý định và loại văn bản ưu tiên ---
|
219 |
+
# Đặt các intent cụ thể và dễ xung đột lên đầu.
|
220 |
|
221 |
+
# INTENT 1: Dữ kiện cụ thể (Diện tích, Dân số) - Rất cụ thể
|
222 |
+
if not intent_found and (
|
223 |
+
any(kw in query_lower for kw in ["diện tích", "dân số", "số lượng"])
|
224 |
+
and any(loc_kw in query_lower for loc_kw in ["tỉnh", "thành phố", "huyện", "xã", "việt nam"])
|
225 |
+
):
|
226 |
+
info["preferred_doc_type"] = "NGHỊ QUYẾT"
|
227 |
+
logger.info("Intent detected: Specific Factual Data (Area, Population) -> Preferring 'NGHỊ QUYẾT'.")
|
228 |
+
intent_found = True
|
229 |
+
# Với intent này, chúng ta không áp dụng bộ lọc entity_type tự động.
|
230 |
+
|
231 |
+
# INTENT 2: Mức phạt / Chế tài - Rất cụ thể
|
232 |
+
if not intent_found and any(kw in query_lower for kw in [
|
233 |
+
"phạt bao nhiêu", "mức xử phạt", "tiền phạt", "xử phạt", "phạt tiền",
|
234 |
+
"mức phạt", "số tiền phạt", "bị phạt", "chế phạt", "tước bằng",
|
235 |
+
"tạm giữ phương tiện", "tịch thu", "vi phạm"
|
236 |
+
]):
|
|
|
|
|
|
|
237 |
info["preferred_doc_type"] = "NGHỊ ĐỊNH"
|
238 |
logger.info("Intent detected: Sanction/Penalty -> Preferring 'NGHỊ ĐỊNH'.")
|
239 |
+
intent_found = True
|
240 |
+
|
241 |
+
# INTENT 3: Thủ tục hành chính - Cụ thể
|
242 |
+
if not intent_found and any(kw in query_lower for kw in [
|
243 |
"thủ tục", "hồ sơ", "đăng ký", "cấp phép", "giấy phép", "chứng nhận",
|
244 |
"xin phép", "nộp hồ sơ", "thời hạn giải quyết", "lệ phí", "phí", "thẩm quyền",
|
245 |
+
"cơ quan nào", "nộp ở đâu", "ai cấp", "quy trình", "trình tự"
|
|
|
|
|
|
|
|
|
246 |
]):
|
247 |
info["preferred_doc_type"] = "THÔNG TƯ"
|
|
|
248 |
logger.info("Intent detected: Administrative Procedure -> Preferring 'THÔNG TƯ'.")
|
249 |
+
intent_found = True
|
250 |
|
251 |
+
# INTENT 4: Biểu mẫu / Tiêu chuẩn kỹ thuật - Cụ thể
|
252 |
+
if not intent_found and any(kw in query_lower for kw in [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
253 |
"biểu mẫu", "mẫu đơn", "form", "danh mục", "bảng biểu", "định mức",
|
254 |
+
"khung", "tiêu chuẩn kỹ thuật", "quy chuẩn", "đơn giá"
|
|
|
255 |
]):
|
256 |
info["preferred_doc_type"] = "THÔNG TƯ"
|
|
|
257 |
logger.info("Intent detected: Forms/Standards/Rates -> Preferring 'THÔNG TƯ'.")
|
258 |
+
intent_found = True
|
259 |
|
260 |
+
# INTENT 5: Tổ chức bộ máy cụ thể (Sáp nhập, thành lập) - Chung hơn
|
261 |
+
# Phải đứng trước intent về Nguyên tắc chung để bắt các case "sáp nhập đơn vị hành chính"
|
262 |
+
if not intent_found and any(kw in query_lower for kw in [
|
263 |
+
"bộ máy", "cơ cấu tổ chức", "chức năng", "nhiệm vụ cụ thể",
|
264 |
+
"thành lập", "giải thể", "sáp nhập", "chia tách", "tái cơ cấu",
|
265 |
+
"bổ nhiệm", "miễn nhiệm"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
266 |
]):
|
267 |
+
info["preferred_doc_type"] = "NGHỊ ĐỊNH" # Có thể là NGHỊ QUYẾT nữa
|
268 |
+
logger.info("Intent detected: Specific Organization Structure -> Preferring 'NGHỊ ĐỊNH'.")
|
269 |
+
intent_found = True
|
270 |
+
|
271 |
+
# INTENT 6: Nguyên tắc chung / Định nghĩa / Cấu trúc cơ bản - Rất chung
|
272 |
+
# Đặt cuối cùng để nó chỉ bắt các câu hỏi chung chung thực sự.
|
273 |
+
if not intent_found and any(kw in query_lower for kw in [
|
274 |
+
"nguyên tắc", "quyền và nghĩa vụ", "quyền", "nghĩa vụ", "trách nhiệm",
|
275 |
+
"khái niệm", "định nghĩa", "là gì", "hiểu như thế nào", "nghiêm cấm",
|
276 |
+
"đơn vị hành chính", "cấp hành chính", "bao nhiêu cấp", "phân cấp",
|
277 |
+
"cấu trúc nhà nước", "hệ thống chính quyền"
|
278 |
]):
|
279 |
info["preferred_doc_type"] = "LUẬT"
|
280 |
+
logger.info("Intent detected: General Principle/Definition/Rights/Administrative Structure -> Preferring 'LUẬT'.")
|
281 |
+
intent_found = True
|
282 |
|
283 |
+
# --- Giai đoạn 2: Áp dụng bộ lọc (filters) một cách có kiểm soát ---
|
284 |
|
285 |
+
# 2.1. Lọc theo lĩnh vực (field) - Có thể áp dụng cho hầu hết các trường hợp
|
286 |
+
inferred_field = infer_field(query, None)
|
287 |
+
if inferred_field and inferred_field != "khac":
|
288 |
+
info["base_filters"]["field"] = inferred_field
|
289 |
+
logger.info(f"Applying filter: field = {inferred_field}")
|
290 |
+
|
291 |
+
# 2.2. Lọc theo loại thực thể (entity_type) - CHỈ áp dụng khi thực sự cần thiết
|
292 |
+
# Chúng ta KHÔNG áp dụng bộ lọc này cho các câu hỏi về dữ kiện địa lý
|
293 |
+
# hoặc các câu hỏi chung chung có thể không có entity_type rõ ràng.
|
294 |
+
# Ví dụ, chỉ áp dụng cho các câu hỏi về thủ tục, tổ chức, chế tài...
|
295 |
+
|
296 |
+
# Lấy lại intent đã xác định ở trên để quyết định
|
297 |
+
current_intent_log = logger.handlers[0].records[-1].msg if logger.handlers and logger.handlers[0].records else ""
|
298 |
+
|
299 |
+
# Chỉ áp dụng entity filter cho các intent này
|
300 |
+
applicable_intents_for_entity_filter = [
|
301 |
+
"Sanction/Penalty",
|
302 |
+
"Administrative Procedure",
|
303 |
+
"Specific Organization Structure"
|
304 |
+
]
|
305 |
+
|
306 |
+
if any(intent_name in current_intent_log for intent_name in applicable_intents_for_entity_filter):
|
307 |
+
inferred_entities = infer_entity_type(query, inferred_field)
|
308 |
+
if inferred_entities:
|
309 |
+
info["base_filters"]["entity_type"] = inferred_entities
|
310 |
+
logger.info(f"Applying filter: entity_type = {inferred_entities}")
|
311 |
+
else:
|
312 |
+
logger.info("Skipping entity_type filter for the detected intent.")
|
313 |
+
|
314 |
+
logger.info(f"Final extracted query info: {info}")
|
315 |
+
return info
|