Spaces:
Runtime error
Runtime error
Commit
·
eb4d8a0
1
Parent(s):
fb63684
upgrade: qa chain
Browse files- prompt_templete.py +393 -186
- rag_components.py +66 -42
prompt_templete.py
CHANGED
@@ -33,45 +33,7 @@
|
|
33 |
|
34 |
# Prompt to condense question for legal chain
|
35 |
|
36 |
-
CONDENSE_QUESTION_PROMPT = """"
|
37 |
-
Bạn là một chuyên gia tối ưu hóa truy vấn tìm kiếm cho hệ thống pháp luật.
|
38 |
-
Nhiệm vụ của bạn là kết hợp lịch sử trò chuyện (nếu có liên quan) và một câu hỏi mới để tạo ra một **câu hỏi độc lập, hoàn chỉnh duy nhất**. Câu hỏi này phải rõ ràng và sẵn sàng để được sử dụng để truy vấn một cơ sở dữ liệu vector.
|
39 |
|
40 |
-
**QUY TẮC BẮT BUỘC:**
|
41 |
-
- **GIỮ NGUYÊN:** Giữ lại tất cả các thuật ngữ pháp lý, số hiệu văn bản, điều khoản, ngày tháng, năm cụ thể.
|
42 |
-
- **KHÔNG THÊM THẮT:** Nếu câu hỏi gốc mang tính tổng quát, câu hỏi viết lại phải giữ nguyên sự tổng quát đó, không được tự ý thêm các giả định không có trong câu hỏi.
|
43 |
-
- **BỎ QUA NẾU KHÔNG LIÊN QUAN:** Nếu câu hỏi mới là một chủ đề hoàn toàn khác với lịch sử trò chuyện, hãy bỏ qua lịch sử và chỉ tập trung vào câu hỏi mới.
|
44 |
-
- **HOÀN CHỈNH:** Câu hỏi cuối cùng phải là một câu hỏi hoàn chỉnh, có đầy đủ chủ ngữ, vị ngữ.
|
45 |
-
|
46 |
-
---
|
47 |
-
**VÍ DỤ:**
|
48 |
-
|
49 |
-
**Ví dụ 1: Câu hỏi nối tiếp thay đổi chủ thể**
|
50 |
-
- Lịch sử hội thoại: `[("Hỏi: Mức phạt khi vượt đèn đỏ với xe máy là bao nhiêu?", "Trả lời: ...")]`
|
51 |
-
- Câu hỏi mới của người dùng: `còn ô tô thì sao`
|
52 |
-
- Câu hỏi độc lập: `Mức xử phạt hành chính đối với người điều khiển xe ô tô có hành vi không chấp hành hiệu lệnh của đèn tín hiệu giao thông là bao nhiêu?`
|
53 |
-
|
54 |
-
**Ví dụ 2: Câu hỏi mới không liên quan đến lịch sử**
|
55 |
-
- Lịch sử hội thoại: `[("Hỏi: Thủ tục ly hôn đơn phương gồm những gì?", "Trả lời: ...")]`
|
56 |
-
- Câu hỏi mới của người dùng: `quy định về hợp đồng lao động`
|
57 |
-
- Câu hỏi độc lập: `Quy định của pháp luật về hợp đồng lao động là gì?`
|
58 |
-
|
59 |
-
**Ví dụ 3: Câu hỏi mới đã đủ rõ ràng**
|
60 |
-
- Lịch sử hội thoại: `(trống)`
|
61 |
-
- Câu hỏi mới của người dùng: `Người lao động bị nợ lương 2 tháng thì phải làm gì?`
|
62 |
-
- Câu hỏi độc lập: `Người lao động bị nợ lương 2 tháng thì phải làm gì?`
|
63 |
-
---
|
64 |
-
|
65 |
-
**BÂY GIỜ, HÃY THỰC HIỆN NHIỆM VỤ:**
|
66 |
-
|
67 |
-
**Lịch sử hội thoại:**
|
68 |
-
{chat_history}
|
69 |
-
|
70 |
-
**Câu hỏi mới của người dùng:**
|
71 |
-
{input}
|
72 |
-
|
73 |
-
**Câu hỏi độc lập:**
|
74 |
-
"""
|
75 |
|
76 |
# CONDENSE_QUESTION_PROMPT = """
|
77 |
# Dựa trên lịch sử hội thoại sau và một câu hỏi mới của người dùng, hãy viết lại câu hỏi mới thành một câu hỏi **độc lập, đầy đủ ý nghĩa và ngắn gọn nhất có thể**.
|
@@ -190,43 +152,6 @@ Nhiệm vụ của bạn là trả lời câu hỏi của người dùng dựa H
|
|
190 |
|
191 |
# Prompt for generic chain
|
192 |
|
193 |
-
GENERAL_PROMPT = """
|
194 |
-
Bạn là JuriBot, một trợ lý AI thân thiện và chuyên nghiệp, chuyên sâu về pháp luật Việt Nam.
|
195 |
-
Nhiệm vụ của bạn là trả lời một cách lịch sự dựa trên câu hỏi đã được viết lại và phân loại của người dùng.
|
196 |
-
|
197 |
-
**QUY TẮC PHẢN HỒI (DỰA TRÊN `classification`):**
|
198 |
-
|
199 |
-
- Nếu `classification` là **`chit_chat`**:
|
200 |
-
- Hãy phản hồi một cách tự nhiên và thân thiện.
|
201 |
-
- Nếu là lời chào, hãy chào lại.
|
202 |
-
- Nếu là lời cảm ơn, hãy đáp lại ("Rất vui được giúp bạn!").
|
203 |
-
- Nếu là nhận xét hoặc hỏi về bản thân ("bạn là ai?"), hãy giới thiệu ngắn gọn vai trò của mình là một trợ lý pháp lý AI, nhấn mạnh chỉ cung cấp thông tin tham khảo và không thay thế luật sư.
|
204 |
-
|
205 |
-
- Nếu `classification` là **`out_of_scope_legal`**:
|
206 |
-
- Hãy lịch sự trả lời rằng chuyên môn của bạn chỉ giới hạn trong pháp luật Việt Nam và không thể cung cấp thông tin về luật của quốc gia khác.
|
207 |
-
|
208 |
-
- Nếu `classification` là **`general_knowledge`**:
|
209 |
-
- Hãy lịch sự giải thích rằng bạn là một trợ lý chuyên về pháp lý và không được đào tạo để trả lời các câu hỏi kiến thức chung.
|
210 |
-
|
211 |
-
- Nếu `classification` là **`ambiguous_legal_topic`** (dành cho phiên bản nâng cao của prompt tiền xử lý):
|
212 |
-
- Hãy yêu cầu người dùng làm rõ câu hỏi, có thể gợi ý một vài ví dụ để giúp họ.
|
213 |
-
|
214 |
-
**HƯỚNG DẪN TÔNG GIỌNG:**
|
215 |
-
- Luôn giữ thái độ chuyên nghiệp, hữu ích và khiêm tốn.
|
216 |
-
- Kết thúc câu trả lời bằng một câu hỏi mở để khuyến khích người dùng tiếp tục hỏi về pháp luật Việt Nam (ví dụ: "Bạn có câu hỏi nào khác liên quan đến pháp luật Việt Nam không ạ?").
|
217 |
-
|
218 |
-
---
|
219 |
-
**DỮ LIỆU ĐẦU VÀO:**
|
220 |
-
|
221 |
-
**Phân loại:**
|
222 |
-
{classification}
|
223 |
-
|
224 |
-
**Câu hỏi c��a người dùng (đã được viết lại):**
|
225 |
-
{rewritten_question}
|
226 |
-
|
227 |
-
**Câu trả lời của bạn:**
|
228 |
-
"""
|
229 |
-
|
230 |
# GENERAL_PROMPT = """
|
231 |
# Bạn là JuriBot, một trợ lý AI chuyên sâu về pháp luật Việt Nam.
|
232 |
|
@@ -252,94 +177,6 @@ Nhiệm vụ của bạn là trả lời một cách lịch sự dựa trên câ
|
|
252 |
|
253 |
# prompt_templete.py
|
254 |
|
255 |
-
UNIFIED_PREPROCESSING_PROMPT=""""
|
256 |
-
Bạn là một AI điều phối viên siêu thông minh, chuyên phân tích và tối ưu hóa các câu hỏi của người dùng cho một hệ thống chatbot **CHUYÊN VỀ PHÁP LUẬT VIỆT NAM**.
|
257 |
-
Nhiệm vụ của bạn là nhận câu hỏi của người dùng và lịch sử trò chuyện, sau đó viết lại câu hỏi cho rõ ràng và phân loại nó một cách chính xác.
|
258 |
-
|
259 |
-
**QUY TRÌNH BẮT BUỘC:**
|
260 |
-
|
261 |
-
**Bước 1: CHUẨN HÓA CƠ BẢN**
|
262 |
-
- **Thêm dấu tiếng Việt đầy đủ và chính xác** nếu câu hỏi bị thiếu dấu.
|
263 |
-
- Sửa các lỗi chính tả và ngữ pháp thông thường.
|
264 |
-
|
265 |
-
**Bước 2: VIẾT LẠI & HOÀN CHỈNH**
|
266 |
-
- Dựa vào kết quả của Bước 1 và lịch sử trò chuyện, hãy giải quyết các đại từ và các câu hỏi nối tiếp.
|
267 |
-
- Nếu đầu vào là một câu hỏi pháp lý, hãy thay thế thuật ngữ thông tục bằng thuật ngữ pháp lý chính thức và tạo ra một **câu hỏi tìm kiếm độc lập, hoàn chỉnh**.
|
268 |
-
- Nếu đầu vào không phải là câu hỏi (ví dụ: chào hỏi, cảm ơn, nhận xét), chỉ cần chuẩn hóa nó thành một câu hoàn chỉnh và lịch sự.
|
269 |
-
|
270 |
-
**Bước 3: PHÂN LOẠI**
|
271 |
-
- Dựa trên nội dung đã được hoàn chỉnh ở Bước 2, phân loại nó vào MỘT trong các loại sau:
|
272 |
-
- `legal_rag`: Nếu câu hỏi liên quan đến tra cứu quy định pháp lý của **Việt Nam**.
|
273 |
-
- `out_of_scope_legal`: Nếu câu hỏi liên quan đến pháp luật của **quốc gia khác** hoặc các vấn đề pháp lý không thuộc phạm vi hệ thống.
|
274 |
-
- `chit_chat`: Đối với chào hỏi, cảm ơn, nhận xét, hỏi đáp thông thường không phải là câu hỏi (ví dụ: "bạn là ai?", "bạn làm được gì?").
|
275 |
-
- `general_knowledge`: Đối với các câu hỏi về kiến thức chung, không liên quan đến pháp luật (ví dụ: diện tích một tỉnh, thủ đô một nước).
|
276 |
-
|
277 |
-
**Lịch sử trò chuyện (nếu có):**
|
278 |
-
{chat_history}
|
279 |
-
|
280 |
-
**Câu hỏi mới của người dùng:**
|
281 |
-
{input}
|
282 |
-
|
283 |
-
**OUTPUT (Chỉ trả về một đối tượng JSON duy nhất):**
|
284 |
-
{{
|
285 |
-
"classification": "...",
|
286 |
-
"rewritten_question": "..."
|
287 |
-
}}
|
288 |
-
|
289 |
-
---
|
290 |
-
**VÍ DỤ CHI TIẾT:**
|
291 |
-
|
292 |
-
**Ví dụ 1 (Pháp lý trong phạm vi):**
|
293 |
-
- Câu hỏi mới: "xe may vuot den do bi phat bao nhieu tien"
|
294 |
-
- Output:
|
295 |
-
{{
|
296 |
-
"classification": "legal_rag",
|
297 |
-
"rewritten_question": "Mức xử phạt hành chính đối với người điều khiển xe mô tô, xe gắn máy có hành vi không chấp hành hiệu lệnh của đèn tín hiệu giao thông là bao nhiêu?"
|
298 |
-
}}
|
299 |
-
|
300 |
-
**Ví dụ 2 (Pháp lý ngoài phạm vi):**
|
301 |
-
- Câu hỏi mới: "điều kiện kết hôn tại Mỹ"
|
302 |
-
- Output:
|
303 |
-
{{
|
304 |
-
"classification": "out_of_scope_legal",
|
305 |
-
"rewritten_question": "Điều kiện kết hôn tại Mỹ được quy định như thế nào?"
|
306 |
-
}}
|
307 |
-
|
308 |
-
**Ví dụ 3 (Kiến thức chung):**
|
309 |
-
- Câu hỏi mới: "tuyen quang co dien tich bao nhieu"
|
310 |
-
- Output:
|
311 |
-
{{
|
312 |
-
"classification": "general_knowledge",
|
313 |
-
"rewritten_question": "Tỉnh Tuyên Quang có diện tích bao nhiêu?"
|
314 |
-
}}
|
315 |
-
|
316 |
-
**Ví dụ 4 (Trò chuyện/Nhận xét):**
|
317 |
-
- Câu hỏi mới: "bro trả lời oke phết"
|
318 |
-
- Output:
|
319 |
-
{{
|
320 |
-
"classification": "chit_chat",
|
321 |
-
"rewritten_question": "Cảm ơn bạn đã nhận xét."
|
322 |
-
}}
|
323 |
-
|
324 |
-
**Ví dụ 5 (Chào hỏi):**
|
325 |
-
- Câu hỏi mới: "chao ban"
|
326 |
-
- Output:
|
327 |
-
{{
|
328 |
-
"classification": "chit_chat",
|
329 |
-
"rewritten_question": "Chào bạn."
|
330 |
-
}}
|
331 |
-
|
332 |
-
**Ví dụ 6 (Lịch sử & Sai chính tả):**
|
333 |
-
- Lịch sử: [("Hỏi: Điều kiện kết hôn là gì?", "Trả lời: ...")]
|
334 |
-
- Câu hỏi mới: "the thu tuc ly hon don phuong thì sao"
|
335 |
-
- Output:
|
336 |
-
{{
|
337 |
-
"classification": "legal_rag",
|
338 |
-
"rewritten_question": "Thủ tục ly hôn theo yêu cầu của một bên (ly hôn đơn phương) được quy định như thế nào?"
|
339 |
-
}}
|
340 |
-
---
|
341 |
-
"""
|
342 |
-
|
343 |
|
344 |
# UNIFIED_PREPROCESSING_PROMPT = """
|
345 |
# Bạn là một AI điều phối viên siêu thông minh, chuyên phân tích và tối ưu hóa các câu hỏi của người dùng cho một hệ thống chatbot **CHUYÊN VỀ PHÁP LUẬT VIỆT NAM**.
|
@@ -413,43 +250,413 @@ Nhiệm vụ của bạn là nhận câu hỏi của người dùng và lịch s
|
|
413 |
|
414 |
|
415 |
|
|
|
416 |
|
|
|
|
|
417 |
|
418 |
-
|
419 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
420 |
|
421 |
-
**
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
426 |
|
427 |
-
|
428 |
-
|
429 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
430 |
xử phạt xe máy
|
431 |
không chấp hành hiệu lệnh đèn tín hiệu giao thông
|
432 |
tước quyền sử dụng giấy phép lái xe
|
433 |
|
434 |
-
**
|
435 |
-
|
436 |
-
OUTPUT:
|
437 |
thủ tục ly hôn đơn phương
|
438 |
hồ sơ ly hôn
|
439 |
giấy tờ cần thiết
|
440 |
tòa án nhân dân
|
441 |
-
|
442 |
-
**Ví dụ 3:**
|
443 |
-
Câu hỏi: Người lao động bị nợ lương 2 tháng phải làm sao?
|
444 |
-
OUTPUT:
|
445 |
-
người lao động bị nợ lương
|
446 |
-
người sử dụng lao động không trả lương
|
447 |
-
khiếu nại tiền lương
|
448 |
-
khởi kiện đòi lương
|
449 |
-
|
450 |
---
|
451 |
-
**
|
452 |
{question}
|
453 |
|
454 |
**OUTPUT:**
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
455 |
"""
|
|
|
33 |
|
34 |
# Prompt to condense question for legal chain
|
35 |
|
|
|
|
|
|
|
36 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
|
38 |
# CONDENSE_QUESTION_PROMPT = """
|
39 |
# Dựa trên lịch sử hội thoại sau và một câu hỏi mới của người dùng, hãy viết lại câu hỏi mới thành một câu hỏi **độc lập, đầy đủ ý nghĩa và ngắn gọn nhất có thể**.
|
|
|
152 |
|
153 |
# Prompt for generic chain
|
154 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
# GENERAL_PROMPT = """
|
156 |
# Bạn là JuriBot, một trợ lý AI chuyên sâu về pháp luật Việt Nam.
|
157 |
|
|
|
177 |
|
178 |
# prompt_templete.py
|
179 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
180 |
|
181 |
# UNIFIED_PREPROCESSING_PROMPT = """
|
182 |
# Bạn là một AI điều phối viên siêu thông minh, chuyên phân tích và tối ưu hóa các câu hỏi của người dùng cho một hệ thống chatbot **CHUYÊN VỀ PHÁP LUẬT VIỆT NAM**.
|
|
|
250 |
|
251 |
|
252 |
|
253 |
+
#-----------------------------New Prompts Vietnamese--------------------------------
|
254 |
|
255 |
+
# KEYWORD_EXTRACTION_PROMPT = """
|
256 |
+
# Bạn là một chuyên gia phân tích truy vấn pháp lý. Nhiệm vụ của bạn là nhận một câu h��i và rút ra một danh sách các **cụm từ khóa cốt lõi, ngắn gọn và có khả năng xuất hiện cao nhất** trong nội dung một điều luật cụ thể.
|
257 |
|
258 |
+
# **HƯỚNG DẪN:**
|
259 |
+
# - Tập trung vào **hành vi vi phạm** và **đối tượng**.
|
260 |
+
# - Loại bỏ các từ hỏi như "bao nhiêu", "là gì", "thế nào".
|
261 |
+
# - Sử dụng các thuật ngữ pháp lý nếu có thể.
|
262 |
+
# - Chỉ trả về các cụm từ khóa, mỗi cụm từ trên một dòng, không có đánh số.
|
263 |
+
|
264 |
+
# **Ví dụ 1:**
|
265 |
+
# Câu hỏi: Mức xử phạt hành chính khi xe máy vượt đèn đỏ theo quy định hiện hành?
|
266 |
+
# OUTPUT:
|
267 |
+
# xử phạt xe máy
|
268 |
+
# không chấp hành hiệu lệnh đèn tín hiệu giao thông
|
269 |
+
# tước quyền sử dụng giấy phép lái xe
|
270 |
+
|
271 |
+
# **Ví dụ 2:**
|
272 |
+
# Câu hỏi: Thủ tục ly hôn đơn phương cần những giấy tờ gì?
|
273 |
+
# OUTPUT:
|
274 |
+
# thủ tục ly hôn đơn phương
|
275 |
+
# hồ sơ ly hôn
|
276 |
+
# giấy tờ cần thiết
|
277 |
+
# tòa án nhân dân
|
278 |
+
|
279 |
+
# **Ví dụ 3:**
|
280 |
+
# Câu hỏi: Người lao động bị nợ lương 2 tháng phải làm sao?
|
281 |
+
# OUTPUT:
|
282 |
+
# người lao động bị nợ lương
|
283 |
+
# người sử dụng lao động không trả lương
|
284 |
+
# khiếu nại tiền lương
|
285 |
+
# khởi kiện đòi lương
|
286 |
+
|
287 |
+
# ---
|
288 |
+
# **Câu hỏi gốc:**
|
289 |
+
# {question}
|
290 |
|
291 |
+
# **OUTPUT:**
|
292 |
+
# """
|
293 |
+
|
294 |
+
# CONDENSE_QUESTION_PROMPT = """"
|
295 |
+
# Bạn là một chuyên gia tối ưu hóa truy vấn tìm kiếm cho hệ thống pháp luật.
|
296 |
+
# Nhiệm vụ của bạn là kết hợp lịch sử trò chuyện (nếu có liên quan) và một câu hỏi mới để tạo ra một **câu hỏi độc lập, hoàn chỉnh duy nhất**. Câu hỏi này phải rõ ràng và sẵn sàng để được sử dụng để truy vấn một cơ sở dữ liệu vector.
|
297 |
+
|
298 |
+
# **QUY TẮC BẮT BUỘC:**
|
299 |
+
# - **GIỮ NGUYÊN:** Giữ lại tất cả các thuật ngữ pháp lý, số hiệu văn bản, điều khoản, ngày tháng, năm cụ thể.
|
300 |
+
# - **KHÔNG THÊM THẮT:** Nếu câu hỏi gốc mang tính tổng quát, câu hỏi viết lại phải giữ nguyên sự tổng quát đó, không được tự ý thêm các giả định không có trong câu hỏi.
|
301 |
+
# - **BỎ QUA NẾU KHÔNG LIÊN QUAN:** Nếu câu hỏi mới là một chủ đề hoàn toàn khác với lịch sử trò chuyện, hãy bỏ qua lịch sử và chỉ tập trung vào câu hỏi mới.
|
302 |
+
# - **HOÀN CHỈNH:** Câu hỏi cuối cùng phải là một câu hỏi hoàn chỉnh, có đầy đủ chủ ngữ, vị ngữ.
|
303 |
+
|
304 |
+
# ---
|
305 |
+
# **VÍ DỤ:**
|
306 |
+
|
307 |
+
# **Ví dụ 1: Câu hỏi nối tiếp thay đổi chủ thể**
|
308 |
+
# - Lịch sử hội thoại: `[("Hỏi: Mức phạt khi vượt đèn đỏ với xe máy là bao nhiêu?", "Trả lời: ...")]`
|
309 |
+
# - Câu hỏi mới của người dùng: `còn ô tô thì sao`
|
310 |
+
# - Câu hỏi độc lập: `Mức xử phạt hành chính đối với người điều khiển xe ô tô có hành vi không chấp hành hiệu lệnh của đèn tín hiệu giao thông là bao nhiêu?`
|
311 |
+
|
312 |
+
# **Ví dụ 2: Câu hỏi mới không liên quan đến lịch sử**
|
313 |
+
# - Lịch sử hội thoại: `[("Hỏi: Thủ tục ly hôn đơn phương gồm những gì?", "Trả lời: ...")]`
|
314 |
+
# - Câu hỏi mới của người dùng: `quy định về hợp đồng lao động`
|
315 |
+
# - Câu hỏi độc lập: `Quy định của pháp luật về hợp đồng lao động là gì?`
|
316 |
+
|
317 |
+
# **Ví dụ 3: Câu hỏi mới đã đủ rõ ràng**
|
318 |
+
# - Lịch sử hội thoại: `(trống)`
|
319 |
+
# - Câu hỏi mới của người dùng: `Người lao động bị nợ lương 2 tháng thì phải làm gì?`
|
320 |
+
# - Câu hỏi độc lập: `Người lao động bị nợ lương 2 tháng thì phải làm gì?`
|
321 |
+
# ---
|
322 |
+
|
323 |
+
# **BÂY GIỜ, HÃY THỰC HIỆN NHIỆM VỤ:**
|
324 |
+
|
325 |
+
# **Lịch sử hội thoại:**
|
326 |
+
# {chat_history}
|
327 |
+
|
328 |
+
# **Câu hỏi mới của người dùng:**
|
329 |
+
# {input}
|
330 |
+
|
331 |
+
# **Câu hỏi độc lập:**
|
332 |
+
# """
|
333 |
|
334 |
+
|
335 |
+
# UNIFIED_PREPROCESSING_PROMPT=""""
|
336 |
+
# Bạn là một AI điều phối viên siêu thông minh, chuyên phân tích và tối ưu hóa các câu hỏi của người dùng cho một hệ thống chatbot **CHUYÊN VỀ PHÁP LUẬT VIỆT NAM**.
|
337 |
+
# Nhiệm vụ của bạn là nhận câu hỏi của người dùng và lịch sử trò chuyện, sau đó viết lại câu hỏi cho rõ ràng và phân loại nó một cách chính xác.
|
338 |
+
|
339 |
+
# **QUY TRÌNH BẮT BUỘC:**
|
340 |
+
|
341 |
+
# **Bước 1: CHUẨN HÓA CƠ BẢN**
|
342 |
+
# - **Thêm dấu tiếng Việt đầy đủ và chính xác** nếu câu hỏi bị thiếu dấu.
|
343 |
+
# - Sửa các lỗi chính tả và ngữ pháp thông thường.
|
344 |
+
|
345 |
+
# **Bước 2: VIẾT LẠI & HOÀN CHỈNH**
|
346 |
+
# - Dựa vào kết quả của Bước 1 và lịch sử trò chuyện, hãy giải quyết các đại từ và các câu hỏi nối tiếp.
|
347 |
+
# - Nếu đầu vào là một câu hỏi pháp lý, hãy thay thế thuật ngữ thông tục bằng thuật ngữ pháp lý chính thức và tạo ra một **câu hỏi tìm kiếm độc lập, hoàn chỉnh**.
|
348 |
+
# - Nếu đầu vào không phải là câu hỏi (ví dụ: chào hỏi, cảm ơn, nhận xét), chỉ cần chuẩn hóa nó thành một câu hoàn chỉnh và lịch sự.
|
349 |
+
|
350 |
+
# **Bước 3: PHÂN LOẠI**
|
351 |
+
# - Dựa trên nội dung đã được hoàn chỉnh ở Bước 2, phân loại nó vào MỘT trong các loại sau:
|
352 |
+
# - `legal_rag`: Nếu câu hỏi liên quan đến tra cứu quy định pháp lý của **Việt Nam**.
|
353 |
+
# - `out_of_scope_legal`: Nếu câu hỏi liên quan đến pháp luật của **quốc gia khác** hoặc các vấn đề pháp lý không thuộc phạm vi hệ thống.
|
354 |
+
# - `chit_chat`: Đối với chào hỏi, cảm ơn, nhận xét, hỏi đáp thông thường không phải là câu hỏi (ví dụ: "bạn là ai?", "bạn làm được gì?").
|
355 |
+
# - `general_knowledge`: Đối với các câu hỏi về kiến thức chung, không liên quan đến pháp luật (ví dụ: diện tích một tỉnh, thủ đô một nước).
|
356 |
+
|
357 |
+
# **Lịch sử trò chuyện (nếu có):**
|
358 |
+
# {chat_history}
|
359 |
+
|
360 |
+
# **Câu hỏi mới của người dùng:**
|
361 |
+
# {input}
|
362 |
+
|
363 |
+
# **OUTPUT:**
|
364 |
+
# **QUAN TRỌNG: Chỉ được trả về một đối tượng JSON duy nhất, không có bất kỳ văn bản, giải thích, hay lời dẫn nào trước hoặc sau nó. Toàn bộ phản hồi của bạn phải là một JSON hợp lệ.**
|
365 |
+
# {{
|
366 |
+
# "classification": "...",
|
367 |
+
# "rewritten_question": "..."
|
368 |
+
# }}
|
369 |
+
|
370 |
+
# ---
|
371 |
+
# **VÍ DỤ CHI TIẾT:**
|
372 |
+
|
373 |
+
# **Ví dụ 1 (Pháp lý trong phạm vi):**
|
374 |
+
# - Câu hỏi mới: "xe may vuot den do bi phat bao nhieu tien"
|
375 |
+
# - Output:
|
376 |
+
# {{
|
377 |
+
# "classification": "legal_rag",
|
378 |
+
# "rewritten_question": "Mức xử phạt hành chính đối với người điều khiển xe mô tô, xe gắn máy có hành vi không chấp hành hiệu lệnh của đèn tín hiệu giao thông là bao nhiêu?"
|
379 |
+
# }}
|
380 |
+
|
381 |
+
# **Ví dụ 2 (Pháp lý ngoài phạm vi):**
|
382 |
+
# - Câu hỏi mới: "điều kiện kết hôn tại Mỹ"
|
383 |
+
# - Output:
|
384 |
+
# {{
|
385 |
+
# "classification": "out_of_scope_legal",
|
386 |
+
# "rewritten_question": "Điều kiện kết hôn tại Mỹ được quy định như thế nào?"
|
387 |
+
# }}
|
388 |
+
|
389 |
+
# **Ví dụ 3 (Kiến thức chung):**
|
390 |
+
# - Câu hỏi mới: "tuyen quang co dien tich bao nhieu"
|
391 |
+
# - Output:
|
392 |
+
# {{
|
393 |
+
# "classification": "general_knowledge",
|
394 |
+
# "rewritten_question": "Tỉnh Tuyên Quang có diện tích bao nhiêu?"
|
395 |
+
# }}
|
396 |
+
|
397 |
+
# **Ví dụ 4 (Trò chuyện/Nhận xét):**
|
398 |
+
# - Câu hỏi mới: "bro trả lời oke phết"
|
399 |
+
# - Output:
|
400 |
+
# {{
|
401 |
+
# "classification": "chit_chat",
|
402 |
+
# "rewritten_question": "Cảm ơn bạn đã nhận xét."
|
403 |
+
# }}
|
404 |
+
|
405 |
+
# **Ví dụ 5 (Chào hỏi):**
|
406 |
+
# - Câu hỏi mới: "chao ban"
|
407 |
+
# - Output:
|
408 |
+
# {{
|
409 |
+
# "classification": "chit_chat",
|
410 |
+
# "rewritten_question": "Chào bạn."
|
411 |
+
# }}
|
412 |
+
|
413 |
+
# **Ví dụ 6 (Lịch sử & Sai chính tả):**
|
414 |
+
# - Lịch sử: [("Hỏi: Điều kiện kết hôn là gì?", "Trả lời: ...")]
|
415 |
+
# - Câu hỏi mới: "the thu tuc ly hon don phuong thì sao"
|
416 |
+
# - Output:
|
417 |
+
# {{
|
418 |
+
# "classification": "legal_rag",
|
419 |
+
# "rewritten_question": "Thủ tục ly hôn theo yêu cầu của một bên (ly hôn đơn phương) được quy định như thế nào?"
|
420 |
+
# }}
|
421 |
+
# ---
|
422 |
+
# """
|
423 |
+
|
424 |
+
|
425 |
+
# GENERAL_PROMPT = """
|
426 |
+
# Bạn là JuriBot, một trợ lý AI thân thiện và chuyên nghiệp, chuyên sâu về pháp luật Việt Nam.
|
427 |
+
# Nhiệm vụ của bạn là trả lời một cách lịch sự dựa trên câu hỏi đã được viết lại và phân loại của người dùng.
|
428 |
+
|
429 |
+
# **QUY TẮC PHẢN HỒI (DỰA TRÊN `classification`):**
|
430 |
+
|
431 |
+
# - Nếu `classification` là **`chit_chat`**:
|
432 |
+
# - Hãy phản hồi một cách tự nhiên và thân thiện.
|
433 |
+
# - Nếu là lời chào, hãy chào lại.
|
434 |
+
# - Nếu là lời cảm ơn, hãy đáp lại ("Rất vui được giúp bạn!").
|
435 |
+
# - Nếu là nhận xét hoặc hỏi về bản thân ("bạn là ai?"), hãy giới thiệu ngắn gọn vai trò của mình là một trợ lý pháp lý AI, nhấn mạnh chỉ cung cấp thông tin tham khảo và không thay thế luật sư.
|
436 |
+
|
437 |
+
# - Nếu `classification` là **`out_of_scope_legal`**:
|
438 |
+
# - Hãy lịch sự trả lời rằng chuyên môn của bạn chỉ giới hạn trong pháp luật Việt Nam và không thể cung cấp thông tin về luật của quốc gia khác.
|
439 |
+
|
440 |
+
# - Nếu `classification` là **`general_knowledge`**:
|
441 |
+
# - Hãy lịch sự giải thích rằng bạn là một trợ lý chuyên về pháp lý và không được đào tạo để trả lời các câu hỏi kiến thức chung.
|
442 |
+
|
443 |
+
# - Nếu `classification` là **`ambiguous_legal_topic`** (dành cho phiên bản nâng cao của prompt tiền xử lý):
|
444 |
+
# - Hãy yêu cầu người dùng làm rõ câu hỏi, có thể gợi ý một vài ví dụ để giúp họ.
|
445 |
+
|
446 |
+
# **HƯỚNG DẪN TÔNG GIỌNG:**
|
447 |
+
# - Luôn giữ thái độ chuyên nghiệp, hữu ích và khiêm tốn.
|
448 |
+
# - Kết thúc câu trả lời bằng một câu hỏi mở để khuyến khích người dùng tiếp tục hỏi về pháp luật Việt Nam (ví dụ: "Bạn có câu hỏi nào khác liên quan đến pháp luật Việt Nam không ạ?").
|
449 |
+
|
450 |
+
# ---
|
451 |
+
# **DỮ LIỆU ĐẦU VÀO:**
|
452 |
+
|
453 |
+
# **Phân loại:**
|
454 |
+
# {classification}
|
455 |
+
|
456 |
+
# **Câu hỏi của người dùng (đã được viết lại):**
|
457 |
+
# {rewritten_question}
|
458 |
+
|
459 |
+
# **Câu trả lời của bạn:**
|
460 |
+
# """
|
461 |
+
#------------------------------New Prompts Vietnamese--------------------------------
|
462 |
+
|
463 |
+
|
464 |
+
#-----------------------------New Prompts English--------------------------------
|
465 |
+
|
466 |
+
# ==============================================================================
|
467 |
+
# PROMPT 1: UNIFIED_PREPROCESSING_PROMPT
|
468 |
+
# Nhiệm vụ: "Bộ não" chính, phân tích và định tuyến câu hỏi.
|
469 |
+
# Tối ưu: Chỉ dẫn tiếng Anh ngắn gọn, giữ ví dụ tiếng Việt, quy tắc JSON nghiêm ngặt.
|
470 |
+
# ==============================================================================
|
471 |
+
UNIFIED_PREPROCESSING_PROMPT = """
|
472 |
+
You are a lean, efficient query pre-processing engine for a Vietnamese Law chatbot.
|
473 |
+
Your task is to analyze the user's input and chat history, then output a single, raw JSON object.
|
474 |
+
|
475 |
+
**INSTRUCTIONS:**
|
476 |
+
1. **Rewrite:** Create a clear, standalone Vietnamese question based on the user's input and chat history. Use official legal terms for legal queries.
|
477 |
+
2. **Classify:** Categorize the rewritten question into ONE of these types:
|
478 |
+
- `legal_rag`: A specific question about Vietnamese law.
|
479 |
+
- `out_of_scope_legal`: A question about non-Vietnamese law.
|
480 |
+
- `chit_chat`: Greetings, thanks, feedback, or questions about the bot.
|
481 |
+
- `general_knowledge`: A non-legal, general knowledge question.
|
482 |
+
- `ambiguous_legal_topic`: A legal topic mentioned without a specific question.
|
483 |
+
|
484 |
+
---
|
485 |
+
**EXAMPLES:**
|
486 |
+
|
487 |
+
# Example 1: In-scope Legal
|
488 |
+
- User Input: "xe may vuot den do bi phat bao nhieu tien"
|
489 |
+
- Output:
|
490 |
+
{
|
491 |
+
"classification": "legal_rag",
|
492 |
+
"rewritten_question": "Mức xử phạt hành chính đối với người điều khiển xe mô tô, xe gắn máy có hành vi không chấp hành hiệu lệnh của đèn tín hiệu giao thông là bao nhiêu?"
|
493 |
+
}
|
494 |
+
|
495 |
+
# Example 2: Out-of-scope Legal
|
496 |
+
- User Input: "điều kiện kết hôn tại Mỹ"
|
497 |
+
- Output:
|
498 |
+
{
|
499 |
+
"classification": "out_of_scope_legal",
|
500 |
+
"rewritten_question": "Điều kiện kết hôn tại Mỹ được quy định như thế nào?"
|
501 |
+
}
|
502 |
+
|
503 |
+
# Example 3: Chit-chat
|
504 |
+
- User Input: "bro trả lời oke phết"
|
505 |
+
- Output:
|
506 |
+
{
|
507 |
+
"classification": "chit_chat",
|
508 |
+
"rewritten_question": "Cảm ơn bạn đã nhận xét."
|
509 |
+
}
|
510 |
+
|
511 |
+
# Example 4: History-aware
|
512 |
+
- History: [("Hỏi: Điều kiện kết hôn là gì?", "Trả lời: ...")]
|
513 |
+
- User Input: "the thu tuc ly hon don phuong thì sao"
|
514 |
+
- Output:
|
515 |
+
{
|
516 |
+
"classification": "legal_rag",
|
517 |
+
"rewritten_question": "Thủ tục ly hôn theo yêu cầu của một bên (ly hôn đơn phương) được quy định như thế nào?"
|
518 |
+
}
|
519 |
+
---
|
520 |
+
|
521 |
+
**Chat History:**
|
522 |
+
{chat_history}
|
523 |
+
|
524 |
+
**User Input:**
|
525 |
+
{input}
|
526 |
+
|
527 |
+
**OUTPUT:**
|
528 |
+
**CRITICAL: Your entire response MUST be a single, raw JSON object. Do not include any text, explanations, or markdown formatting before or after the JSON.**
|
529 |
+
"""
|
530 |
+
|
531 |
+
# ==============================================================================
|
532 |
+
# PROMPT 2: QA_PROMPT_TEMPLATE
|
533 |
+
# Nhiệm vụ: Prompt RAG chính, tạo câu trả lời từ context.
|
534 |
+
# Tối ưu: Thêm quy tắc trả lời đa ngôn ngữ, giữ cấu trúc Chain-of-Thought.
|
535 |
+
# ==============================================================================
|
536 |
+
QA_PROMPT_TEMPLATE = """
|
537 |
+
You are JuriBot, a meticulous AI legal assistant.
|
538 |
+
**CRITICAL RULE: Always respond in the same language as the user's QUESTION (`{input}`).**
|
539 |
+
|
540 |
+
Your task is to answer the QUESTION based **strictly** on the provided CONTEXT.
|
541 |
+
|
542 |
+
**RULES:**
|
543 |
+
1. **NO OUTSIDE KNOWLEDGE:** Your answer must be 100% derived from the CONTEXT.
|
544 |
+
2. **BE HONEST:** If the CONTEXT is empty or irrelevant, state: "Dựa trên các tài liệu được cung cấp, tôi không tìm thấy thông tin để trả lời câu hỏi này."
|
545 |
+
3. **PRIORITIZE NEWEST LAW:** If laws conflict, use the one with the most recent `nam_ban_hanh` (year) from metadata.
|
546 |
+
4. **STATE FACTS, NOT ADVICE:** Present information only. Do not give advice or opinions.
|
547 |
+
|
548 |
+
---
|
549 |
+
**CONTEXT:**
|
550 |
+
*(Note: Context is a list of documents with `page_content` and `metadata`)*
|
551 |
+
{context}
|
552 |
+
---
|
553 |
+
**QUESTION:**
|
554 |
+
{input}
|
555 |
+
---
|
556 |
+
|
557 |
+
**ANSWER GENERATION PROCESS (Internal thought process):**
|
558 |
+
|
559 |
+
**1. Analysis:**
|
560 |
+
- **Core Request:** [Summarize what the user wants]
|
561 |
+
- **Main Subject & Action:** [Identify key entities and events]
|
562 |
+
|
563 |
+
**2. Context Evaluation:**
|
564 |
+
- [List relevant documents from CONTEXT and why. If none, state that.]
|
565 |
+
|
566 |
+
**3. Response Plan:**
|
567 |
+
- [Outline the answer structure based on selected documents.]
|
568 |
+
|
569 |
+
**4. Final Answer (Use this exact format):**
|
570 |
+
|
571 |
+
**[BEGIN FINAL ANSWER]**
|
572 |
+
|
573 |
+
### [A clear, concise title for the answer in the user's language]
|
574 |
+
|
575 |
+
[Present the answer here. Use bullet points for key information.]
|
576 |
+
- **Quy định (Regulation):** [Content of the regulation]
|
577 |
+
- **Mức phạt (Penalty):** [Details on the penalty, if any]
|
578 |
+
- **Biện pháp bổ sung (Additional Measures):** [Details on supplementary penalties]
|
579 |
+
|
580 |
+
### Nguồn tham khảo (Source)
|
581 |
+
|
582 |
+
- **Văn bản (Document):** [`ten_van_ban`, `so_hieu` from metadata]
|
583 |
+
- **Điều khoản (Clause):** [`dieu_code`, `khoan_code` from metadata, if available]
|
584 |
+
|
585 |
+
*(Repeat Source block for each document used)*
|
586 |
+
|
587 |
+
**[END FINAL ANSWER]**
|
588 |
+
"""
|
589 |
+
|
590 |
+
|
591 |
+
# ==============================================================================
|
592 |
+
# PROMPT 3: GENERAL_RESPONSE_PROMPT
|
593 |
+
# Nhiệm vụ: Tạo các câu trả lời không cần tra cứu (Non-RAG).
|
594 |
+
# Tối ưu: Thêm quy tắc trả lời đa ngôn ngữ, nhận cả `input` gốc.
|
595 |
+
# ==============================================================================
|
596 |
+
GENERAL_RESPONSE_PROMPT = """
|
597 |
+
You are JuriBot, a friendly and professional AI assistant for Vietnamese law.
|
598 |
+
**CRITICAL RULE: Always respond in the same language as the user's original question (`{input}`).**
|
599 |
+
|
600 |
+
Based on the provided classification, formulate a polite response.
|
601 |
+
|
602 |
+
- If `classification` is **`chit_chat`**: Respond naturally. If it's about you, introduce yourself as a Vietnamese legal AI assistant.
|
603 |
+
- If `classification` is **`out_of_scope_legal`**: Politely state that your expertise is limited to Vietnamese law.
|
604 |
+
- If `classification` is **`general_knowledge`**: Politely explain you are a specialized legal AI and cannot answer general knowledge questions.
|
605 |
+
- If `classification` is **`ambiguous_legal_topic`**: Ask for clarification and suggest example questions.
|
606 |
+
|
607 |
+
---
|
608 |
+
**INPUT DATA:**
|
609 |
+
- **User's Original Question:** {input}
|
610 |
+
- **Classification:** {classification}
|
611 |
+
- **Rewritten Question:** {rewritten_question}
|
612 |
+
|
613 |
+
**YOUR RESPONSE (in user's language):**
|
614 |
+
"""
|
615 |
+
|
616 |
+
# ==============================================================================
|
617 |
+
# Các prompt phụ (KEYWORD và CONDENSE) - Tùy chọn nếu bạn có dùng trong chain
|
618 |
+
# Tối ưu: Đã được dịch và rút gọn.
|
619 |
+
# ==============================================================================
|
620 |
+
KEYWORD_EXTRACTION_PROMPT = """
|
621 |
+
You are a legal query analyst. Extract core search keywords from the Vietnamese question.
|
622 |
+
Focus on the **violating act**, **subject**, and **consequences**. Remove question words.
|
623 |
+
Return only keywords, one per line.
|
624 |
+
|
625 |
+
**Question:** Mức xử phạt hành chính khi xe máy vượt đèn đỏ theo quy định hiện hành?
|
626 |
+
**OUTPUT:**
|
627 |
xử phạt xe máy
|
628 |
không chấp hành hiệu lệnh đèn tín hiệu giao thông
|
629 |
tước quyền sử dụng giấy phép lái xe
|
630 |
|
631 |
+
**Question:** Thủ tục ly hôn đơn phương cần những giấy tờ gì?
|
632 |
+
**OUTPUT:**
|
|
|
633 |
thủ tục ly hôn đơn phương
|
634 |
hồ sơ ly hôn
|
635 |
giấy tờ cần thiết
|
636 |
tòa án nhân dân
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
637 |
---
|
638 |
+
**Question:**
|
639 |
{question}
|
640 |
|
641 |
**OUTPUT:**
|
642 |
+
"""
|
643 |
+
|
644 |
+
CONDENSE_QUESTION_PROMPT = """
|
645 |
+
Rephrase the follow-up question into a single, standalone Vietnamese question, using the chat history for context. If the new question is unrelated, ignore the history.
|
646 |
+
|
647 |
+
**History:** `[("Hỏi: Mức phạt khi vượt đèn đỏ với xe máy là bao nhiêu?", "Trả lời: ...")]`
|
648 |
+
**Follow-up:** `còn ô tô thì sao`
|
649 |
+
**Standalone Question:** `Mức xử phạt hành chính đối với người điều khiển xe ô tô có hành vi không chấp hành hiệu lệnh của đèn tín hiệu giao thông là bao nhiêu?`
|
650 |
+
|
651 |
+
**History:** `[("Hỏi: Thủ tục ly hôn đơn phương gồm những gì?", "Trả lời: ...")]`
|
652 |
+
**Follow-up:** `quy định về hợp đồng lao động`
|
653 |
+
**Standalone Question:** `Quy định của pháp luật về hợp đồng lao động là gì?`
|
654 |
+
---
|
655 |
+
**History:**
|
656 |
+
{chat_history}
|
657 |
+
|
658 |
+
**Follow-up Question:**
|
659 |
+
{input}
|
660 |
+
|
661 |
+
**Standalone Question:**
|
662 |
"""
|
rag_components.py
CHANGED
@@ -14,6 +14,8 @@ import weaviate
|
|
14 |
import weaviate.classes.config as wvc_config
|
15 |
from weaviate.exceptions import WeaviateQueryException
|
16 |
import time
|
|
|
|
|
17 |
from operator import itemgetter
|
18 |
|
19 |
|
@@ -425,22 +427,36 @@ def get_google_llm(google_api_key):
|
|
425 |
|
426 |
|
427 |
#new update
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
428 |
def _extract_final_answer(rag_output_with_thinking: str) -> str:
|
429 |
"""
|
430 |
Hàm trợ giúp để trích xuất câu trả lời cuối cùng từ output của QA_PROMPT_TEMPLATE.
|
431 |
-
Nó tìm các thẻ đánh dấu đặc biệt và chỉ trả về nội dung ở giữa.
|
432 |
"""
|
433 |
-
start_tag = "[
|
434 |
-
end_tag = "[
|
435 |
|
436 |
start_index = rag_output_with_thinking.find(start_tag)
|
437 |
end_index = rag_output_with_thinking.find(end_tag)
|
438 |
|
439 |
if start_index != -1 and end_index != -1:
|
440 |
-
# Lấy nội dung giữa 2 thẻ
|
441 |
return rag_output_with_thinking[start_index + len(start_tag):end_index].strip()
|
442 |
|
443 |
-
# Nếu không tìm thấy thẻ, trả về toàn bộ output để gỡ lỗi
|
444 |
logger.warning("Không tìm thấy thẻ đánh dấu trả lời trong output của RAG. Trả về toàn bộ output.")
|
445 |
return rag_output_with_thinking
|
446 |
|
@@ -451,63 +467,53 @@ def create_qa_chain(
|
|
451 |
process_input_llm: any = None
|
452 |
):
|
453 |
"""
|
454 |
-
PHIÊN BẢN
|
455 |
-
|
456 |
"""
|
457 |
if not all([llm, retriever]):
|
458 |
logger.error("🔸 Thiếu LLM hoặc Retriever chính để tạo QA Chain.")
|
459 |
return None
|
460 |
|
461 |
try:
|
462 |
-
logger.info("🔸 Bắt đầu tạo QA Chain
|
463 |
|
464 |
preprocessing_llm = process_input_llm or llm
|
465 |
|
466 |
-
# ----- 1. KHAI BÁO
|
467 |
-
|
468 |
-
# Prompt tiền xử lý hợp nhất (bộ não của hệ thống)
|
469 |
-
# Dòng này đã được sửa để khớp với tên prompt của bạn
|
470 |
unified_preprocessing_prompt = ChatPromptTemplate.from_template(
|
471 |
prompt_templete.UNIFIED_PREPROCESSING_PROMPT
|
472 |
)
|
473 |
-
|
474 |
-
# Prompt tạo câu trả lời RAG (với Chain-of-Thought)
|
475 |
qa_rag_prompt = ChatPromptTemplate.from_template(
|
476 |
prompt_templete.QA_PROMPT_TEMPLATE
|
477 |
)
|
478 |
-
|
479 |
-
# Prompt tạo câu trả lời chung (cho các trường hợp không phải pháp lý)
|
480 |
general_response_prompt = ChatPromptTemplate.from_template(
|
481 |
-
prompt_templete.
|
482 |
)
|
483 |
|
484 |
-
# ----- 2. ĐỊNH NGHĨA CÁC NHÁNH XỬ LÝ
|
485 |
|
486 |
-
# --- Nhánh A: LEGAL
|
487 |
legal_rag_chain = (
|
488 |
RunnablePassthrough.assign(
|
489 |
context=itemgetter("rewritten_question") | retriever
|
490 |
).assign(
|
491 |
-
#
|
492 |
answer=(
|
493 |
-
|
494 |
-
| qa_rag_prompt
|
495 |
| llm
|
496 |
| StrOutputParser()
|
497 |
| RunnableLambda(_extract_final_answer)
|
498 |
)
|
499 |
)
|
500 |
-
# Chỉ
|
501 |
| (lambda x: {"answer": x["answer"], "context": x["context"]})
|
502 |
-
).with_config({"run_name": "
|
503 |
-
|
504 |
|
505 |
-
# --- Nhánh B: GENERAL RESPONSE (
|
506 |
general_response_chain = (
|
507 |
general_response_prompt
|
508 |
| llm
|
509 |
| StrOutputParser()
|
510 |
-
# Bọc output lại thành dict để đồng bộ với nhánh legal
|
511 |
| (lambda answer_str: {"answer": answer_str, "context": []})
|
512 |
).with_config({"run_name": "GeneralResponseChain"})
|
513 |
|
@@ -515,8 +521,6 @@ def create_qa_chain(
|
|
515 |
def route(info: dict):
|
516 |
classification = info.get("classification")
|
517 |
logger.info(f"➡️ Định tuyến truy vấn với phân loại: '{classification}'")
|
518 |
-
|
519 |
-
# Sử dụng 'legal_rag' vì đó là tên phân loại trong prompt của bạn
|
520 |
if classification == "legal_rag":
|
521 |
return legal_rag_chain
|
522 |
else:
|
@@ -524,24 +528,44 @@ def create_qa_chain(
|
|
524 |
|
525 |
# ----- 4. KẾT HỢP THÀNH FULL CHAIN -----
|
526 |
|
527 |
-
#
|
528 |
-
preprocessing_chain = unified_preprocessing_prompt | preprocessing_llm | JsonOutputParser()
|
529 |
-
|
530 |
-
|
531 |
-
def chain_with_context(info_dict: dict):
|
532 |
-
selected_chain = route(info_dict)
|
533 |
-
return selected_chain.invoke(info_dict)
|
534 |
|
535 |
-
#
|
536 |
-
|
537 |
-
|
|
|
|
|
|
|
|
|
538 |
|
539 |
-
|
540 |
-
|
|
|
|
|
|
|
|
|
|
|
541 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
542 |
|
|
|
543 |
|
544 |
-
logger.info("✅ Tạo thành công QA Chain
|
545 |
return full_chain
|
546 |
|
547 |
except Exception as e:
|
|
|
14 |
import weaviate.classes.config as wvc_config
|
15 |
from weaviate.exceptions import WeaviateQueryException
|
16 |
import time
|
17 |
+
import json
|
18 |
+
import re
|
19 |
from operator import itemgetter
|
20 |
|
21 |
|
|
|
427 |
|
428 |
|
429 |
#new update
|
430 |
+
def _extract_and_parse_json(text_with_json: str) -> dict:
|
431 |
+
"""
|
432 |
+
Hàm trợ giúp để tìm và trích xuất khối JSON đầu tiên từ một chuỗi văn bản.
|
433 |
+
"""
|
434 |
+
json_match = re.search(r'\{.*\}', text_with_json, re.DOTALL)
|
435 |
+
if json_match:
|
436 |
+
json_str = json_match.group(0)
|
437 |
+
try:
|
438 |
+
return json.loads(json_str)
|
439 |
+
except json.JSONDecodeError:
|
440 |
+
logger.error(f"Không thể phân tích chuỗi JSON được trích xuất: {json_str}")
|
441 |
+
raise
|
442 |
+
else:
|
443 |
+
logger.error(f"Không tìm thấy khối JSON nào trong output: {text_with_json}")
|
444 |
+
raise ValueError("Không tìm thấy đối tượng JSON trong output của LLM")
|
445 |
+
|
446 |
+
|
447 |
def _extract_final_answer(rag_output_with_thinking: str) -> str:
|
448 |
"""
|
449 |
Hàm trợ giúp để trích xuất câu trả lời cuối cùng từ output của QA_PROMPT_TEMPLATE.
|
|
|
450 |
"""
|
451 |
+
start_tag = "[BEGIN FINAL ANSWER]"
|
452 |
+
end_tag = "[END FINAL ANSWER]"
|
453 |
|
454 |
start_index = rag_output_with_thinking.find(start_tag)
|
455 |
end_index = rag_output_with_thinking.find(end_tag)
|
456 |
|
457 |
if start_index != -1 and end_index != -1:
|
|
|
458 |
return rag_output_with_thinking[start_index + len(start_tag):end_index].strip()
|
459 |
|
|
|
460 |
logger.warning("Không tìm thấy thẻ đánh dấu trả lời trong output của RAG. Trả về toàn bộ output.")
|
461 |
return rag_output_with_thinking
|
462 |
|
|
|
467 |
process_input_llm: any = None
|
468 |
):
|
469 |
"""
|
470 |
+
PHIÊN BẢN CUỐI CÙNG: Tạo ra một RAG chain hoàn chỉnh, có khả năng xử lý đa ngôn ngữ
|
471 |
+
bằng cách bảo toàn dữ liệu đầu vào gốc.
|
472 |
"""
|
473 |
if not all([llm, retriever]):
|
474 |
logger.error("🔸 Thiếu LLM hoặc Retriever chính để tạo QA Chain.")
|
475 |
return None
|
476 |
|
477 |
try:
|
478 |
+
logger.info("🔸 Bắt đầu tạo QA Chain phiên bản Tối Ưu Nhất...")
|
479 |
|
480 |
preprocessing_llm = process_input_llm or llm
|
481 |
|
482 |
+
# ----- 1. KHAI BÁO PROMPTS -----
|
|
|
|
|
|
|
483 |
unified_preprocessing_prompt = ChatPromptTemplate.from_template(
|
484 |
prompt_templete.UNIFIED_PREPROCESSING_PROMPT
|
485 |
)
|
|
|
|
|
486 |
qa_rag_prompt = ChatPromptTemplate.from_template(
|
487 |
prompt_templete.QA_PROMPT_TEMPLATE
|
488 |
)
|
|
|
|
|
489 |
general_response_prompt = ChatPromptTemplate.from_template(
|
490 |
+
prompt_templete.GENERAL_RESPONSE_PROMPT
|
491 |
)
|
492 |
|
493 |
+
# ----- 2. ĐỊNH NGHĨA CÁC NHÁNH XỬ LÝ -----
|
494 |
|
495 |
+
# --- Nhánh A: LEGAL RAG (Nhận dict đầy đủ) ---
|
496 |
legal_rag_chain = (
|
497 |
RunnablePassthrough.assign(
|
498 |
context=itemgetter("rewritten_question") | retriever
|
499 |
).assign(
|
500 |
+
# Lấy câu trả lời đã được dọn dẹp
|
501 |
answer=(
|
502 |
+
qa_rag_prompt
|
|
|
503 |
| llm
|
504 |
| StrOutputParser()
|
505 |
| RunnableLambda(_extract_final_answer)
|
506 |
)
|
507 |
)
|
508 |
+
# Chỉ trả về 2 key quan trọng nhất
|
509 |
| (lambda x: {"answer": x["answer"], "context": x["context"]})
|
510 |
+
).with_config({"run_name": "LegalRAGChain"})
|
|
|
511 |
|
512 |
+
# --- Nhánh B: GENERAL RESPONSE (Nhận dict đầy đủ) ---
|
513 |
general_response_chain = (
|
514 |
general_response_prompt
|
515 |
| llm
|
516 |
| StrOutputParser()
|
|
|
517 |
| (lambda answer_str: {"answer": answer_str, "context": []})
|
518 |
).with_config({"run_name": "GeneralResponseChain"})
|
519 |
|
|
|
521 |
def route(info: dict):
|
522 |
classification = info.get("classification")
|
523 |
logger.info(f"➡️ Định tuyến truy vấn với phân loại: '{classification}'")
|
|
|
|
|
524 |
if classification == "legal_rag":
|
525 |
return legal_rag_chain
|
526 |
else:
|
|
|
528 |
|
529 |
# ----- 4. KẾT HỢP THÀNH FULL CHAIN -----
|
530 |
|
531 |
+
# <--- THAY ĐỔI QUAN TRỌNG BẮT ĐẦU TỪ ĐÂY --->
|
|
|
|
|
|
|
|
|
|
|
|
|
532 |
|
533 |
+
# 4.1. Chuỗi con để thực hiện tiền xử lý và trả về JSON
|
534 |
+
preprocessing_logic = (
|
535 |
+
unified_preprocessing_prompt
|
536 |
+
| preprocessing_llm
|
537 |
+
| StrOutputParser()
|
538 |
+
| RunnableLambda(_extract_and_parse_json)
|
539 |
+
)
|
540 |
|
541 |
+
# 4.2. Xây dựng chuỗi chính để BẢO TOÀN và HỢP NHẤT dữ liệu
|
542 |
+
full_chain = (
|
543 |
+
# Bắt đầu với một Passthrough để giữ lại dữ liệu gốc (input, chat_history)
|
544 |
+
RunnablePassthrough.assign(
|
545 |
+
# Chạy chuỗi tiền xử lý và gán kết quả của nó vào một key mới là `processed`
|
546 |
+
processed=preprocessing_logic
|
547 |
+
)
|
548 |
|
549 |
+
| RunnableLambda(
|
550 |
+
# Hàm này sẽ "làm phẳng" dict trên thành một dict duy nhất
|
551 |
+
# để các nhánh sau có thể truy cập tất cả các key
|
552 |
+
lambda x: {
|
553 |
+
"input": x["input"],
|
554 |
+
"chat_history": x.get("chat_history", []),
|
555 |
+
"classification": x["processed"]["classification"],
|
556 |
+
"rewritten_question": x["processed"]["rewritten_question"]
|
557 |
+
}
|
558 |
+
)
|
559 |
+
# 4.3. Chạy bộ định tuyến với dict đã được làm phẳng
|
560 |
+
| RunnableLambda(
|
561 |
+
# `info_dict` bây giờ chứa tất cả các key cần thiết
|
562 |
+
lambda info_dict: route(info_dict).invoke(info_dict)
|
563 |
+
)
|
564 |
+
)
|
565 |
|
566 |
+
# <--- THAY ĐỔI QUAN TRỌNG KẾT THÚC TẠI ĐÂY --->
|
567 |
|
568 |
+
logger.info("✅ Tạo thành công QA Chain phiên bản TỐI ƯU NHẤT.")
|
569 |
return full_chain
|
570 |
|
571 |
except Exception as e:
|