Chẩn đoán thích ứng CAT-lite
Cách chọn câu hỏi, chấm MCQ và rubric-AI, phân bổ ngân sách và xác định điều kiện dừng chẩn đoán.
CAT — Computerized Adaptive Testing là kiểm tra thích ứng trên máy tính. Fidea dùng bản rút gọn, có mục tiêu lấy đủ bằng chứng với ít câu hỏi hợp lý.
[!NOTE] CAT-lite hiện tại là thuật toán chọn câu tất định trên Question Bank tĩnh. Nó chưa phải mô hình CAT thống kê đầy đủ như IRT.
1. Candidate set — tập câu hỏi ứng viên
Với Cluster đang kiểm tra:
- Lấy toàn bộ item của Cluster từ Question Bank đã publish.
- Bỏ item không đạt
is_servable_item()— xem §7. - Loại các
question_idđã hỏi. - Xác định core competency chưa có evidence.
- Sắp theo độ khó giảm dần.
- Trong cùng độ khó, ưu tiên câu phủ competency chưa có evidence.
Quy đổi độ khó:
Sort key trong code tương đương:
(-difficulty_rank, covers_uncovered ? 0 : 1)Do Python sort ổn định, khi hai item cùng key, thứ tự gốc trong Question Bank được giữ nguyên.
2. Chấm bài — hai đường
Mỗi Question Bank có 143 item mỗi môn (715 item cho cả 5 môn): 78 multiple_choice,
39 short_answer, 26 high_information. Runtime hôm nay phát hai loại
(SERVABLE_QUESTION_TYPES), và hai loại đó đi hai đường chấm khác nhau.
2.1 MCQ — Level 0 vĩnh viễn
is_exact_match() chỉ trim + upper, không normalize gì thêm:
Không gọi LLM, không truy vấn pgvector và không tải rubric mới khi chấm. Nới lỏng
phép so khớp này sẽ làm lệch mọi nhãn golden đang khoá false_confirmation_rate.
2.2 high_information — rubric-AI sau guardrail
grade_rubric_ai() (src/agents/diagnostic/grading.py) chấm theo rubric v2 đã
duyệt, prompt src/prompts/system_prompts/rubric_grader.md
(RUBRIC_GRADER_PROMPT_VERSION = "rubric-grader-v2"), rồi bắt buộc đi qua
validate_rubric_proposal (src/agents/diagnostic/guardrails.py). Trình tự là hybrid
envelope, không thương lượng:
baseline tất định (exact match → rubric 1.0/0.0)
→ đề xuất của model, schema-constrained
→ validator: nhận hoặc TỪ CHỐI (không bao giờ sửa lại)
→ bị từ chối → rơi về baseline nguyên khốiĐiểm cuối là weighted mean của rubric scores:
mastery, evidence_confidence baseline và diagnostic_status không bao giờ do
đường này ghi. Tắt ai_enrichment_enabled thì tập phát thu về MCQ — không hạ cấp
bài tự luận thành exact match, vì một điểm 0 do so khớp chuỗi trên bài tự luận là bằng
chứng âm bịa ra.
misconception_findings của AI còn qua validate_misconception_findings: id phải tồn
tại trong Misconception Library của đúng bank version đang chấm, và AI chỉ được gọi
tên ở chỗ baseline chưa có tên.
3. Cluster Budget — ngân sách một Cluster
Business baseline là 3 câu. Runtime hiện dùng sàn theo số core competency để tránh trường hợp chính sách confirmation yêu cầu phủ bốn competency nhưng chỉ cho hỏi ba câu:
Đây vẫn là OD-02 baseline, không phải ngưỡng tối ưu đã được chứng minh.
4. Session Budget — ngân sách toàn phiên
Baseline:
Phiên hết ngân sách nếu:
Hiện tại backend đếm session evidence theo student_id và course_id trong
đường gọi diagnostic. Vì vậy cần thận trọng khi diễn giải “toàn phiên” giữa nhiều
môn: đây là một chi tiết hiện trạng triển khai cần được kiểm chứng với OD-02.
5. Dynamic allocation — phân bổ động
Baseline sắp Cluster để cấp ngân sách:
Trong đó r là self_assessment_raw. Đây chỉ là heuristic — quy tắc kinh nghiệm.
6. Stopping rule — quy tắc dừng
Một Cluster được verified khi đồng thời:
- Có ít nhất một evidence.
- Mọi core competency có ít nhất một evidence đạt điểm
>= 0.6. - Không có evidence mang misconception mức
major.
Nếu chưa đạt:
| Tình huống | Trạng thái |
|---|---|
| Còn budget và còn câu | Hỏi tiếp |
| Hết Cluster Budget, đã có evidence | partial |
| Hết Session Budget hoặc không có evidence đáng tin | unverified |
Confirmation được kiểm tra trước kết luận hết budget, nên câu cuối cùng vẫn có
thể làm Cluster chuyển thành verified.
7. Asset gate — cổng tài sản
Gate mở theo từng item, không theo tên loại câu và cũng không theo tên version.
is_servable_item() (src/agents/diagnostic/selection.py) yêu cầu:
question_type ∈ SERVABLE_QUESTION_TYPES # {multiple_choice, high_information}
và nếu type đi đường rubric-AI (AI_RUBRIC_GRADABLE_TYPES = {high_information}):
get_settings().ai_rubric_open_for(type)
len(item.rubric) >= MIN_RUBRIC_CRITERIA_FOR_AI_RUBRIC # = 3| Loại | Trạng thái hôm nay | Đường chấm |
|---|---|---|
multiple_choice | Mở (Level 0 vĩnh viễn) | Exact match, không LLM |
high_information | Mở từ 2026-08-29 (ADR 15) | Rubric-AI + guardrail |
short_answer | Còn gate | Khi mở sẽ là tất định: khoá đáp án chuẩn hoá + accepted_aliases |
feynman | Còn gate | Chưa có asset đã duyệt |
short_answer là cloze một ô, nên nó thuộc nửa tất định của split gate — không phải
đường rubric-AI ≥3 tiêu chí. Đường đó chỉ áp cho high_information.
Vì ngưỡng tiêu chí đọc trên từng item, cùng một câu high_information có thể servable
trên v2 mà không servable trên v1: histogram số tiêu chí là v1 {1: 3, 2: 101, 3: 26}
và v2 {3: 130}, tức 104/130 item của v1 dưới ngưỡng còn 26 item của v1 đã đạt.
Golden label cho high_information vẫn là seed_placeholder, nên chưa có số đo False
Confirmation Rate cho đường rubric-AI; báo cáo eval giữ banner provisional (ADR 15).
8. Thuật ngữ
- Candidate set — tập ứng viên: các câu có thể được chọn tiếp.
- Coverage — độ bao phủ: competency nào đã được đo.
- Stopping rule — quy tắc dừng: điều kiện đủ để ngừng hỏi.
- Budget exhaustion — hết ngân sách: chạm giới hạn câu hoặc thời gian.
- Asset gate — cổng tài sản: chỉ mở năng lực khi có dữ liệu đã duyệt.
- Guardrail validator — bộ kiểm biên: thành phần duy nhất được ghi kết quả có AI chạm vào; nó từ chối, không sửa lại.
- Misconception — quan niệm sai: cách hiểu sai có hệ thống, không chỉ là một lần bấm nhầm.
9. Tham chiếu code
src/agents/diagnostic/selection.pysrc/agents/diagnostic/grading.pysrc/agents/diagnostic/guardrails.pysrc/agents/diagnostic/budget.pysrc/agents/diagnostic/mastery.pysrc/api/diagnostic_routes.py