№ 06
Hệ thống quản lý và tối ưu trạm sạc xe điện trong khu dân cư có sự hỗ trợ của AI Agent cho cư dân và vận hành trạm. Đường dẫn cho vận hành trạm: https://dashboard-operator-lyart.vercel.app/
Bản tóm tắt dự án theo bốn phần: Bài toán · Giải pháp kỹ thuật · Tính khả thi · Hướng phát triển.
Số lượng xe điện trong các chung cư và khu đô thị tăng nhanh hơn nhiều so với tốc độ lắp thêm trụ sạc. Hệ quả là cùng một hạ tầng thiếu thốn tạo ra hai nhóm vấn đề khác nhau, ở hai phía người dùng khác nhau.
| Vấn đề | Biểu hiện thực tế |
|---|---|
| Tranh chỗ sạc | Về đến hầm thì trụ đã kín. Không có cơ chế giữ chỗ hay xếp hàng minh bạch. |
| Không ai cam kết gì | Cắm xe rồi đi ngủ, sáng dậy mới biết pin có kịp đầy hay không. |
| Bị cắt sạc bất ngờ | Khi lưới quá tải, xe bị giảm hoặc ngắt công suất mà không được báo trước. |
| Trả tiền giờ cao điểm | Xe đứng yên suốt đêm nhưng vẫn sạc đúng vào khung giá điện đắt nhất. |
| Rào cản thao tác | Ứng dụng đặt chỗ nhiều bước, người lớn tuổi ngại dùng. |
| Vấn đề | Biểu hiện thực tế |
|---|---|
| Nguy cơ quá tải | Nhiều xe cắm cùng lúc đẩy phụ tải vượt ngưỡng trạm biến áp nội khu, nhảy aptomat cả hầm. |
| Mù thông tin | Không có công cụ nào cho biết tổng công suất đang là bao nhiêu, ngay lúc này. |
| Xử lý tranh chấp thủ công | Mọi khiếu nại giải quyết bằng tay qua nhóm chat cư dân, không có bằng chứng. |
| Thiếu dữ liệu để đầu tư | Không biết nên lắp thêm bao nhiêu trụ, ở đâu, vào lúc nào. |
Đây không phải bài toán xếp lịch thông thường, vì ba ràng buộc kéo ngược chiều nhau:
Điểm khiến bài toán khắt khe hơn nữa: ràng buộc số 2 là ràng buộc an toàn vật lý. Vi phạm một lần là mất điện cả hầm xe. Nó không được phép sai kể cả trong trường hợp hiếm, và vì thế không thể giao cho một mô hình ngôn ngữ quyết định.
LLM cầm micro, không cầm cầu dao.
Hệ thống tách đôi trách nhiệm một cách dứt khoát:
ParsedChargingIntent: mức pin hiện tại, mức mong muốn, thời hạn). Nó không có quyền gọi bất kỳ lệnh điều khiển công suất nào.Nhờ vậy, an toàn điện của toà nhà không phụ thuộc vào việc mô hình hôm nay có ảo giác hay không.
Agent được dựng bằng LangGraph, mỗi bước là một node tường minh và có thể kiểm thử độc lập:
input_guardrail → classify_intent
├── out-of-scope ──────→ fallback_out_of_scope
├── hỏi đáp ───────────→ run_qna_tools_and_synthesize
└── yêu cầu sạc
↓
parse_intent_with_gpt ← LLM dừng ở đây
↓
validate_identity_and_ownership
↓
calculate_feasibility → ask_clarification / explain_alternatives
↓
await_confirmation ← cổng xác nhận 2 bước
↓
create_request → allocate_or_queue
↓
run_optimizer ← thuật toán tất định
↓
validate_schedule ← SafetyValidator
↓
create_approval (nếu bất lợi) ← chốt chặn HITL
↓
persist_and_dispatch → explain_result_with_gpt
Hai chốt chặn đáng chú ý:
await_confirmation — agent tóm tắt lại yêu cầu nó đã hiểu và dừng lại. Không có lịch nào được tạo cho tới khi cư dân xác nhận rõ ràng.explain_result_with_gpt — LLM chỉ quay lại ở bước cuối để diễn giải kết quả, sau khi mọi quyết định đã được chốt.SmartChargingOptimizer (src/optimizer/optimizer.py) — bộ phân bổ khung giờ tất định, ưu tiên theo thời hạn:
slot_minutes).Decimal, không dùng số thực dấu phẩy động — để kết quả tái lập được và kiểm toán được.Ngoài ra hệ thống tính thêm chỉ số bất mãn người dùng (dissatisfaction.py, theo mô hình Ko et al.). Đây là chỉ số báo cáo, tính sau khi kế hoạch đã hình thành — nó không tham gia vào việc chọn khung giờ, nên không làm mờ tính tất định của bộ tối ưu.
Đây là chi tiết kỹ thuật quan trọng nhất của dự án. SafetyValidator (src/optimizer/safety.py) chạy sau bộ tối ưu và:
tái suy diễn lại toàn bộ bất biến từ đầu ra thô, không tin vào sổ sách nội bộ của bộ tối ưu.
Nghĩa là nó cộng lại tổng công suất từng khung từ chính danh sách slot được sinh ra, so với trần và phụ tải nền, kiểm tra lại từng deadline, từng phép tính năng lượng. Nếu phát hiện vi phạm, nó ném SafetyViolationError và kế hoạch bị chặn — không được phát lệnh xuống trụ.
Cách làm này bảo vệ hệ thống ngay cả khi bộ tối ưu có lỗi logic: một bug trong optimizer không thể biến thành sự cố điện. Có test chuyên biệt bơm đầu ra giả mạo vào validator để chứng minh nó bắt được (test_catches_fabricated_output_that_exceeds_site_limit).
Mọi thay đổi bất lợi cho xe đang sạc (giảm công suất, lùi thời gian hoàn tất) không được áp dụng tự động:
ApprovalRequest.Cơ chế move-and-park (cư dân tự nguyện đăng ký khung giờ sẵn sàng nhường trụ) dùng lại đúng đường ống ApprovalRequest này — không tạo luồng phê duyệt song song.
| Lớp | Công nghệ | Ghi chú |
|---|---|---|
| Backend | FastAPI + SQLAlchemy 2.0 (async) | 143 module, 112 REST endpoint |
| Cơ sở dữ liệu | PostgreSQL 16 + asyncpg, Alembic | 16 migration |
| AI Agent | LangGraph + LangChain + OpenAI | Có guardrail đầu vào/đầu ra |
| Bộ tối ưu | Python thuần, Decimal | Không phụ thuộc LLM |
| Realtime | WebSocket | Đẩy sự kiện cho cả cư dân và vận hành |
| Trụ sạc | Lớp trừu tượng gateway | InProcessChargerGateway (mô phỏng) hoặc MqttChargerGateway (Mosquitto) |
| Frontend | React + TypeScript + Vite ×2 | PWA cư dân + dashboard vận hành, 189 file TS |
| Giọng nói | Service riêng | Chạy theo profile voice |
| Triển khai | Docker Compose, GitHub Actions | Deploy tự động lên VPS qua GHCR |
| Nỗi đau | Chức năng giải quyết |
|---|---|
| Rào cản thao tác | Chat tiếng Việt (kèm giọng nói), agent tự hỏi lại phần còn thiếu; gợi ý theo thói quen sạc của từng xe |
| Không ai cam kết gì | Ước tính trước khi đặt: chi phí, khung giờ được xếp, có kịp deadline không |
| Quá tải lưới | Trần công suất là ràng buộc cứng; giám sát quá tải chạy nền; tự tái tối ưu khi có xe mới / xe rút sớm / phụ tải nền tăng |
| Tiền điện giờ cao điểm | Dịch tải sang khung giờ rẻ mà vẫn giữ cam kết thời gian |
| Bị cắt sạc bất ngờ | HITL: đề xuất bất lợi phải được duyệt; thông báo realtime; nhật ký kiểm toán + AI log truy vết được |
| Mù thông tin | Dashboard realtime: toàn bộ trụ, hàng đợi, tổng công suất trên một màn hình |
| Thiếu dữ liệu đầu tư | Báo cáo sản lượng, giờ cao điểm, hiệu suất sử dụng từng trụ |
Toàn bộ hệ thống đã được xây dựng và vận hành end-to-end. Các con số dưới đây đo trực tiếp trên mã nguồn:
| Hạng mục | Số lượng |
|---|---|
| REST API endpoint | 112 |
| Test tự động | 643 |
| Dòng code backend Python | ~23.800 (143 module) |
| Migration cơ sở dữ liệu | 16 |
| File TypeScript frontend | 189 (2 giao diện) |
Đây là điểm mạnh nhất về mặt khả thi kỹ thuật. Các bất biến an toàn không được kiểm bằng vài test ví dụ, mà bằng property-based testing (Hypothesis) — công cụ tự sinh hàng nghìn kịch bản đầu vào ngẫu nhiên và tìm phản ví dụ:
test_property_output_never_exceeds_site_limit — đầu ra chưa bao giờ vượt trần công suất.test_catches_slot_scheduled_after_deadline — không khung nào bị xếp quá thời hạn.test_invariant_planned_energy_math_is_consistent — phép tính năng lượng nhất quán.test_catches_fabricated_output_that_exceeds_site_limit — validator bắt được cả đầu ra giả mạo.test_adverse_reoptimization_creates_approval_and_keeps_old_plan — HITL giữ đúng kế hoạch cũ trong lúc chờ duyệt.Trước khi bàn giao, từng mục dưới đây được chạy thực tế, không phải suy luận trên giấy:
alembic upgrade head → seed → khởi động, lặp lại nhiều lần từ trạng thái trắng.docker compose up --build: backend và frontend đều báo healthy, nginx proxy hoạt động.measured_power_kw cập nhật trong một chu kỳ (2–5s).Một yếu tố khả thi quan trọng cho triển khai thật: hệ thống không phụ thuộc sống còn vào OpenAI. Khi không có API key hoặc key lỗi, endpoint chat trả về 503 LLM_NOT_CONFIGURED một cách có kiểm soát, còn form đặt lịch thủ công vẫn tạo được yêu cầu với đầy đủ chức năng — vì bộ tối ưu và toàn bộ logic điện vốn không cần LLM. Điều này đã được kiểm chứng bằng cách chạy thật với OPENAI_API_KEY rỗng.
Hệ thống chạy được trọn vẹn trên một VPS phổ thông với Docker Compose. Không cần cụm máy chủ, không cần GPU, không cần broker MQTT ngoài (có sẵn gateway mô phỏng nội bộ; khi cần thì bật profile Mosquitto). Ban quản lý một toà nhà hoàn toàn có thể tự vận hành.
Để đánh giá khả thi cho đúng, cần nêu rõ những gì bản hiện tại chưa làm:
Đây đều là những khoảng cách đã được nhận diện và nằm trong lộ trình dưới đây.
| Hạng mục | Nội dung |
|---|---|
| OCPP 1.6 / 2.0.1 thật | Thay gateway mô phỏng bằng trụ sạc phần cứng thương mại. Lớp trừu tượng gateway đã có sẵn nên đây là thay thế implementation, không phải viết lại kiến trúc. |
| Dự báo bằng học máy | Thay heuristic thói quen bằng mô hình chuỗi thời gian thực thụ, dự đoán nhu cầu theo giờ/ngày. |
| Thanh toán thật | Cổng thanh toán và hoá đơn điện tử thay cho luồng mô phỏng hiện tại. |
| Ứng dụng di động | Bản native kèm thông báo đẩy, thay vì chỉ PWA. |
| Hạng mục | Nội dung |
|---|---|
| Đa trạm, đa toà nhà | Một ban quản lý điều phối nhiều khu, với trần tải phân cấp theo từng cấp lưới. |
| Mô hình ba pha | Cân bằng pha thay vì chỉ ràng buộc tổng công suất — sát thực tế lưới hạ thế hơn. |
| Tối ưu toàn cục | Chuyển từ heuristic sang quy hoạch tuyến tính (LP/MILP) có chứng minh tối ưu, giữ nguyên SafetyValidator làm lớp kiểm chứng. |
| Giá điện động | Bám biểu giá bậc thang và tín hiệu giá theo thời gian thực. |
| Hạng mục | Nội dung |
|---|---|
| V2G (Vehicle-to-Grid) | Xe trả điện ngược về toà nhà trong giờ cao điểm, cư dân được trả tiền. Bài toán tối ưu mở rộng từ một chiều thành hai chiều. |
| Ghép điện mặt trời & pin lưu trữ | Chuyển mục tiêu từ tránh quá tải sang tối ưu tự tiêu thụ năng lượng tái tạo tại chỗ. |
| Tham gia thị trường điều độ | Gộp công suất điều tiết của cả khu thành một nguồn linh hoạt, bán dịch vụ phụ trợ cho đơn vị vận hành lưới. |
| Agent đàm phán liên toà | Các khu dân cư tự trao đổi hạn mức công suất với nhau theo nhu cầu thực tế từng thời điểm. |
MVP đã giải quyết xong phần khó nhất và rủi ro nhất: điều phối công suất an toàn, có kiểm chứng, có con người trong vòng lặp. Các hạng mục phía trên hầu hết là mở rộng quy mô hoặc thay thế một thành phần đã được cô lập sau lớp trừu tượng — chứ không phải viết lại nền móng.
Riêng lớp SafetyValidator giữ nguyên giá trị qua mọi giai đoạn: dù bộ tối ưu có được thay bằng LP, MILP hay mô hình học tăng cường, lớp kiểm chứng độc lập vẫn đứng chắn giữa thuật toán và cầu dao.