NỎ THẦN AGENTIC
Ghi chú kỹ thuật

Tin tức & ghi chú kỹ thuật

Đây là những ghi chú ngắn giải thích vì sao chúng tôi chọn một cách làm cụ thể, viết từ chính đội ngũ đã đưa ra quyết định đó, dựa trên hệ thống SOAI đã nghiệm thu POC.

Vì sao chúng tôi chọn kiến trúc plugin cho tích hợp thiết bị

Camera IP không nói cùng một ngôn ngữ: ONVIF, VAPIX, ISAPI mỗi hãng một kiểu. Chúng tôi tách phần đọc hình ảnh khỏi phần phân tích, để thêm một hãng mới không đụng tới lõi hệ thống.

Khi bắt đầu tích hợp camera cho hệ thống giám sát SOAI, chúng tôi gặp ngay một sự thật khó chịu: mỗi hãng camera có một giao thức riêng. Camera IP theo chuẩn mở dùng ONVIF Profile S và RTSP. Axis dùng VAPIX song song với ONVIF. Hikvision dùng ISAPI và SDK riêng của họ. Không có một API duy nhất để "nói chuyện" với tất cả camera trên đời, và sẽ không bao giờ có.

Nếu viết logic đọc từng loại camera lẫn vào logic phân tích AI, mỗi lần thêm một hãng mới là một lần sửa lõi, và đó là rủi ro làm hỏng thứ đang chạy ổn định chỉ để thêm một thứ mới. Vì vậy chúng tôi dựng hai lớp trừu tượng tách biệt: `DeviceProvider` chịu trách nhiệm duy nhất là lấy được hình ảnh/video từ một thiết bị, bất kể giao thức gì bên dưới; `AnalysisEngine` chịu trách nhiệm duy nhất là phân tích một khung hình hoặc một video, không quan tâm hình đó lấy từ đâu.

Kết quả thực tế: thêm hỗ trợ một dòng camera mới nghĩa là viết một plugin `DeviceProvider` mới tuân theo interface đã định nghĩa, để yên engine phân tích và các module đã nghiệm thu (đếm SKU, phân tích video đóng gói, live view...). Tương tự, thêm một nghiệp vụ kiểm tra AI mới là viết một `AnalysisEngine` mới, để yên lớp đọc thiết bị.

Đây cũng là lý do chúng tôi có thể đàm phán hợp tác kỹ thuật với Axis và Hikvision mà không cần viết lại hệ thống. Dù mỗi hãng có SDK và tài liệu khác nhau, chúng tôi chỉ cần một plugin tuân theo cùng một hợp đồng interface.

Đọc tiếp

Đếm SKU trên ảnh mờ: vì sao chúng tôi dùng SAHI cùng YOLOv8

Một lần chạy suy luận nhìn cả bức ảnh thường bỏ lỡ những vật thể nhỏ, xếp dày và chen lấn nhau. Cắt ảnh thành từng lát trước khi đưa vào mô hình giải quyết đúng vấn đề đó.

Bài toán đếm SKU trên ảnh nghe đơn giản: đếm số hộp, số sản phẩm trong một khung hình. Nhưng nó khó ở chỗ các vật thể thường nhỏ so với toàn bức ảnh, xếp sát nhau, và đôi khi ảnh có phần mờ do góc chụp hoặc điều kiện ánh sáng thực tế tại nhà máy hoặc kho hàng.

Một mô hình object detection tiêu chuẩn như YOLOv8 chạy một lần suy luận trên toàn bức ảnh sẽ có xu hướng bỏ lỡ các vật thể nhỏ nằm dày đặc, vì mô hình phải "nhìn" cả bức ảnh lớn trong một lần và các vật thể nhỏ chiếm quá ít pixel để mô hình tự tin phát hiện.

SAHI (Slicing Aided Hyper Inference) giải quyết vấn đề này bằng một cách rất trực tiếp: cắt ảnh gốc thành nhiều lát nhỏ chồng lấn nhau, chạy suy luận YOLOv8 riêng trên từng lát, rồi ghép kết quả lại và loại bỏ các phát hiện trùng lặp ở vùng chồng lấn. Vì mỗi lát nhỏ hơn, vật thể nhỏ trong lát đó chiếm tỷ lệ pixel lớn hơn, nên mô hình phát hiện chính xác hơn.

Trong module đã nghiệm thu, cách kết hợp YOLOv8 và SAHI này cho ra kết quả đếm trong thời hạn SLA dưới 3 giây, kèm ảnh xuất ra có vẽ khung bounding box cho từng vật thể được đếm. Hệ thống cũng ghi lại phiên bản mô hình đã dùng cho lần đếm đó, để khi khách hàng hỏi "vì sao lần này đếm khác lần trước", chúng tôi có thể tra ngược lại chính xác phiên bản đã chạy.

