Fidea AI Docs
Thuật toán

Ưu tiên và sức chứa thời gian

Công thức Priority Score, xếp hạng, workload, capacity và trạng thái quá tải.

Agent 3 tạo hai output độc lập:

  1. Priority Set — tập ưu tiên: nên học phần nào trước.
  2. Capacity Context — bối cảnh sức chứa: quỹ thời gian có chịu được khối lượng hay không.

Toàn bộ phần chấm điểm là Zero-LLM: priority_score, need, learning_importance, urgency, thứ hạng và mọi số học capacity đều tất định. Không LLM nào được đặt chúng — §10 nói về lớp narrative có AI và nó không chạm vào con số nào ở đây.

1. Priority score

V1 chỉ dùng ba tín hiệu:

P=WNN+WII+WUUP=W_NN+W_II+W_UU

Với baseline:

WN=0.33,WI=0.33,WU=0.34W_N=0.33,\qquad W_I=0.33,\qquad W_U=0.34

Do ba trọng số cộng bằng 1 và các tín hiệu nằm trong [0,1], P[0,1]P\in[0,1].

Không đưa vào công thức V1:

  • remaining work;
  • capacity;
  • confidence gap;
  • difficulty;
  • dependency hoặc prerequisite;
  • unlock value;
  • priority type.

2. Missing signal

P=nullifN=nullI=nullU=nullP=\text{null} \quad\text{if}\quad N=\text{null}\lor I=\text{null}\lor U=\text{null}

Khi đó ranking_status = incomplete. Đây là fail-closed behavior — thiếu dữ liệu thì không phát hành một thứ hạng giả.

3. Ranking — xếp hạng

Chỉ item complete được rank theo thứ tự:

priority_score DESC
→ urgency DESC
→ need_score DESC
→ learning_importance DESC
→ learning_unit_id ASC

Tie-breaker cuối bằng ID giúp kết quả tái lập được hoàn toàn.

4. Priority type

Các nhãn:

  • strategic_priority — ưu tiên chiến lược;
  • urgent_weakness — điểm yếu cấp bách;
  • general_priority — ưu tiên chung.

Chúng chỉ dùng giải thích, không cộng điểm và không đổi rank. Ngưỡng phân loại là baseline chưa freeze.

5. Item reasons — lý do của một item

Runtime có các reason code tất định:

CodeDịch nghĩa
HIGH_NEEDNhu cầu học cao
HIGH_LEARNING_IMPORTANCETầm quan trọng cao
HIGH_URGENCYĐộ cấp bách cao
APPROACHING_DEADLINEĐang gần deadline
UNVERIFIED_SELF_REPORTEDNhu cầu dựa trên tự khai báo chưa kiểm chứng

Ranking explanation so sánh từng cặp liền kề và cho biết item trên có score, urgency, need hoặc importance cao hơn; nếu tất cả bằng nhau thì ghi TIE_BROKEN_BY_ID.

6. Candidate workload — khối lượng ứng viên

Trong một deadline window ww:

Workw=iCandidate(w)remaining_work_minutesiWork_w=\sum_{i\in Candidate(w)}remaining\_work\_minutes_i

Agent 3 không tự chọn Top-K để làm giảm Work.

7. Available capacity — quỹ thời gian khả dụng

Nếu không có phân bổ sẵn:

Capacityw=Daysw×AvailableMinutesPerDaywCapacity_w=Days_w\times AvailableMinutesPerDay_w

Với các window chồng lấn của cùng một môn, coordinator cấp capacity cho deadline sớm trước; deadline sau chỉ nhận phần thời gian chưa được cấp. Cách này tránh đếm cùng một phút học hai lần.

8. Gap và ratio

Gapw=WorkwCapacitywGap_w=Work_w-Capacity_w
  • Gap dương: thiếu phút.
  • Gap bằng 0: vừa đủ.
  • Gap âm: dư phút.
