Mô hình dữ liệu và hợp đồng API
Phân cấp kiến thức, schema ownership, bảng dữ liệu và hợp đồng API giữa các Agent.
1. Knowledge hierarchy — phân cấp kiến thức
Course → Knowledge Cluster → Chapter → Topic → CLO → CompetencyCluster là lớp UX; Topic/CLO/Competency là độ phân giải cần giữ cho diagnostic và priority downstream.
2. Schema ownership — quyền sở hữu schema
| Nhóm dữ liệu | Chủ sở hữu | Mục đích |
|---|---|---|
| Knowledge Map | Role 1 | Cây môn học và competency |
| Question Bank + Coverage | Role 1 | Asset câu hỏi/rubric đã duyệt |
| Evidence + Knowledge State | Agent 2/Role 2 | Sự thật chẩn đoán |
| Importance Configuration | Role 1 | Tầm quan trọng có provenance |
| Priority Set + Capacity Context | Agent 3 | Rank và áp lực thời gian |
| Schedule | Planner | Ngày, slot và buổi học |
| Study Content | Study service | Học liệu hỗ trợ đã cache |
3. Database tables — các bảng hiện có
Bảy bảng, không hơn:
| Table | Nội dung |
|---|---|
users | Tài khoản và thông tin auth |
feedbacks | Phản hồi người dùng |
knowledge_states | Trạng thái chẩn đoán hiện tại theo Cluster |
diagnostic_evidence | Evidence từng câu trả lời (kèm misconception_id) |
study_contents | Nội dung Study Workspace đã cache |
triage_sessions | Phiên MVP legacy |
agent_decision_log | Phong bì audit của hybrid envelope (§6.1) |
agent_decision_log ghi một dòng cho mỗi quyết định có AI chạm vào: baseline tất
định, đề xuất thô của model, phần guardrail chấp nhận, phần bị từ chối, kết quả cuối,
cùng provenance (asset_versions, prompt_version, validator) và chi phí (latency,
token). trace_id là UNIQUE nên một quyết định chỉ được kể một câu chuyện; retry
đọc lại dòng cũ thay vì thêm dòng mới. ADR 12 chốt retention 30 ngày và redaction PII
bắt buộc ở write seam (src/services/decision_log_redaction.py).
Question Bank và Misconception Library là asset JSON versioned trong repository, không nằm trong bảng runtime.
4. API map
| Method | Endpoint | Chức năng |
|---|---|---|
| POST | /api/v1/auth/register | Đăng ký |
| POST | /api/v1/auth/login | Đăng nhập |
| GET | /api/v1/auth/me | Người dùng hiện tại |
| GET | /api/v1/courses/active | Danh sách môn đang phục vụ ở runtime |
| POST | /api/v1/diagnostic/reset-session | Xóa evidence để bắt đầu budget cycle mới |
| POST | /api/v1/diagnostic/cluster-assessment | Bắt đầu/tiếp tục một Cluster |
| POST | /api/v1/diagnostic/submit-answer | Chấm câu đang treo và tiến phiên |
| POST | /api/v1/priority/coordinate | Tạo Priority Set + Capacity Context |
| POST | /api/v1/plan/schedule | Agent 4 tất định: ngày, slot, deferral |
| GET | /api/v1/study/content | Lấy cache hoặc sinh Study Content |
| POST | /api/v1/study/generate | Buộc sinh lại Study Content |
| POST | /api/v1/feedback | Gửi feedback có JWT |
| GET | /health | Health check |
4.1 Admin pipeline — chỉ đọc, chỉ admin
Toàn bộ nhóm dưới nằm sau Depends(require_admin) và không có POST/PUT/PATCH/DELETE:
soi được pipeline soạn đề mà không sửa được asset đã publish.
| Method | Endpoint |
|---|---|
| GET | /api/v1/admin/pipeline/stages |
| GET | /api/v1/admin/pipeline/gates |
| GET | /api/v1/admin/pipeline/courses |
| GET | /api/v1/admin/pipeline/courses/{course_id}/versions/{version} |
| GET | /api/v1/admin/pipeline/courses/{course_id}/versions/{version}/items/{item_id} |
| GET | /api/v1/admin/pipeline/courses/{course_id}/artifacts |
/api/v1/triage/swipe, /api/v1/triage/session/{student_id} và
/api/v1/triage/explain là legacy compatibility API của MVP cũ — vẫn chạy, nhưng
không định nghĩa Agent 2/3/4 hiện hành.
5. Agent 2 input contract
{
"student_id": "student-001",
"course_id": "dsa",
"cluster_id": "dsa_graph",
"self_assessment_raw": 5,
"competency_count": 3,
"start_new_run": true
}self_confidence nếu client gửi sẽ bị server tính lại từ raw.
Resume semantics — ngữ nghĩa tiếp tục phiên
start_new_run=true: xóa evidence/Knowledge State cũ của đúng Cluster rồi phát câu đầu.start_new_run=false: tiếp tục phiên; server dựng lại pending question tất định.
6. Question output contract
{
"question_id": "dsa-q-001",
"cluster_id": "dsa_graph",
"competency_id": "dsa-graph-traversal",
"prompt": "...",
"question_type": "multiple_choice",
"difficulty": "hard",
"options": ["A", "B", "C", "D"],
"question_bank_version": "v2"
}Không có expected_answer hoặc rubric.
question_bank_version mặc định là DEFAULT_QUESTION_BANK_VERSION = "v2"
(src/api/diagnostic_routes.py). question_type chỉ nhận hai giá trị ở runtime hôm nay:
multiple_choice và high_information — và ngay trong hai loại đó, item vẫn phải qua
is_servable_item() mới được phát.
7. Answer submission contract
{
"student_id": "student-001",
"course_id": "dsa",
"cluster_id": "dsa_graph",
"question_id": "dsa-q-001",
"question_bank_version": "v2",
"answer": "B",
"elapsed_seconds": 42.5
}Server từ chối:
- không có diagnostic session;
- version không khớp;
- câu không phải pending question;
- câu đã được chấm;
- Cluster đã kết thúc.
8. Diagnostic turn response
{
"evidence": null,
"knowledge_state": {
"student_id": "student-001",
"course_id": "dsa",
"cluster_id": "dsa_graph",
"self_assessment_raw": 5,
"self_confidence": 1.0,
"diagnostic_status": "unverified",
"mastery": null,
"evidence_confidence": null,
"confidence_gap": null,
"evidence_ids": [],
"question_bank_version": "v2",
"pending_question_id": "dsa-q-001",
"generated_disclaimer": "..."
},
"budget": {
"question_budget": 12,
"time_budget_minutes": 20,
"questions_used": 0,
"minutes_used": 0,
"cluster_question_budget": 3
},
"next_question": {}
}9. Agent 3 request
Hai chế độ:
- Gửi
candidate_unitstrực tiếp. - Để danh sách rỗng và gửi
student_id/course_ids; backend dựng từ Knowledge State.
Các context quan trọng:
{
"student_id": "student-001",
"evaluated_at": "2026-08-23T00:00:00Z",
"course_ids": ["dsa", "database"],
"course_contexts": [
{
"course_id": "dsa",
"exam_date": "2026-08-30T02:00:00Z",
"available_study_minutes_per_day": 120
}
],
"available_study_minutes_per_day": 90,
"allow_default_importance_fallback": true,
"previous_priority_scores": {},
"re_evaluation_reason": "new_diagnostic_evidence"
}10. Agent 3 response groups
priority_items
ranked_learning_unit_ids
capacity_contexts
ranking_explanations
weights
urgency_scale_days
warnings
generated_disclaimerCapacity Context không được lặp vào từng Priority Item; schedule không được xuất hiện trong response Agent 3.
ranking_explanations và PriorityItem.reasons là giải thích tất định sinh từ
ReasonCode / RankingReasonCode (src/agents/priority/explanation.py). Narrative do
LLM viết sau này phải dùng tên field khác (item_narratives / ranking_narratives)
để không ai lẫn hai nguồn với nhau.
10a. Agent 4 contract — POST /api/v1/plan/schedule
Planner V1 không trạng thái: không chạm DB, không đọc đồng hồ server. Nó nhận Priority Set của Agent 3 và trả về đúng một lịch.
Request (PlanScheduleRequest, extra="forbid"):
{
"student_id": "student-001",
"plan_start_date": "2026-08-31",
"horizon_days": 14,
"daily_windows": [
{
"timeframe": "evening",
"capacity_minutes": 120,
"start_time": "19:00",
"end_time": "21:00",
"label": "Sau bữa tối"
}
],
"priority_items": [],
"course_deadlines": [{ "course_id": "dsa", "exam_date": "2026-09-10" }]
}Response (PlanScheduleResponse):
days[].windows[].sessions[] learn → practice → review, kèm priority_rank
deferred[] chỉ khi shortfall_minutes >= 1 thật, kèm reason_code
slack_by_course[] required/available/slack_minutes, is_imminent
total_planned_minutes bảo toàn phút: planned + deferred = required
total_deferred_minutes
planner_version "1.1.0-deterministic"
planner_baseline_version "2026-08-31"
pacing_mode "balanced" — HẰNG SỐ, không phải núm của request
generated_disclaimer
warnings[]
advisory LUÔN null: asset gate §5.6 còn ĐÓNG (ADR 11/16)Không field nào của Agent 3 bị tính lại ở đây: priority_score, urgency và mọi số
học capacity đi qua Planner không đổi.
11. Source-of-truth matrix
| Signal | Nguồn sự thật | Consumer |
|---|---|---|
| Self-confidence | Agent 2 từ raw | Agent 3 |
| Mastery/evidence confidence/status | Agent 2 | Agent 3, Planner/UI |
| Importance | Curriculum/Role 1 config | Agent 3 |
| Deadline | Course/upstream | Agent 3, Planner |
| Remaining work | Progress state | Agent 3 capacity, Planner |
| Priority score/rank | Agent 3 | Planner/UI |
| Capacity Context | Agent 3 | Planner/UI |
| Schedule | Agent 4 (POST /api/v1/plan/schedule) | UI/Study Workspace |
12. Contract vocabulary — từ vựng hợp đồng
- Request — yêu cầu: payload client gửi server.
- Response — phản hồi: payload server trả client.
- Contract — hợp đồng: hình dạng và semantics hai phía cam kết.
- Source of truth — nguồn sự thật: nơi duy nhất có quyền quyết định một signal.
- Persistence — lưu trữ bền vững: dữ liệu sống qua request/restart.
- Replay protection — chống nộp lại: ngăn cùng evidence được ghi hai lần.