Spaces:
Runtime error
Runtime error
update analyze : add topic and Guardrail LLM error
Browse files- rag/analyze_and_expand.py +36 -6
- rag/qa_pipeline.py +4 -2
rag/analyze_and_expand.py
CHANGED
|
@@ -38,17 +38,21 @@ def analyze_and_expand_query(question: str) -> Dict[str, Any]:
|
|
| 38 |
- Nếu `CÂU HỎI` là câu hỏi cá nhân, trêu đùa (VD: "bạn biết tôi là ai không", "ăn cơm chưa") -> BỎ QUA TÀI LIỆU, trả lời ngay: "Xin lỗi, tôi chỉ hỗ trợ giải đáp thông tin về quy chế đào tạo."
|
| 39 |
- Nếu `TÀI LIỆU THAM KHẢO` chứa nội dung KHÔNG LIÊN QUAN CHÚT NÀO đến câu hỏi (VD: Hỏi về 'điểm rèn luyện' nhưng tài liệu lại nói về 'học phí') -> TUYỆT ĐỐI KHÔNG tóm tắt tài liệu. Trả lời ngay: "Rất tiếc, hệ thống không tìm thấy thông tin phù hợp trong quy chế để trả lời câu hỏi của bạn."
|
| 40 |
|
| 41 |
-
2.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
- CHỈ DÀNH CHO: "Xin chào", "Hi", "Hello", "Cảm ơn", "Tạm biệt", "Bạn tên là gì?", "Bạn ai tạo ra".
|
| 43 |
- HÀNH ĐỘNG: Trả về câu trả lời ngắn gọn, thân thiện.
|
| 44 |
- Expanded queries: Rỗng [].
|
| 45 |
|
| 46 |
-
|
| 47 |
- Dành cho TẤT CẢ các câu hỏi khác, kể cả câu hỏi ngắn hay viết tắt.
|
| 48 |
- Ví dụ: "Quy chế thi", "mất mạng thì sao", "bị đình chỉ", "tính điểm thế nào", "sinh viên làm gì".
|
| 49 |
- BẮT BUỘC đặt "answer": null (để hệ thống đi tìm trong tài liệu).
|
| 50 |
- Expanded queries: Tạo 2-3 biến thể từ khóa để tìm kiếm tốt hơn.
|
| 51 |
-
|
| 52 |
- Trả về danh sách CHÍNH XÁC 3 CÂU bao gồm: 1 câu gốc đã tối ưu + 2 biến thể theo từ khóa học vụ. KHÔNG ĐƯỢC sinh quá 3 câu.
|
| 53 |
- Bạn phải đóng vai một chuyên viên phòng Đào tạo. Nhiệm vụ của bạn là "dịch" ngôn ngữ đời thường/viết tắt của sinh viên sang các THUẬT NGỮ HÀNH CHÍNH, PHÁP LÝ chính thức thường xuất hiện trong các văn bản quy phạm.
|
| 54 |
- LUÔN LUÔN tạo ra các biến thể tìm kiếm theo 3 hướng sau để đảm bảo không bỏ sót tài liệu:
|
|
@@ -59,8 +63,8 @@ def analyze_and_expand_query(question: str) -> Dict[str, Any]:
|
|
| 59 |
|
| 60 |
OUTPUT JSON FORMAT:
|
| 61 |
{{
|
| 62 |
-
"question_type": "normal" | "simple" | "comparative" | "sequential" | "temporal" | "verification" | "exception",
|
| 63 |
-
"answer": "Nội dung trả lời (chỉ nếu là normal) hoặc null (nếu là câu hỏi thi cử)",
|
| 64 |
"expanded_queries": ["Câu số 1", "Câu số 2", "Câu số 3"]
|
| 65 |
}}
|
| 66 |
|
|
@@ -104,11 +108,37 @@ def analyze_and_expand_query(question: str) -> Dict[str, Any]:
|
|
| 104 |
# Logic an toàn: Nếu AI lỡ trả lời câu hỏi chuyên môn trong field "answer", ta xóa nó đi để ép hệ thống tìm docs
|
| 105 |
q_type = result.get("question_type", "simple")
|
| 106 |
ans = result.get("answer", None)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
if q_type == "normal" and not ans:
|
| 109 |
ans = "Chào bạn 👋 Mình hỗ trợ tra cứu quy chế đào tạo."
|
|
|
|
|
|
|
| 110 |
|
| 111 |
-
if q_type != "normal":
|
| 112 |
ans = None
|
| 113 |
|
| 114 |
# Đảm bảo danh sách truy vấn
|
|
|
|
| 38 |
- Nếu `CÂU HỎI` là câu hỏi cá nhân, trêu đùa (VD: "bạn biết tôi là ai không", "ăn cơm chưa") -> BỎ QUA TÀI LIỆU, trả lời ngay: "Xin lỗi, tôi chỉ hỗ trợ giải đáp thông tin về quy chế đào tạo."
|
| 39 |
- Nếu `TÀI LIỆU THAM KHẢO` chứa nội dung KHÔNG LIÊN QUAN CHÚT NÀO đến câu hỏi (VD: Hỏi về 'điểm rèn luyện' nhưng tài liệu lại nói về 'học phí') -> TUYỆT ĐỐI KHÔNG tóm tắt tài liệu. Trả lời ngay: "Rất tiếc, hệ thống không tìm thấy thông tin phù hợp trong quy chế để trả lời câu hỏi của bạn."
|
| 40 |
|
| 41 |
+
2. Loại "outlier" (Ngoài lề):
|
| 42 |
+
- Dành cho các câu hỏi hoàn toàn không liên quan đến QUY CHẾ ĐÀO TẠO CỦA TRƯỜNG ĐẠI HỌC THỦY LỢI ( VD : các câu hỏi về trường khác, chủ đề khác, hoặc câu hỏi cá nhân, trêu đùa).
|
| 43 |
+
- HÀNH ĐỘNG: Trả về câu trả lời từ chối lịch sự, KHÔNG ĐƯỢC phép trả lời theo kiểu "Tôi không biết" hoặc "Tôi không thể trả lời". PHẢI TRẢ LỜI CỤ THỂ rằng bạn chỉ hỗ trợ về quy chế đào tạo của Thủy Lợi.
|
| 44 |
+
- Expanded queries: Rỗng [].
|
| 45 |
+
3. LOẠI "normal" (Xã giao):
|
| 46 |
- CHỈ DÀNH CHO: "Xin chào", "Hi", "Hello", "Cảm ơn", "Tạm biệt", "Bạn tên là gì?", "Bạn ai tạo ra".
|
| 47 |
- HÀNH ĐỘNG: Trả về câu trả lời ngắn gọn, thân thiện.
|
| 48 |
- Expanded queries: Rỗng [].
|
| 49 |
|
| 50 |
+
4. LOẠI "simple" / "comparative" / "sequential" / "temporal" / "verification" / "exception" (Tìm kiếm tài liệu):
|
| 51 |
- Dành cho TẤT CẢ các câu hỏi khác, kể cả câu hỏi ngắn hay viết tắt.
|
| 52 |
- Ví dụ: "Quy chế thi", "mất mạng thì sao", "bị đình chỉ", "tính điểm thế nào", "sinh viên làm gì".
|
| 53 |
- BẮT BUỘC đặt "answer": null (để hệ thống đi tìm trong tài liệu).
|
| 54 |
- Expanded queries: Tạo 2-3 biến thể từ khóa để tìm kiếm tốt hơn.
|
| 55 |
+
5. KỸ NĂNG MỞ RỘNG TỪ KHÓA TỔNG QUÁT (BẮT BUỘC):
|
| 56 |
- Trả về danh sách CHÍNH XÁC 3 CÂU bao gồm: 1 câu gốc đã tối ưu + 2 biến thể theo từ khóa học vụ. KHÔNG ĐƯỢC sinh quá 3 câu.
|
| 57 |
- Bạn phải đóng vai một chuyên viên phòng Đào tạo. Nhiệm vụ của bạn là "dịch" ngôn ngữ đời thường/viết tắt của sinh viên sang các THUẬT NGỮ HÀNH CHÍNH, PHÁP LÝ chính thức thường xuất hiện trong các văn bản quy phạm.
|
| 58 |
- LUÔN LUÔN tạo ra các biến thể tìm kiếm theo 3 hướng sau để đảm bảo không bỏ sót tài liệu:
|
|
|
|
| 63 |
|
| 64 |
OUTPUT JSON FORMAT:
|
| 65 |
{{
|
| 66 |
+
"question_type": "outlier"|"normal" | "simple" | "comparative" | "sequential" | "temporal" | "verification" | "exception",
|
| 67 |
+
"answer": "Nội dung trả lời (chỉ nếu là normal hoặc outlier) hoặc null (nếu là câu hỏi thi cử)",
|
| 68 |
"expanded_queries": ["Câu số 1", "Câu số 2", "Câu số 3"]
|
| 69 |
}}
|
| 70 |
|
|
|
|
| 108 |
# Logic an toàn: Nếu AI lỡ trả lời câu hỏi chuyên môn trong field "answer", ta xóa nó đi để ép hệ thống tìm docs
|
| 109 |
q_type = result.get("question_type", "simple")
|
| 110 |
ans = result.get("answer", None)
|
| 111 |
+
question_lower = question.lower()
|
| 112 |
+
|
| 113 |
+
academic_keywords = [
|
| 114 |
+
"tín chỉ", "học bổng", "bảo lưu", "thi", "điểm", "học vụ",
|
| 115 |
+
"buộc thôi học", "đình chỉ", "nghỉ học", "học phí", "rèn luyện",
|
| 116 |
+
"cảnh báo", "tốt nghiệp", "học lại", "học cải thiện", "đồ án",
|
| 117 |
+
"chuyên đề", "chuẩn đầu ra", "học kỳ", "học phần"
|
| 118 |
+
]
|
| 119 |
+
school_keywords = ["tlu", "thủy lợi", "thuy loi", "truong minh", "trường mình"]
|
| 120 |
+
|
| 121 |
+
has_academic_keyword = any(kw in question_lower for kw in academic_keywords)
|
| 122 |
+
has_school_keyword = any(skw in question_lower for skw in school_keywords)
|
| 123 |
|
| 124 |
+
if q_type == "normal":
|
| 125 |
+
# Normal: Chỉ cần có từ khóa học vụ là bẻ lái (hoặc câu quá dài)
|
| 126 |
+
if has_academic_keyword or len(question.split()) > 10:
|
| 127 |
+
yield " Phát hiện từ khóa học vụ. Ép về simple."
|
| 128 |
+
q_type = "simple"
|
| 129 |
+
ans = None
|
| 130 |
+
|
| 131 |
+
elif q_type == "outlier":
|
| 132 |
+
if has_academic_keyword and has_school_keyword:
|
| 133 |
+
yield " G Có đủ từ khóa học vụ và tên trường. Cứu vớt ép về simple."
|
| 134 |
+
q_type = "simple"
|
| 135 |
+
ans = None
|
| 136 |
if q_type == "normal" and not ans:
|
| 137 |
ans = "Chào bạn 👋 Mình hỗ trợ tra cứu quy chế đào tạo."
|
| 138 |
+
if q_type == "outlier" and not ans:
|
| 139 |
+
ans = "Xin lỗi, tôi là trợ lý AI chuyên trách của Trường Đại học Thủy Lợi. Tôi chỉ hỗ trợ giải đáp các quy chế và thông tin liên quan đến sinh viên Thủy Lợi."
|
| 140 |
|
| 141 |
+
if q_type != "normal" and q_type != "outlier":
|
| 142 |
ans = None
|
| 143 |
|
| 144 |
# Đảm bảo danh sách truy vấn
|
rag/qa_pipeline.py
CHANGED
|
@@ -141,9 +141,11 @@ def ask_ai_stream_delta(message: str, history: List, hybrid_retriever, cohort_ke
|
|
| 141 |
question = generate_standalone_query(message, history)
|
| 142 |
|
| 143 |
processed_data = analyze_and_expand_query(question)
|
|
|
|
| 144 |
|
| 145 |
-
|
| 146 |
-
|
|
|
|
| 147 |
yield ans
|
| 148 |
return
|
| 149 |
|
|
|
|
| 141 |
question = generate_standalone_query(message, history)
|
| 142 |
|
| 143 |
processed_data = analyze_and_expand_query(question)
|
| 144 |
+
q_type = processed_data.get("question_type")
|
| 145 |
|
| 146 |
+
# Chặn ngay lập tức nếu là xã giao hoặc lạc đề
|
| 147 |
+
if q_type in ["normal", "outlier"]:
|
| 148 |
+
ans = processed_data.get("answer") or "Mình là trợ lý hỗ trợ quy chế đào tạo Trường Đại học Thủy Lợi. Bạn cần hỏi gì về quy chế?"
|
| 149 |
yield ans
|
| 150 |
return
|
| 151 |
|