Đọc tiếp

126 kịch bản test, không có ngoại lệ bị nuốt: cách chúng tôi kiểm thử hệ thống giám sát

Với một hệ thống giám sát, phần mềm chạy "có vẻ ổn" trên ảnh hỏng còn nguy hiểm hơn phần mềm báo lỗi rõ ràng. Vì vậy khoảng một phần năm bộ test của chúng tôi cố tình đưa dữ liệu xấu vào hệ thống.

Bộ test của hệ thống SOAI được chia thành ba lớp. Lớp thứ nhất là 10 test suite unit và integration ở backend, bao phủ models, các `AnalysisEngine`, các worker xử lý bất đồng bộ (Celery) và các API. Lớp thứ hai là 99 kịch bản end-to-end, đi qua toàn bộ luồng dữ liệu thật: Upload → Process → Storage → Query. Nghĩa là kiểm tra không chỉ một hàm chạy đúng, mà cả một chuỗi bước từ lúc người dùng tải video lên đến lúc họ tra được kết quả.

Lớp thứ ba là 27 bài test áp lực và đối kháng (stress & adversarial media test): đưa vào hệ thống video/ảnh mờ, file bị hỏng cấu trúc, mã QR không đọc được rõ, và kết nối mạng bị ngắt giữa lúc xử lý.

Vì sao lớp thứ ba này quan trọng hơn ở một hệ thống giám sát so với phần mềm thông thường: nếu một ứng dụng quản lý văn bản gặp file hỏng và báo lỗi, người dùng thử lại là xong. Nhưng nếu một hệ thống giám sát gặp video hỏng hoặc ảnh mờ và im lặng trả về "không phát hiện vi phạm", một kết quả trông hoàn toàn bình thường, thì đó là một lỗ hổng an toàn thực sự, vì không ai biết hệ thống đã thất bại.

Đọc tiếp

Vì sao chúng tôi không có đường fallback im lặng

Một exception bị nuốt âm thầm có thể biến một video hỏng thành một kết quả "không có vi phạm" trông hoàn toàn bình thường. Chúng tôi cho lỗi nổi lên thành exception rõ ràng, kèm log chi tiết.

Hãy tưởng tượng một tình huống cụ thể: một file video ghi lại quá trình đóng hàng bị hỏng một phần do lỗi ghi đĩa, và khi hệ thống cố trích xuất khung hình bằng FFmpeg, lệnh gọi thất bại. Có hai cách một hệ thống có thể xử lý việc này. Cách thứ nhất: bắt lỗi, trả về một kết quả mặc định rỗng, ví dụ "không tìm thấy mã QR" hoặc "không phát hiện vi phạm", và tiếp tục chạy. Cách thứ hai: để lỗi đó nổi lên thành một exception rõ ràng, kèm thông tin vì sao thất bại.

Chúng tôi chọn cách thứ hai. Toàn bộ hệ thống SOAI dùng một hệ thống ngoại lệ tuỳ biến gọi là `SOAIException`, phân theo loại lỗi cụ thể (lỗi cơ sở dữ liệu, file hỏng, lỗi xử lý media, lỗi kết nối thiết bị...). Mọi sự cố đều đi qua hệ thống này, được quăng lên thành một lỗi minh bạch kèm HTTP response tuân thủ chuẩn RFC, và được ghi log chi tiết.

Lý do điều này quan trọng với đúng bản chất của một hệ thống giám sát: giá trị của hệ thống nằm ở việc nó có thể trả lời chính xác "có" hoặc "không" cho một câu hỏi nghiệp vụ (có đủ hàng không, có vi phạm an toàn không). Một cách fallback im lặng, tức trả về mặc định khi gặp lỗi, sẽ biến một sự cố kỹ thuật thành một câu trả lời nghiệp vụ sai, và người xem báo cáo sẽ không có cách nào phân biệt được "không có vi phạm thật" với "hệ thống đã thất bại nhưng không ai biết".

Nói cách khác, một lỗi hiện rõ và được ghi log là một sự cố có thể sửa. Một lỗi bị nuốt âm thầm là một sự cố sẽ quay lại tìm chúng tôi, dưới dạng một khách hàng mất niềm tin vào dữ liệu mà hệ thống báo cáo.

Đọc tiếp
Hỗ trợ qua email và điện thoại, 9:00-17:00 thứ Hai đến thứ Sáu