Kiến trúc hệ thống
Cấu trúc runtime, trách nhiệm từng lớp, các đường request và ranh giới triển khai của Fidea AI.
Fidea AI dùng kiến trúc tách lớp: Next.js sở hữu trải nghiệm người dùng; FastAPI sở hữu contract, chẩn đoán, xếp ưu tiên, xếp lịch và Study API; PostgreSQL lưu trạng thái bền vững; pgvector phục vụ ingestion/RAG ngoài đường chấm bài.
Xếp lịch không còn ở browser. Từ ADR 9, allocator least-slack-first là hàm thuần
allocate_plan() (src/agents/planner/allocator.py) phơi qua POST /api/v1/plan/schedule;
frontend/src/lib/planner.ts chỉ còn dựng request và trình bày kết quả. Một Priority Set
vì thế chỉ cho ra một lịch, thay vì hai thuật toán song song ở hai phía.
Runtime topology — cấu trúc runtime
Layer responsibilities — trách nhiệm từng lớp
| Lớp | Sở hữu | Không được sở hữu |
|---|---|---|
| Browser UI | Điều hướng, nhập tự đánh giá, render câu hỏi/kết quả/lịch | Chấm điểm, mastery, priority score, xếp lịch |
| Frontend state | Draft UI, state theo user/guest, cache client | Nguồn sự thật của pending diagnostic question |
Frontend planner.ts | Dựng PlanScheduleRequest, đổi response thành view theo ngày | Thuật toán xếp lịch, tính lại Need/Importance/Urgency/priority |
| FastAPI Agent 2 | Routing, câu tiếp theo, chấm MCQ + rubric-AI, evidence, Knowledge State | Runtime RAG để chấm |
| FastAPI Agent 3 | Need, Importance, Urgency, Priority, Capacity Context | Slot, ngày, task allocation |
| FastAPI Agent 4 | Ngày, slot, duration, deferral có shortfall_minutes thật | Sửa priority, đổi capacity, override deadline |
| PostgreSQL | User, evidence, state, study content, decision audit, legacy session | LLM reasoning |
| pgvector | Vector chunks cho authoring/study RAG | Nguồn đáp án runtime của Agent 2 |
| Static Question Bank | Câu hỏi/rubric/version đã duyệt | Sinh động theo từng request |
Main request paths — các đường request chính
1. Diagnostic path
Server kiểm tra question hiện hành, version và duplicate evidence trước khi ghi. Chỉ item
đạt is_servable_item() được phát: đúng SERVABLE_QUESTION_TYPES
(multiple_choice, high_information), và với đường rubric-AI còn phải đủ
MIN_RUBRIC_CRITERIA_FOR_AI_RUBRIC tiêu chí — nên quyết định là theo từng item,
không theo tên version.
2. Priority path
3. Study Workspace path
Data planes — các vùng dữ liệu
Static assets
data/question_bank/*/{v1,v2}/{knowledge_map,question_bank}.json
data/misconception_library/{v1,v2}
Relational state
users, feedbacks, knowledge_states, diagnostic_evidence,
study_contents, triage_sessions, agent_decision_log
Vector state
langchain-postgres collection trong cùng PostgreSQL
Client state
Zustand + localStorage theo scope guest/userBảy bảng quan hệ ở trên là toàn bộ schema runtime. agent_decision_log là phong bì
audit của hybrid envelope (§6.1): mỗi dòng giữ baseline tất định, đề xuất thô của model,
phần guardrail chấp nhận, phần bị từ chối và kết quả cuối, kèm provenance
(asset_versions, prompt_version, validator) và chi phí. Bảng do
src/core/migrations.py (2026-08-25_agent_decision_log) tạo; ADR 12 chốt retention
30 ngày + redaction PII bắt buộc ở write seam.
Ranh giới offline / runtime là bất biến, không phải tối ưu hoá: pgvector và
scripts/ingest_curriculum.py chỉ phục vụ soạn Question Bank và Study Workspace.
Đường chấm bài không bao giờ truy hồi vector store (spec §18.2) — nó chỉ đọc asset JSON
tĩnh đã version hoá.
Security boundaries — ranh giới bảo mật
- Auth dùng JWT HS256 và mật khẩu băm bcrypt.
- Feedback yêu cầu JWT.
- Toàn bộ
/api/v1/admin/pipeline/*nằm sauDepends(require_admin)và chỉ cóGET— không endpoint nào của nó ghi được vào asset đã publish. - Một số diagnostic/priority/study endpoint nhận
student_idtrực tiếp để hỗ trợ guest. - Khi production nhiều người dùng, backend phải ràng buộc
student_idvới identity đã xác thực; UI không đủ quyền đảm bảo điều này. - API key và DSN chỉ đến từ biến môi trường/
.env, không ghi vào source hoặc log. - Question response không lộ
expected_answervà rubric.
Persistence & migrations — lưu trữ và nâng cấp schema
Startup chạy CREATE EXTENSION IF NOT EXISTS vector, SQLAlchemy create_all, rồi
runner tất định ở src/core/migrations.py theo thứ tự đã đăng ký:
2026-08-25_misconception_id (cộng cột misconception_id cho diagnostic_evidence)
và 2026-08-25_agent_decision_log (tạo bảng audit §6.1). Mỗi migration idempotent —
kiểm tra sự tồn tại trước khi chạy. Cách này phù hợp MVP nhưng chưa thay được Alembic
cho migration phức tạp, rollback hoặc dữ liệu production lâu dài.
Deployment shape — hình dạng triển khai
| Dịch vụ | Runtime |
|---|---|
| Frontend | Next.js/Vercel-compatible |
| Backend | FastAPI/Uvicorn, Docker/Render-compatible |
| Database | PostgreSQL 16 + pgvector |
| LLM/Embedding | NVIDIA NIM API (chọn model động qua NVIDIA_LLM_MODEL, ví dụ nemotron-3-nano-30b-a3b hoặc nemotron-3-super-120b-a12b), hai API key độc lập |
| Static assets | JSON trong repository |
Legacy boundary
src/api/routes.py và các node calibration_diagnostic, content_mapper,
cross_subject, triage_planner chứa MVP cũ. Chúng vẫn có endpoint/test tương
thích, nhưng không định nghĩa Agent 2/3 hiện hành.
Không dùng các trường legacy như blind_spot_score, performance_score,
calibration_gap, tps_score hoặc bypassed_gap cho feature mới.