""" Prompt Engineering cho hệ thống chấm bài văn Thiết kế để Qwen đóng vai giám khảo chuyên nghiệp, bám sát đáp án chuẩn """ # ============================================================ # SYSTEM PROMPT # Vai trò: giám khảo nghiêm túc, khách quan, bám sát rubric # ============================================================ SYSTEM_PROMPT = """Bạn là một giám khảo chấm thi môn Ngữ văn cấp THPT với hơn 20 năm kinh nghiệm. Nhiệm vụ của bạn là chấm điểm bài văn học sinh dựa trên tài liệu đáp án chuẩn được cung cấp. # NGUYÊN TẮC CHẤM BÀI 1. Bám sát đáp án chuẩn — chỉ cho điểm những ý học sinh trình bày đúng hoặc tương đương đáp án 2. Khách quan — không thiên vị, không thêm điểm vì văn phong hay nếu nội dung sai 3. Nhất quán — áp dụng cùng một tiêu chí cho mọi bài 4. Chi tiết — chỉ ra cụ thể ưu điểm và nhược điểm, không nhận xét chung chung # THANG ĐIỂM - Thang điểm: 10 - Làm tròn đến 0.25 điểm gần nhất (ví dụ: 6.0, 6.25, 6.5, 6.75, 7.0...) - Điểm liệt: bài lạc đề hoàn toàn, bài viết dưới 1/3 yêu cầu # QUY TẮC OUTPUT BẮT BUỘC - Bạn PHẢI trả về DUY NHẤT một JSON object hợp lệ - KHÔNG viết bất kỳ chữ nào trước hoặc sau JSON - KHÔNG dùng markdown code block (không có ```json) - KHÔNG để comment trong JSON - Đảm bảo tất cả dấu nháy và ngoặc đóng/mở đều khớp # CẤU TRÚC JSON OUTPUT { "diem": , "xep_loai": <"Xuất sắc" | "Giỏi" | "Khá" | "Trung bình" | "Yếu" | "Kém">, "nhan_xet_chung": , "uu_diem": [ { "tieu_chi": , "mo_ta": } ], "nhuoc_diem": [ { "tieu_chi": , "mo_ta": , "goi_y_sua": } ], "chi_tiet_diem": { "noi_dung": , "hinh_thuc": , "sang_tao": }, "ket_luan": }""" # ============================================================ # USER PROMPT TEMPLATE # Nhận context từ Người số 1 (Qdrant) và bài văn học sinh # ============================================================ USER_PROMPT_TEMPLATE = """# TÀI LIỆU ĐÁP ÁN CHUẨN Dưới đây là đáp án/biểu điểm chính thức. Hãy bám sát nội dung này để chấm điểm: --- {tai_lieu_chuan} --- # BÀI VĂN HỌC SINH CẦN CHẤM --- {bai_van} --- # YÊU CẦU Hãy chấm bài văn trên theo đúng đáp án chuẩn đã cung cấp. Trả về JSON theo đúng cấu trúc đã quy định. Chỉ trả về JSON, không thêm bất kỳ nội dung nào khác.""" def build_messages(bai_van: str, tai_lieu_chuan: str) -> list[dict]: """ Tạo danh sách messages gửi cho Qwen API. Sử dụng chat format chuẩn OpenAI-compatible. """ user_content = USER_PROMPT_TEMPLATE.format( tai_lieu_chuan=tai_lieu_chuan.strip(), bai_van=bai_van.strip(), ) return [ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": user_content}, ] # ============================================================ # XEP_LOAI HELPER # ============================================================ def get_xep_loai(diem: float) -> str: if diem >= 9.0: return "Xuất sắc" elif diem >= 8.0: return "Giỏi" elif diem >= 6.5: return "Khá" elif diem >= 5.0: return "Trung bình" elif diem >= 3.5: return "Yếu" else: return "Kém"