Ratiow=Workwmax(Capacityw,1)Ratio_w=\frac{Work_w}{\max(Capacity_w,1)}

Mẫu số tối thiểu 1 tránh chia cho 0 nhưng không tạo thêm capacity thực.

9. Capacity status

Status={within_capacity,Ratio0.80at_risk,0.80<Ratio1.00over_capacity,Ratio>1.00Status= \begin{cases} within\_capacity, & Ratio\le0.80 \\ at\_risk, & 0.80<Ratio\le1.00 \\ over\_capacity, & Ratio>1.00 \end{cases}

Các ngưỡng là baseline. Status chỉ mô tả áp lực; Planner mới được split, defer, drop hoặc reallocate.

10. Ví dụ đầy đủ

Giả sử:

N=0.80,I=0.90,U=0.70N=0.80,\quad I=0.90,\quad U=0.70

P=0.33(0.80)+0.33(0.90)+0.34(0.70)=0.799P=0.33(0.80)+0.33(0.90)+0.34(0.70)=0.799

Nếu cần 300 phút nhưng còn 240 phút:

Gap=300240=60Gap=300-240=60

Ratio=300/240=1.25over_capacityRatio=300/240=1.25\Rightarrow over\_capacity

Priority vẫn là 0.799; capacity không hạ hoặc nâng điểm đó.

11. AI advisory — narrative, không phải điểm

Gate §5.5 đã MỞ (ADR 10), nhưng chỉ cho văn bản giải thích. Bốn nhóm field của PriorityAdvisory (src/agents/priority/advisory.py): item_narratives, ranking_narratives, tie_break_recommendations, capacity_tradeoffs. Tên field khác hẳn ranking_explanations / PriorityItem.reasons tất định ở §5, để mỗi khái niệm chỉ có một nơi sinh ra.

advisory_guardrails.py từ chối bất kỳ đề xuất nào muốn đổi score, rank, importance, urgency hoặc thành phần của tập item. Bị từ chối → advisory = null kèm advisory_rejection_reason, phần lõi tất định không đổi một byte.

Đường mặc định vẫn tất định: include_advisory mặc định False, vì advisory là một lượt gọi LLM cloud 10-20s và không được chắn trước Priority Set của người học. Client lấy narrative bằng lượt gọi thứ hai với include_advisory=Trueevaluated_at lấy đúng từ response lượt đầu — bỏ nó đi thì lượt hai tính urgency theo mốc thời gian khác và advisory sẽ mô tả một Priority Set khác với cái đang hiện trên màn hình.

Cờ này không phải kill switch: ai_enrichment_enabled = false vẫn thắng.

Mỗi lượt advisory ghi một phong bì §2.4 vào agent_decision_log (build_agent3_advisory_envelopeaudit_or_reject, src/services/decision_audit.py), và Decision #2 đã đóng theo ADR 12. Ghi audit thất bại thì bỏ lớp AI và trả baseline tất định kèm advisory_rejection_reason — không bao giờ phục vụ một câu trả lời AI không kiểm toán được, cũng không làm vỡ request của người học vì một sự cố bảng audit.

12. Thuật ngữ

  • Priority — mức ưu tiên: thứ tự nên xử lý.
  • Capacity — sức chứa thời gian: lượng thời gian có thể dùng.
  • Deadline window — cửa sổ thời hạn: khoảng từ mốc đánh giá tới deadline.
  • Tie-breaker — quy tắc phá hòa: quy tắc phụ khi điểm bằng nhau.
  • Deterministic — tất định: cùng input cho cùng output.
  • Auditable — có thể kiểm toán: truy lại được tín hiệu và công thức.

13. Tham chiếu code

  • src/agents/priority/priority_engine.py
  • src/agents/priority/capacity_engine.py
  • src/agents/priority/explanation.py
  • src/agents/priority/advisory.py
  • src/agents/priority/advisory_guardrails.py
  • src/services/decision_audit.py
  • src/services/priority_coordinator.py