Fidea AI Docs
Thuật toán

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:

  1. Lấy toàn bộ item của Cluster từ Question Bank đã publish.
  2. Bỏ item không đạt is_servable_item() — xem §7.
  3. Loại các question_id đã hỏi.
  4. Xác định core competency chưa có evidence.
  5. Sắp theo độ khó giảm dần.
  6. Trong cùng độ khó, ưu tiên câu phủ competency chưa có evidence.

Quy đổi độ khó:

easy=1,medium=2,hard=3\text{easy}=1,\quad \text{medium}=2,\quad \text{hard}=3

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:

is_correct=upper(trim(answer))=upper(trim(expected_answer))\text{is\_correct}= \operatorname{upper}(\operatorname{trim}(answer)) = \operatorname{upper}(\operatorname{trim}(expected\_answer)) score={1,correct0,incorrectscore= \begin{cases} 1, & \text{correct} \\ 0, & \text{incorrect} \end{cases}

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:

score=iwisiiwiscore=\frac{\sum_i w_i\,s_i}{\sum_i w_i}

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:

Bcluster=max(3,  Ncore_competency)B_{cluster}=\max(3,\;N_{core\_competency})

Đâ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:

Bquestion=12,Btime=20 minutesB_{question}=12,\qquad B_{time}=20\text{ minutes}

Phiên hết ngân sách nếu:

session_exhausted=(Qused12)(Tused20)\text{session\_exhausted} = (Q_{used}\ge 12)\lor(T_{used}\ge20)

Hiện tại backend đếm session evidence theo student_idcourse_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:

cluster_priority_for_budget=r×Ncompetency\text{cluster\_priority\_for\_budget} =r\times N_{competency}

Trong đó rself_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:

  1. Có ít nhất một evidence.
  2. Mọi core competency có ít nhất một evidence đạt điểm >= 0.6.
  3. Không có evidence mang misconception mức major.

Nếu chưa đạt:

Tình huốngTrạng thái
Còn budget và còn câuHỏi tiếp
Hết Cluster Budget, đã có evidencepartial
Hết Session Budget hoặc không có evidence đáng tinunverified

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ạiTrạng thái hôm nayĐường chấm
multiple_choiceMở (Level 0 vĩnh viễn)Exact match, không LLM
high_informationMở từ 2026-08-29 (ADR 15)Rubric-AI + guardrail
short_answerCòn gateKhi mở sẽ là tất định: khoá đáp án chuẩn hoá + accepted_aliases
feynmanCòn gateChưa có asset đã duyệt

short_answercloze 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}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.py
  • src/agents/diagnostic/grading.py
  • src/agents/diagnostic/guardrails.py
  • src/agents/diagnostic/budget.py
  • src/agents/diagnostic/mastery.py
  • src/api/diagnostic_routes.py