Global Orchestrator
"Con học 3 school cùng lúc. Hôm nay ưu tiên cái nào?"
Thiết kế: SDD-007 §9 · Nguồn: SRC-032
1. Không có file nào tên orchestrator
grep -rniE "orchestrat" workers/api/src apps/*/src # → rỗngNhưng khác với Depth Engine — nơi thật sự chưa có gì. Ở đây, SDD-007 §9 đã tự quyết định điều đó:
Orchestrator = lớp umbrella chứa 3 decision engine — công thức
GlobalPrioritythuộc Recommendation Engine, kiểm capacity thuộc Constraint Engine, sinh/điều chỉnh plan thuộc Planning Engine.
Nghĩa là: Orchestrator là một cái tên cho ba engine phối hợp, không phải một thành phần thứ tư. Đi tìm orchestrator.ts là đi tìm nhầm thứ.
| Phần việc | Engine thật đang làm |
|---|---|
| Xếp hạng candidate | Recommendation Engine |
| Kiểm quỹ thời gian | Constraint Engine |
| Sinh & điều chỉnh kế hoạch | Planning Engine |
GlobalLearningPlan | chính là allocation của Learning Plan Model |
Ánh xạ này mang dấu ✍️ (AI tự quyết, chờ chủ dự án duyệt — Q-097).
2. Thiết kế: điều phối giữa các school
GlobalPriority = GoalValue × Urgency × ExpectedImpact × DependencyImportance × Confidence
÷ (TimeCost × CognitiveCost)
ràng buộc: TotalAllocatedTime ≤ LearnerCapacityVí dụ của SDD, và nó nói rõ vấn đề đang giải:
Fix Fractions 3h · SAT Mock 2h · IELTS Reading 3h · Shark Geometry → hoãnMột đứa trẻ học Turtle (nền tảng) + Ray (SAT) + Squid (IELTS) sẽ có ba nguồn sinh đề xuất, mỗi nguồn đều nghĩ việc của mình là quan trọng nhất. Không có lớp điều phối thì tổng thời gian đề xuất vượt xa quỹ thật, và đứa trẻ nhận về một danh sách không thể làm hết — rồi tự thấy mình kém.
School engine chỉ tạo candidate; quyết định cuối ở lớp điều phối.
3. Hiện trạng: mỗi lần chỉ điều phối trong một môn
Đây là khoảng cách thật giữa thiết kế và code:
| Thiết kế §9 | Hôm nay | |
|---|---|---|
| Phạm vi | Mọi school, mọi môn cùng lúc | Một môn một lần — buildCockpit(learnerId, subjectId) |
| Ràng buộc thời gian | TotalAllocatedTime ≤ LearnerCapacity | ❌ cockpit không kiểm capacity |
| Thứ nguyên xếp hạng | 5 nhân, 2 chia | weight × deficit (recommendation §2) |
CognitiveCost | có | ❌ chưa đo được |
Ba mảnh đã có và đang làm đúng phần việc của mình:
- Planning Engine đã điều phối theo thời gian: chia một buổi thành ôn / vá / theo mục tiêu, tổng đúng bằng
daily_minutes(learning-plan §4). Đây chính làGlobalLearningPlanở dạng một môn. - Constraint Model đã trả lời được
LearnerCapacitykèmsource(constraint-model). - Goal Model đã xếp hạng mục tiêu xuyên môn —
urgencytính chung, nên thi học kỳ Toán 5 ngày nữa thắng kỳ thi IELTS 6 tháng nữa (goal-model §3).
Thứ còn thiếu là mối nối: cockpit của môn Toán không biết cockpit của môn IELTS vừa đề xuất gì, và không ai cộng tổng thời gian lại.
Hệ quả thực tế hôm nay: learner mở môn Toán thấy 5 việc, mở IELTS thấy 5 việc nữa — 10 việc, không ai nói cái nào nhường cái nào.
4. Vì sao chưa gấp
Hai lý do, cả hai đều là hiện trạng dữ liệu chứ không phải né tránh:
- Phần lớn learner đang học một school. Bài toán đa-school là thật, nhưng chưa phổ biến ở quy mô hiện tại.
- Thiếu
TimeCostđáng tin. Ràng buộcTotalAllocatedTime ≤ LearnerCapacitycần biết mỗi việc tốn bao lâu. Hôm nay chỉ review candidate cóestimated_minutes(=question_count × 3); các loại action khác không có ước lượng nào. Cùng thứ đang chặn Depth Engine.
Không có TimeCost, "tổng ≤ capacity" là một bất đẳng thức không tính được.
5. Khi xây thì đặt ở đâu
Theo đúng ánh xạ §1 — không tạo engine thứ tư:
1. estimated_minutes cho MỌI loại action ← dữ liệu, chặn nặng nhất
2. buildCockpit nhận nhiều subject_id ← Recommendation Engine
3. GlobalPriority thay weight × deficit ← Recommendation Engine
4. cắt danh sách theo capacity từ Constraint ← Planning Engine
5. allocation xuyên môn trong Learning Plan ← Planning Engine (đã có khung)Bước 5 gần như đã sẵn: allocation hiện chia theo loại việc; chia thêm theo môn là mở rộng cùng một cấu trúc, không phải viết lại.
Và giữ nguyên luật đã có của Planning: "không viết allocation logic thứ hai" — mode blend 80/20 là default heuristic thuộc Planning Engine, precedence là Constraint/health context > mode blend > default deep.
6. Bất biến (cho lúc xây)
- Không tạo module
orchestratorriêng — ba engine đã có, orchestrator là tên gọi cho sự phối hợp. - School engine chỉ sinh candidate; quyết định cuối ở lớp điều phối.
- Không viết logic phân bổ thứ hai — mọi allocation đi qua Planning Engine.
TotalAllocatedTime ≤ LearnerCapacitylà ràng buộc cứng, không phải gợi ý.- Hoãn một việc phải nói ra (
defercó lý do), không im lặng bỏ khỏi danh sách.
Điều 5 quan trọng với đứa trẻ: "tuần này mình gác Hình học lại để tập trung thi học kỳ" là một quyết định em ấy hiểu và đồng ý được; còn việc Hình học biến mất không lời giải thích thì chỉ tạo cảm giác hệ thống thất thường.
Trace
- REQ-INT-09, REQ-LRN-06 (điều phối xuyên school) · REQ-INT-20 (Planning).
- Nguồn: SRC-032, SRC-105 · Q-097 (ánh xạ umbrella — ✍️ chờ duyệt).
- Thiết kế: SDD-007 §8/§9/§10, SDD-011 §6.
- Liên quan: Recommendation · Constraint · Learning Plan · Goal · Depth Engine.