№ 48
AirFuture là AI agent giám sát và dự báo chất lượng không khí đô thị theo thời gian thực: cảm biến báo, luật cứng chấm mức nguy hiểm, AI giải thích và đề xuất, con người bấm duyệt trước khi hành động.
AI agent giám sát và dự báo chất lượng không khí đô thị theo thời gian thực — cảm biến báo, luật cứng chấm mức nguy hiểm, AI giải thích và đề xuất, con người bấm duyệt trước khi hành động.
Đề tài SC-07 · VinUni AI20K Build Phase, Cohort 3 · Nhóm Anyways Phạm Đức Thiện (Nhóm trưởng — LSTM, Eval & CI/CD) · Nguyễn Minh Quang (Backend, API, Frontend) · Đoàn Văn Tuyền (Frontend, mô phỏng IoT) · Võ Quốc Huy (AI Agents, Guardrails, Zalo)
Số liệu môi trường trong các khu dân cư/toà nhà không hề thiếu — cảm biến IoT đo liên tục. Cái thiếu là khả năng đọc kịp và hiểu đúng số liệu đó, ở đúng ba nhóm người cần nó:
| Đối tượng | Vấn đề cụ thể |
|---|---|
| Ban Quản Lý (BQL) toà nhà | Nhân lực mỏng — một người trực, hàng chục cảm biến, nhiều màn hình rời rạc. Bất thường chỉ lộ ra khi đã bùng phát, cảnh báo tới trễ. |
| Cư dân | Chỉ số thô, phải tự đoán lấy ý nghĩa. "PM2.5 = 86" không nói cho một phụ huynh biết có nên cho trẻ ra ngoài hay không. |
| Ứng dụng chất lượng không khí hiện có | Dừng lại ở hiển thị tức thời — không dự báo trước xu hướng, không cá nhân hoá theo tình trạng sức khoẻ hộ gia đình, và không chạm được tới thiết bị vật lý (quạt thông gió...) để thực sự xử lý sự cố. |
Nói ngắn gọn: có dữ liệu, không có hành động. Khoảng trống nằm giữa "cảm biến đo được gì" và "con người nên làm gì tiếp theo".
AirFuture không để AI tự quyết định điều gì là nguy hiểm. Toàn hệ thống vận hành theo một vòng khép kín, một điểm chốt duy nhất là con người:
Cảm biến → Luật cứng đánh giá rủi ro → AI giải thích & đề xuất → Người phê duyệt → Thiết bị chạy → Cư dân được báo
Ba nguyên tắc bất biến chi phối toàn bộ kiến trúc:
LOW/MODERATE/HIGH/CRITICAL/SEVERE) do công thức Python (risk_engine) tính bằng cách so ngưỡng với cửa sổ trượt chuẩn (24h cho PM2.5/PM10, 8h cho CO/O3, 1h cho nhiệt độ/độ ẩm) — tái lập được, kiểm toán được, và vẫn chạy đúng ngay cả khi mất kết nối LLM. LLM chỉ giải thích nguyên nhân và dựa trên mức rủi ro đã tính sẵn, và mọi output của nó đều bị validate lại bằng schema Pydantic + kiểm tra tham chiếu thực tế trước khi ghi vào cơ sở dữ liệu.PENDING_APPROVAL. Chỉ vai trò Ban Quản Lý/Admin mới được duyệt hoặc từ chối — đây là ràng buộc Human-in-the-loop được cưỡng chế ở tầng backend và tầng Policy Gate, không phải chỉ hiển thị trên giao diện.Không phải một app cho tất cả — mỗi nhóm người dùng có một kênh riêng phù hợp với nhu cầu:
| Bề mặt | Đối tượng | Chức năng chính |
|---|---|---|
| Dashboard Next.js (15 trang) | Ban Quản Lý | Bản đồ nhiệt theo khu vực, chi tiết cảnh báo kèm phân tích AI, nút duyệt/từ chối lệnh điều khiển, báo cáo xuất PDF/CSV, quản trị master data |
| Chat Zalo 1-1 | Cư dân | Hỏi đáp tiếng Việt về AQI/thời tiết, khai báo độ nhạy cảm môi trường hộ gia đình, kết nối Google Calendar, bản tin chủ động mỗi sáng 6 giờ |
| Màn hình công cộng | Người qua đường | LED sảnh & TV thang máy hiển thị AQI/khuyến cáo, không cần đăng nhập, tự báo khi mất kết nối |
Cảm biến IoT / Node-RED ─┐
├─ MQTT (HiveMQ Cloud, TLS)
OpenWeather API ──────────┘
│
▼
FastAPI Backend
├─ MQTT Consumer (auto-provision zone/device, ghi sensor_reading)
├─ Assessment Worker — tính cửa sổ trượt + VN-AQI (QĐ 1459/QĐ-TCMT)
├─ Risk Engine — luật cứng, KHÔNG LLM
├─ Incident Agent (LangGraph, 13 node) — chỉ 3 node gọi LLM
├─ LSTM Predictor — dự báo PM2.5/PM10/CO2 1–6 giờ tới
├─ Guardrails 5 lớp + Policy Gate 8 chặng — kiểm soát mọi lệnh gọi công cụ AI
└─ REST/WebSocket API (92 endpoint)
│
▼
TimescaleDB (Postgres, 59 bảng) ── HuggingFace model registry (LSTM)
│
▼
Dashboard Next.js · Zalo bridge (Node.js, zca-js) · Màn hình công cộng
Vì sao LangGraph: máy trạng thái tường minh (state machine), không phải vòng lặp agent tự do — mỗi bước là một hàm Python thuần, kiểm soát và kiểm toán được từng node, dễ test độc lập.
Vì sao TimescaleDB: mở rộng từ Postgres, tối ưu sẵn cho dữ liệu chuỗi thời gian — đúng hình dạng của dữ liệu cảm biến đo liên tục.
Đây là bộ não xử lý sự cố, kích hoạt tự động mỗi khi có Alert mới:
initialize_run → validate_alert → load_context → check_data_quality → assess_risk (luật cứng). Rủi ro LOW dừng ở đây — chỉ lưu kết quả, không sinh cảnh báo/thông báo, không tốn chi phí gọi LLM.analyze_context (phân tích nguyên nhân + đánh giá sức khoẻ theo từng nhóm cư dân) → generate_actions (đề xuất hành động, có validate lại thiết bị/nhóm cư dân tồn tại thật) → compose_notifications (soạn nội dung thông báo).Ba lớp phòng thủ độc lập, xếp chồng — một lớp bị vượt qua thì lớp sau vẫn chặn:
| Chỉ số | Giá trị |
|---|---|
| Dòng code Python backend | 30.070 |
| Hàm test | 1.012 (trải trên 110 tệp) |
| Test coverage | 71% |
| Endpoint REST & WebSocket | 92 |
| Bảng TimescaleDB | 59 |
| Công cụ AI có kiểm soát quyền | 14 |
| Hạng mục | Kết quả |
|---|---|
| Chat — an toàn nội dung | 5/5 |
| Điểm liên quan câu trả lời | 4,85 / 5 |
| Bất biến duyệt công cụ phần cứng (Human-in-the-loop) | 1,00 (100%) |
| Hạng mục eval bắt buộc đạt | 100% (11/11) |
Ràng buộc hiệu năng: một lượt chat tối đa 45 giây, tối đa 8 lần gọi công cụ — có ngân sách cứng để tránh vòng lặp agent vô hạn.
ruff (lint) + pytest (test suite) + gate rủi ro + build Admin UI tự động qua GitHub Actions.main: tự động build Docker image và SSH deploy lên Oracle Cloud; frontend deploy qua Vercel.ADMIN; nghiệp vụ alert/duyệt lệnh yêu cầu BOARD_MEMBER/ADMIN.| Ưu tiên | Hạng mục |
|---|---|
| Cao | Hoàn thiện bước gửi lệnh MQTT thật xuống thiết bị thông gió sau khi BQL duyệt — hiện bước duyệt mới dừng ở ghi nhận trạng thái, chưa publish lệnh điều khiển thật ra broker. |
| Trung bình | Chuyển checkpointer của LangGraph từ lưu tạm sang PostgreSQL bền vững ngay từ đầu (rút kinh nghiệm từ giai đoạn build hiện tại, tránh phải nâng cấp giữa chừng). |
| Trung bình | Ổn định hoá phiên đăng nhập Zalo bridge — thư viện zca-js hiện chưa lưu session bền vững qua các lần khởi động lại container. |
| Thấp | Bổ sung Alembic migration thật thay cho create_all() + script vá tay, để có đường rollback an toàn khi lên production chính thức. |