update new hybrid match_documents
Browse files- app/llm.py +1 -1
- app/main.py +23 -19
- app/reranker.py +3 -3
- app/supabase_db.py +11 -3
app/llm.py
CHANGED
|
@@ -412,7 +412,7 @@ class LLMClient:
|
|
| 412 |
|
| 413 |
{{
|
| 414 |
"muc_dich": "mục đích của câu hỏi",
|
| 415 |
-
"phuong_tien": "loại phương tiện giao thông (
|
| 416 |
"hanh_vi_vi_pham": "hành vi vi phạm pháp luật giao thông"
|
| 417 |
}}
|
| 418 |
|
|
|
|
| 412 |
|
| 413 |
{{
|
| 414 |
"muc_dich": "mục đích của câu hỏi",
|
| 415 |
+
"phuong_tien": "loại phương tiện giao thông (xe máy, ô tô, xe tải, người đi bộ...)",
|
| 416 |
"hanh_vi_vi_pham": "hành vi vi phạm pháp luật giao thông"
|
| 417 |
}}
|
| 418 |
|
app/main.py
CHANGED
|
@@ -372,7 +372,11 @@ async def process_business_logic(log_kwargs: Dict[str, Any], page_token: str) ->
|
|
| 372 |
logger.info(f"[DEBUG] tạo embedding: {action}")
|
| 373 |
embedding = await embedding_client.create_embedding(action)
|
| 374 |
logger.info(f"[DEBUG] embedding: {embedding[:5]} ... (total {len(embedding)})")
|
| 375 |
-
matches = supabase_client.match_documents(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 376 |
logger.info(f"[DEBUG] matches: {matches}")
|
| 377 |
if matches:
|
| 378 |
response = await format_search_results(message, matches, page_token, log_kwargs['recipient_id'])
|
|
@@ -438,21 +442,21 @@ async def format_search_results(question: str, matches: List[Dict[str, Any]], pa
|
|
| 438 |
hanhvi = (tieude + "\n" + noidung).strip().replace('\n', ' ')
|
| 439 |
full_result_text += f"Thực hiện hành vi:\n{hanhvi}"
|
| 440 |
# Cá nhân bị phạt tiền
|
| 441 |
-
canhantu = arr_to_str(match.get('
|
| 442 |
-
canhanden = arr_to_str(match.get('
|
| 443 |
if canhantu or canhanden:
|
| 444 |
full_result_text += f"\nCá nhân sẽ bị phạt tiền từ {canhantu} VNĐ đến {canhanden} VNĐ"
|
| 445 |
# Tổ chức bị phạt tiền
|
| 446 |
-
tochuctu = arr_to_str(match.get('
|
| 447 |
-
tochucden = arr_to_str(match.get('
|
| 448 |
if tochuctu or tochucden:
|
| 449 |
full_result_text += f"\nTổ chức sẽ bị phạt tiền từ {tochuctu} VNĐ đến {tochucden} VNĐ"
|
| 450 |
# Hình phạt bổ sung
|
| 451 |
-
hpbsnoidung = arr_to_str(match.get('
|
| 452 |
if hpbsnoidung:
|
| 453 |
full_result_text += f"\nNgoài việc bị phạt tiền, người vi phạm còn bị: {hpbsnoidung}"
|
| 454 |
# Biện pháp khắc phục hậu quả
|
| 455 |
-
bpkpnoidung = arr_to_str(match.get('
|
| 456 |
if bpkpnoidung:
|
| 457 |
full_result_text += f"\nNgoài ra, người vi phạm còn bị buộc: {bpkpnoidung}"
|
| 458 |
|
|
@@ -461,18 +465,18 @@ async def format_search_results(question: str, matches: List[Dict[str, Any]], pa
|
|
| 461 |
noidung = (top.get('noidung') or '').strip()
|
| 462 |
hanhvi = (tieude + "\n" + noidung).strip().replace('\n', ' ')
|
| 463 |
top_result_text += f"Thực hiện hành vi:\n{hanhvi}"
|
| 464 |
-
canhantu = arr_to_str(top.get('
|
| 465 |
-
canhanden = arr_to_str(top.get('
|
| 466 |
if canhantu or canhanden:
|
| 467 |
top_result_text += f"\nCá nhân sẽ bị phạt tiền từ {canhantu} VNĐ đến {canhanden} VNĐ"
|
| 468 |
-
tochuctu = arr_to_str(top.get('
|
| 469 |
-
tochucden = arr_to_str(top.get('
|
| 470 |
if tochuctu or tochucden:
|
| 471 |
top_result_text += f"\nTổ chức sẽ bị phạt tiền từ {tochuctu} VNĐ đến {tochucden} VNĐ"
|
| 472 |
-
hpbsnoidung = arr_to_str(top.get('
|
| 473 |
if hpbsnoidung:
|
| 474 |
top_result_text += f"\nNgoài việc bị phạt tiền, người vi phạm còn bị: {hpbsnoidung}"
|
| 475 |
-
bpkpnoidung = arr_to_str(top.get('
|
| 476 |
if bpkpnoidung:
|
| 477 |
top_result_text += f"\nNgoài ra, người vi phạm còn bị buộc: {bpkpnoidung}"
|
| 478 |
else:
|
|
@@ -506,18 +510,18 @@ async def format_search_results(question: str, matches: List[Dict[str, Any]], pa
|
|
| 506 |
noidung = (match.get('noidung') or '').strip()
|
| 507 |
if tieude or noidung:
|
| 508 |
fallback += f" - Hành vi: {(tieude + ' ' + noidung).strip()}\n"
|
| 509 |
-
canhantu = arr_to_str(match.get('
|
| 510 |
-
canhanden = arr_to_str(match.get('
|
| 511 |
if canhantu or canhanden:
|
| 512 |
fallback += f" - Cá nhân bị phạt tiền từ {canhantu} VNĐ đến {canhanden} VNĐ\n"
|
| 513 |
-
tochuctu = arr_to_str(match.get('
|
| 514 |
-
tochucden = arr_to_str(match.get('
|
| 515 |
if tochuctu or tochucden:
|
| 516 |
fallback += f" - Tổ chức bị phạt tiền từ {tochuctu} VNĐ đến {tochucden} VNĐ\n"
|
| 517 |
-
hpbsnoidung = arr_to_str(match.get('
|
| 518 |
if hpbsnoidung:
|
| 519 |
fallback += f" - Hình phạt bổ sung: {hpbsnoidung}\n"
|
| 520 |
-
bpkpnoidung = arr_to_str(match.get('
|
| 521 |
if bpkpnoidung:
|
| 522 |
fallback += f" - Biện pháp khắc phục hậu quả: {bpkpnoidung}\n"
|
| 523 |
fallback += "\n"
|
|
|
|
| 372 |
logger.info(f"[DEBUG] tạo embedding: {action}")
|
| 373 |
embedding = await embedding_client.create_embedding(action)
|
| 374 |
logger.info(f"[DEBUG] embedding: {embedding[:5]} ... (total {len(embedding)})")
|
| 375 |
+
matches = supabase_client.match_documents(
|
| 376 |
+
embedding,
|
| 377 |
+
vehicle_keywords=keywords,
|
| 378 |
+
user_question=action
|
| 379 |
+
)
|
| 380 |
logger.info(f"[DEBUG] matches: {matches}")
|
| 381 |
if matches:
|
| 382 |
response = await format_search_results(message, matches, page_token, log_kwargs['recipient_id'])
|
|
|
|
| 442 |
hanhvi = (tieude + "\n" + noidung).strip().replace('\n', ' ')
|
| 443 |
full_result_text += f"Thực hiện hành vi:\n{hanhvi}"
|
| 444 |
# Cá nhân bị phạt tiền
|
| 445 |
+
canhantu = arr_to_str(match.get('canhanTu'))
|
| 446 |
+
canhanden = arr_to_str(match.get('canhanDen'))
|
| 447 |
if canhantu or canhanden:
|
| 448 |
full_result_text += f"\nCá nhân sẽ bị phạt tiền từ {canhantu} VNĐ đến {canhanden} VNĐ"
|
| 449 |
# Tổ chức bị phạt tiền
|
| 450 |
+
tochuctu = arr_to_str(match.get('tochucTu'))
|
| 451 |
+
tochucden = arr_to_str(match.get('tochucDen'))
|
| 452 |
if tochuctu or tochucden:
|
| 453 |
full_result_text += f"\nTổ chức sẽ bị phạt tiền từ {tochuctu} VNĐ đến {tochucden} VNĐ"
|
| 454 |
# Hình phạt bổ sung
|
| 455 |
+
hpbsnoidung = arr_to_str(match.get('hpbsNoidung'), sep="; ")
|
| 456 |
if hpbsnoidung:
|
| 457 |
full_result_text += f"\nNgoài việc bị phạt tiền, người vi phạm còn bị: {hpbsnoidung}"
|
| 458 |
# Biện pháp khắc phục hậu quả
|
| 459 |
+
bpkpnoidung = arr_to_str(match.get('bpkpNoidung'), sep="; ")
|
| 460 |
if bpkpnoidung:
|
| 461 |
full_result_text += f"\nNgoài ra, người vi phạm còn bị buộc: {bpkpnoidung}"
|
| 462 |
|
|
|
|
| 465 |
noidung = (top.get('noidung') or '').strip()
|
| 466 |
hanhvi = (tieude + "\n" + noidung).strip().replace('\n', ' ')
|
| 467 |
top_result_text += f"Thực hiện hành vi:\n{hanhvi}"
|
| 468 |
+
canhantu = arr_to_str(top.get('canhanTu'))
|
| 469 |
+
canhanden = arr_to_str(top.get('canhanDen'))
|
| 470 |
if canhantu or canhanden:
|
| 471 |
top_result_text += f"\nCá nhân sẽ bị phạt tiền từ {canhantu} VNĐ đến {canhanden} VNĐ"
|
| 472 |
+
tochuctu = arr_to_str(top.get('tochucTu'))
|
| 473 |
+
tochucden = arr_to_str(top.get('tochucDen'))
|
| 474 |
if tochuctu or tochucden:
|
| 475 |
top_result_text += f"\nTổ chức sẽ bị phạt tiền từ {tochuctu} VNĐ đến {tochucden} VNĐ"
|
| 476 |
+
hpbsnoidung = arr_to_str(top.get('hpbsNoidung'), sep="; ")
|
| 477 |
if hpbsnoidung:
|
| 478 |
top_result_text += f"\nNgoài việc bị phạt tiền, người vi phạm còn bị: {hpbsnoidung}"
|
| 479 |
+
bpkpnoidung = arr_to_str(top.get('bpkpNoidung'), sep="; ")
|
| 480 |
if bpkpnoidung:
|
| 481 |
top_result_text += f"\nNgoài ra, người vi phạm còn bị buộc: {bpkpnoidung}"
|
| 482 |
else:
|
|
|
|
| 510 |
noidung = (match.get('noidung') or '').strip()
|
| 511 |
if tieude or noidung:
|
| 512 |
fallback += f" - Hành vi: {(tieude + ' ' + noidung).strip()}\n"
|
| 513 |
+
canhantu = arr_to_str(match.get('canhanTu'))
|
| 514 |
+
canhanden = arr_to_str(match.get('canhanDen'))
|
| 515 |
if canhantu or canhanden:
|
| 516 |
fallback += f" - Cá nhân bị phạt tiền từ {canhantu} VNĐ đến {canhanden} VNĐ\n"
|
| 517 |
+
tochuctu = arr_to_str(match.get('tochucTu'))
|
| 518 |
+
tochucden = arr_to_str(match.get('tochucDen'))
|
| 519 |
if tochuctu or tochucden:
|
| 520 |
fallback += f" - Tổ chức bị phạt tiền từ {tochuctu} VNĐ đến {tochucden} VNĐ\n"
|
| 521 |
+
hpbsnoidung = arr_to_str(match.get('hpbsNoidung'), sep="; ")
|
| 522 |
if hpbsnoidung:
|
| 523 |
fallback += f" - Hình phạt bổ sung: {hpbsnoidung}\n"
|
| 524 |
+
bpkpnoidung = arr_to_str(match.get('bpkpNoidung'), sep="; ")
|
| 525 |
if bpkpnoidung:
|
| 526 |
fallback += f" - Biện pháp khắc phục hậu quả: {bpkpnoidung}\n"
|
| 527 |
fallback += "\n"
|
app/reranker.py
CHANGED
|
@@ -58,9 +58,9 @@ class Reranker:
|
|
| 58 |
if not docs:
|
| 59 |
return []
|
| 60 |
|
| 61 |
-
#
|
| 62 |
-
docs_to_rerank = docs
|
| 63 |
-
logger.info(f"[RERANK] Will rerank {len(docs_to_rerank)} docs (
|
| 64 |
|
| 65 |
# Process docs với concurrency
|
| 66 |
batch_size = 5 # Process 5 docs cùng lúc
|
|
|
|
| 58 |
if not docs:
|
| 59 |
return []
|
| 60 |
|
| 61 |
+
# Rerank toàn bộ docs, không giới hạn 10 docs
|
| 62 |
+
docs_to_rerank = docs
|
| 63 |
+
logger.info(f"[RERANK] Will rerank {len(docs_to_rerank)} docs (no limit)")
|
| 64 |
|
| 65 |
# Process docs với concurrency
|
| 66 |
batch_size = 5 # Process 5 docs cùng lúc
|
app/supabase_db.py
CHANGED
|
@@ -32,17 +32,25 @@ class SupabaseClient:
|
|
| 32 |
return None
|
| 33 |
|
| 34 |
@timing_decorator_sync
|
| 35 |
-
def match_documents(self, embedding: List[float], match_count: int = 20, vehicle_keywords: Optional[List[str]] = None):
|
| 36 |
"""
|
| 37 |
Truy vấn vector similarity search qua RPC match_documents.
|
| 38 |
Input: embedding (list[float]), match_count (int), vehicle_keywords (list[str] hoặc None)
|
| 39 |
Output: list[dict] kết quả truy vấn.
|
| 40 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
try:
|
| 42 |
payload = {
|
|
|
|
| 43 |
'query_embedding': embedding,
|
| 44 |
-
'
|
| 45 |
-
'
|
|
|
|
|
|
|
| 46 |
}
|
| 47 |
if vehicle_keywords:
|
| 48 |
vehicle_columns = [VEHICLE_KEYWORD_TO_COLUMN[k] for k in vehicle_keywords if k in VEHICLE_KEYWORD_TO_COLUMN]
|
|
|
|
| 32 |
return None
|
| 33 |
|
| 34 |
@timing_decorator_sync
|
| 35 |
+
def match_documents(self, embedding: List[float], match_count: int = 20, vehicle_keywords: Optional[List[str]] = None, user_question: str = '', min_rank_threshold: float = 0.05, rrf_k: int = 60):
|
| 36 |
"""
|
| 37 |
Truy vấn vector similarity search qua RPC match_documents.
|
| 38 |
Input: embedding (list[float]), match_count (int), vehicle_keywords (list[str] hoặc None)
|
| 39 |
Output: list[dict] kết quả truy vấn.
|
| 40 |
"""
|
| 41 |
+
|
| 42 |
+
# Chuẩn bị chuỗi truy vấn trong Python
|
| 43 |
+
# Tách từ và nối bằng '|'
|
| 44 |
+
or_query_tsquery = " | ".join(user_question.split())
|
| 45 |
+
|
| 46 |
try:
|
| 47 |
payload = {
|
| 48 |
+
'or_query_tsquery': or_query_tsquery,
|
| 49 |
'query_embedding': embedding,
|
| 50 |
+
'match_count': match_count,
|
| 51 |
+
'min_rank_threshold': min_rank_threshold,
|
| 52 |
+
'vehicle_filters': None,
|
| 53 |
+
'rrf_k': rrf_k
|
| 54 |
}
|
| 55 |
if vehicle_keywords:
|
| 56 |
vehicle_columns = [VEHICLE_KEYWORD_TO_COLUMN[k] for k in vehicle_keywords if k in VEHICLE_KEYWORD_TO_COLUMN]
|