lOMoARcPSD| 58833082
3. Triển khai (Implementation/Coding)
3.1. Viết mã nguồn
3.1.1. Tại sao cần thiết kế trước khi viết mã nguồn?
Việc thiết kế trước khi lập trình giúp:
Xác định rõ ràng yêu cầu hệ thống, tránh sai sót.
Đảm bảo mã nguồn có kiến trúc tốt, dễ mở rộng và bảo trì.
Hỗ trợ quá trình kiểm thử, giúp phát hiện lỗi sớm.
Giúp các thành viên trong nhóm hiểu rõ nhiệm vụ của mình.
Ví dụ thực tế với hệ thống gợi ý sản phẩm Trong dự án, trước khi lập trình, chúng ta đã có
một thiết kế rõ ràng, bao gồm: API Backend với Spring Boot (Java). Giao tiếp với AI Model
thông qua REST API. Database MongoDB để lưu lịch sử gợi ý.
3.1.2. Cách tiếp cận
Tạo các RESTful API sử dụng Spring Boot.
Tích hợp MongoDB để lưu dữ liệu lịch sử gợi ý.
Gọi API AI thông qua một service riêng biệt.
Gọi API AI thông qua một service riêng biệt thay vì gọi trực ếp từ client hoặc từ nhiều phn
khác nhau trong hệ thống có nhiều lợi ích, đặc biệt khi bạn triển khai trong một kiến trúc
EventDriven Architecture (EDA) hoc microservices. Dưới đây là mt số lý do chính:
1. Tách biệt trách nhiệm (Separation of Concerns)
Nếu gọi trực tiếp API AI từ nhiều phần khác nhau trong hệ thống, mã nguồn sẽ bị rải rác,
khó quản lý.
Một service riêng biệt giúp đóng gói toàn bộ logic xử lý liên quan đến AI (như tiền xử lý
dữ liệu, caching, logging, thống kê, bảo mật, v.v.).
2. Tăng hiệu suất và giảm chi phí API (Caching & Throttling)
API AI (như OpenAI, Google Gemini, Claude…) thường tốn phí và có giới hạn gọi API.
Một service trung gian có thể caching kết quả, giúp giảm số lần gọi API không cần thiết.
Có thể rate limiting để tránh vượt quá quota của API.
lOMoARcPSD| 58833082
3. Bảo mật & Quản lý API Key
Tránh để API Key xuất hiện trên client, giảm nguy cơ bị lộ hoặc lạm dụng.
Service trung gian có thể kiểm soát ai được phép gọi API AI, tránh bị spam hoặc tấn
công.
4. Dễ dàng thay đổi hoặc nâng cấp AI model
Nếu sau này muốn đổi từ OpenAI sang Claude hoặc Google Gemini, chỉ cần thay đổi
trong service mà không ảnh hưởng đến toàn bộ hệ thống.
Có thể tạo abstraction layer để hỗ trợ nhiều mô hình AI cùng lúc.
3.1.3. Đạt các tiêu chuẩn nào thì có thể thực hiện viết mã nguồn?
Đảm bảo tính đúng đắn: API trả về dữ liệu chính xác theo đầu vào, không phát sinh lỗi
runtime.
Đảm bảo hiệu suất: API phản hồi nhanh, không làm chậm hệ thống.
Sử Dụng Caching Giảm Số Lần Gọi API
Thay vì nh toán lại mỗi lần request, ta có thể cache dữ liệu để trả về kết quả nhanh hơn.
🔥 Redis Cache – Lưu Kết Quả API
Lưu dữ liệu thường truy vấn nhiều (ví dụ: danh sách sản phẩm hot).
Lưu kết quả từ API AI (nếu câu hỏi đã từng được xử lý).
Xử Lý Bất Đồng Bộ – Không Chờ Đợi Quá Lâu
Thay vì chặn API chờ xử, ta có thể xử lý request bất đồng bộ, giúp API phản hồi nhanh hơn.
Bảo mật dữ liệu: Không để lộ thông tin khách hàng, sử dụng JWT Authentication cho API.
Spring Security
Framework bảo mật mạnh mẽ giúp xác thực và phân quyền trong Spring Boot.
lOMoARcPSD| 58833082
Hỗ trợ authentication (xác thực)authorization (phân quyền).
Dễ dàng tích hợp với JWT, OAuth2, LDAP, Database, API Key,...
JWT (JSON Web Token)
Token-based authentication – không cần lưu session trên server.
Token chứa thông tin user, quyền hạn (roles), thời gian hết hạn.
Dùng để xác thực API request mà không cần gửi lại username/password mỗi lần.
OAuth2 (Open Authorization 2.0)
Chuẩn mở cho xác thực và ủy quyền.
Cho phép ứng dụng xác thực thông qua Google, Facebook, GitHub,... mà không cần
lưu password.
Kết hợp với JWT để cấp quyền cho API nhanh chóng.
3.1.4. Các nguyên tắc
SOLID Principles: Ví dụ: S (Single Responsibility) - API chỉ xử lý yêu cầu gợi ý sản
phẩm, không kiêm nhiệm quá nhiều logic.
Clean Code: Đặt tên biến, method có ý nghĩa (getRecommendedProducts() thay vì
getData()),Viết code không lặp lại, giúp dễ bảo trì, ChViết Code Khi Cn, Code càng đơn giản
càng tốt, tránh code phức tạp không cần thiết.
Logging rõ ràng: Sử dụng @Slf4j để ghi log khi gọi API AI.
Nếu tiêu chuẩn được đảm bảo, Unit Test sẽ dễ dàng kiểm tra logic của hệ thống.
3.1.5. Công nghệ mã hóa và chuẩn mực mã hóa áp dụng cho phần mềm này
Công nghệ sử dụng: SpringBoot(Viết RESTful API,MongoDB(Lưu lịch sử gợi ý), Feign
Client / WebClient(Gọi API AI), Lombok(Giảm boilerplate code), MapStruct(Chuyển đổi
DTO).
Chuẩn mực mã hóa: RESTful API chuẩn (sử dụng GET, POST đúng quy tắc), Spring
Security để bảo mật API, Swagger để tài liệu hóa API.
Nếu tuân theo chuẩn RESTful, việc viết API Test sẽ dễ dàng hơn, Security Test cần được
thực hiện để đảm bảo API không bị lộ thông tin.
3.1.6. Công nghệ mã hóa và chuẩn mực mã hóa áp dụng cho phần mềm này
GitHub/GitLab/Bitbucket để quản lý mã nguồn
GitFlow để kiểm soát phiên bản
lOMoARcPSD| 58833082
Khi phát hiện ra lỗi, có thể dùng Git để có thể quay lại phiên bản cũ
3.2. Tích hợp liên tục (Continuous Integration - CI)
3.2.1. Thực hiện tích hợp mã nguồn thường xuyên
Mục đích:
Giúp phát hiện xung đột mã nguồn giữa các thành viên khi làm việc nhóm. Phát
hiện lỗi tích hợp sớm, giảm thời gian sửa lỗi sau này.
Cách thực hiện:
Quy trình commit thường xuyên: Mỗi thành viên push code lên Git ít nhất 1 lần/ngày.
Merge vào branch develop thường xuyên để tránh xung đột lớn.
Sử dụng Pull Request (PR) với Code Review trước khi merge code vào main. Chạy
test tự động sau mỗi lần merge để đảm bảo không làm hỏng hệ thống.
Liên hệ với dự án gợi ý sản phẩm:
Khi cập nhật API gọi AI model, cần kiểm tra xem có ảnh hưởng đến các API khác hay
không.
Khi thay đổi cách lưu lịch sử gợi ý vào database, cần kiểm tra có làm hỏng truy vấn
dữ liệu cũ không.
3.2.2. Sử dụng hệ thống CI để tự động hóa quá trình build, kiểm thử đơn vị, và
kiểm tra chất lượng
Công cụ CI/CD phổ biến:
GitHub Actions
GitLab CI/CD
Jenkins
CircleCI
Quy trình CI trong dự án:
Khi có commit mới vào Git, hệ thống CI sẽ tự động thực hiện:
1. Build ứng dụng: Kiểm tra xem mã nguồn có thể biên dịch không.
2. Chạy kiểm thử đơn vị (Unit Test): Kiểm tra từng chức năng nhỏ có hoạt động đúng
không.
3. Chạy kiểm thử tích hợp (Integration Test): Kiểm tra các API hoạt động đúng khi gọi
lẫn nhau.
4. Phân tích mã nguồn (Code Quality Check): Sử dụng SonarQube để kiểm tra lỗi code.
lOMoARcPSD| 58833082
Liên hệ với dự án gợi ý sản phẩm:
Kiểm thử API gợi ý sản phẩm có trả về kết quả đúng không?
Nếu thay đổi thuật toán gợi ý, CI cần kiểm tra có gợi ý sai sản phẩm không?
Nếu cập nhật database, kiểm tra có ảnh hưởng đến dữ liệu lịch sử không?
3.2.3. CI/CD trong dự án này nằm ở đâu?
CI (Continuous Integration - Tích hợp liên tục):
o Khi developer push code lên Git, CI sẽ tự động kiểm tra lỗi. o Nếu lỗi Unit Test hoặc
Integration Test → Cảnh báo ngay lập tức để sửa lỗi trước khi merge.
CD (Continuous Deployment - Triển khai liên tục): o Khi tất cả bài test đều đạt → h
thống tự động triển khai lên môi trường staging. o Sau khi kiểm tra trên staging → có thể triển
khai lên production một cách an toàn.
Ứng dụng CI/CD vào dự án gợi ý sản phẩm:
o CI giúp kiểm tra API AI Model: Đảm bảo API luôn trả về kết quả đúng. o CI giúp
kiểm tra database: Tránh lỗi khi thay đổi schema của MongoDB.
o CD giúp triển khai nhanh: Khi có cập nhật mới, có thể đẩy lên môi trường thực tế
ngay lập tức.
Kết luận
CI giúp phát hiện lỗi sớm, đảm bảo code luôn ổn định.
CD giúp triển khai nhanh chóng, không bị gián đoạn khi cập nhật hệ thống.
Dự án gợi ý sản phẩm cần CI/CD để đảm bảo hệ thống luôn hoạt động chính xác khi cập nhật
dữ liệu và thuật toán AI.
4. Kiểm thử (Testing)
4.1. Kiểm thử đơn vị (Unit Testing)
Unit Testing (Kiểm thử đơn vị) là một kỹ thuật kiểm thử phần mềm, trong đó từng đơn vị nhỏ
nhất của mã nguồn (thường là một hàm, phương thức hoặc lớp) được kiểm tra độc lập để đảm
bảo rằng nó hoạt động chính xác.
4.1.1. Mục đích
Kiểm tra xem mô hình AI trả về kết quả dự đoán có đúng với mong đợi không (dựa trên
dữ liệu mẫu).
Đánh giá logic tiền xử lý dữ liệu đầu vào của AI trước khi đưa vào mô hình.
Kiểm tra API có gửi đúng dữ liệu đầu vào cho mô hình không.
Kiểm tra API có nhận và xử lý đúng dữ liệu đầu ra từ mô hình không.
lOMoARcPSD| 58833082
Đảm bảo hệ thống không bị sai lệch khi thêm tính năng mới hoặc cập nhật thuật toán dự
đoán.
Giảm thiểu lỗi logic trong xử lý dữ liệu (ví dụ: lấy sản phẩm từ database, tính toán điểm
đánh giá…).
Khi có thay đổi trong mô hình AI hoặc thuật toán, Unit Test giúp nhanh chóng phát hiện
lỗi mà không cần kiểm tra toàn bộ hệ thống.
4.1.2. Đặc điểm
Độc lập: Mỗi test chỉ kiểm tra một thành phần cụ thể như hàm tiền xử lý dữ liệu, hàm dự
đoán AI.
Tự động hóa: Sử dụng các framework như JUnit (Java), xUnit (.NET).
Chạy nhanh: Giúp phát hiện lỗi trong quá trình phát triển mà không làm chậm quá trình
CI/CD.
Kiểm tra trên dữ liệu giả lập (Mock Data): Sử dụng Mockito (Java) hoặc Moq (.NET)
để tạo dữ liệu giả.
Hàm recommendProducts() sẽ gọi API của mô hình AI để lấy danh sách sản phẩm được gợi ý.
lOMoARcPSD| 58833082
4.2. Kiểm thử tích hợp (Integration Testing)
Kiểm thử tích hợp (Integration Testing) là quá trình kiểm thử sự tương tác giữa các thành phần
của hệ thống để đảm bảo chúng hoạt động cùng nhau một cách chính xác.
4.2.1. Khác với Unit Testing
Unit Testing chỉ kiểm tra từng đơn vị riêng lẻ (class, function).
lOMoARcPSD| 58833082
Mock API AI: Tránh gọi API thực, chỉ kiểm tra xem service có gọi đúng API không.
lOMoARcPSD| 58833082
Integration Testing kiểm tra sự phối hợp giữa các thành phần (services, database, API,
message queue...).
Gửi HTTP Request đến Controller để kiểm tra:
o Controller nhận request → Gọi service → Nhận phản hồi từ API AI → Trả kết
quả về frontend.
Kiểm tra database:
o Sau khi gọi API, kiểm tra xem lịch sử gợi ý có được lưu đúng không.
4.3. Kiểm thử hệ thống (System Testing)
Kiểm thử toàn bộ hệ thống hoặc phần chức năng được xây dựng để đảm bảo đáp ứng các yêu
cầu chức năng và phi chức năng.
lOMoARcPSD| 58833082
4.3.1. Khác với Integration Test
Integration Testing: Kiểm tra sự kết hợp giữa Service và Repository hoặc API kết nối
với nhau đúng không.
System Testing: Cho phép người dùng kiểm thử sản phẩm để xác nhận rằng nó đáp ứng
các tiêu chí chấp nhận và nhu cầu của họ.
4.3.2. Ví dụ về System Testing
Mở trang web.
Tìm kiếm sản phẩm.
Thêm sản phẩm vào giỏ hàng.
Thanh toán.
lOMoARcPSD| 58833082
Kiểm tra email xác nhận đơn hàng.
💡 Test này kiểm tra mọi thành phần cùng nhau: UI, API, database, thanh toán, email.
4.4. Kiểm thử mô hình (ML Testing)
So sánh hai mô hình:
LightGBM có ưu thế hơn một chút về Precision, điều này có thể quan trọng vì chúng
tôi muốn tối ưu việc gợi ý sản phẩm với độ chính xác cao hơn.
Random Forest có kết quả gần tương đương, điều này cho thấy dữ liệu đã được xử lý
khá tốt và cả hai mô hình đều hoạt động ổn định,nhưng mà nhóm sẽ ưu tiên cho
LightGBM hơn vì độ chính xác cao hơn
LightGBM bị bias mạnh vào một sản phẩm
LightGBM dự đoán "Dress Skirt T-shirt" với xác suất 95%, trong khi các sản phẩm
khác gần như 0%.
Điều này có thể là do:
o Dữ liệu bị mất cân bằng → Kiểm tra lại tập huấn luyện sau khi dùng SMOTE.
lOMoARcPSD| 58833082
Random Forest có kết quả rời rạc
Xác suất của Random Forest khá đồng đều (~0.12, 0.11, 0.09), cho thấy mô hình chưa
phân biệt rõ giữa các lựa chọn.
Sản phẩm gợi ý "Blouse T-shirt Socks Blouse Blouse Jeans Blouse Sweater" có th
do lỗi trong Label Encoding hoặc cách gộp dữ liệu.
Từ các điều trên, ta cần:
Kiểm tra lại phân phối dữ liệu sau khi dùng SMOTE.
Xử lý lại các nhãn sản phẩm bị lỗi trong Label Encoding
Xử lý lại các nhãn sản phẩm bị lỗi trong Label Encoding o Vấn đề: LightGBM bias mạnh vào mt
sản phẩm → Điều chỉnh tham số để giảm overng.
o Vấn đề: Random Forest có kết quả không rõ ràng, xác suất các nhãn gần nhau.

Preview text:

lOMoAR cPSD| 58833082
3. Triển khai (Implementation/Coding)
3.1. Viết mã nguồn
3.1.1. Tại sao cần thiết kế trước khi viết mã nguồn?
Việc thiết kế trước khi lập trình giúp: •
Xác định rõ ràng yêu cầu hệ thống, tránh sai sót. •
Đảm bảo mã nguồn có kiến trúc tốt, dễ mở rộng và bảo trì. •
Hỗ trợ quá trình kiểm thử, giúp phát hiện lỗi sớm. •
Giúp các thành viên trong nhóm hiểu rõ nhiệm vụ của mình.
Ví dụ thực tế với hệ thống gợi ý sản phẩm Trong dự án, trước khi lập trình, chúng ta đã có
một thiết kế rõ ràng, bao gồm: API Backend với Spring Boot (Java). Giao tiếp với AI Model
thông qua REST API. Database MongoDB để lưu lịch sử gợi ý.
3.1.2. Cách tiếp cận
Tạo các RESTful API sử dụng Spring Boot. •
Tích hợp MongoDB để lưu dữ liệu lịch sử gợi ý. •
Gọi API AI thông qua một service riêng biệt.
Gọi API AI thông qua một service riêng biệt thay vì gọi trực tiếp từ client hoặc từ nhiều phần
khác nhau trong hệ thống có nhiều lợi ích, đặc biệt khi bạn triển khai trong một kiến trúc
EventDriven Architecture (EDA) hoặc microservices. Dưới đây là một số lý do chính:
1. Tách biệt trách nhiệm (Separation of Concerns)
Nếu gọi trực tiếp API AI từ nhiều phần khác nhau trong hệ thống, mã nguồn sẽ bị rải rác, khó quản lý. •
Một service riêng biệt giúp đóng gói toàn bộ logic xử lý liên quan đến AI (như tiền xử lý
dữ liệu, caching, logging, thống kê, bảo mật, v.v.).
2. Tăng hiệu suất và giảm chi phí API (Caching & Throttling)
API AI (như OpenAI, Google Gemini, Claude…) thường tốn phí và có giới hạn gọi API. •
Một service trung gian có thể caching kết quả, giúp giảm số lần gọi API không cần thiết. •
Có thể rate limiting để tránh vượt quá quota của API. lOMoAR cPSD| 58833082
3. Bảo mật & Quản lý API Key
Tránh để API Key xuất hiện trên client, giảm nguy cơ bị lộ hoặc lạm dụng. •
Service trung gian có thể kiểm soát ai được phép gọi API AI, tránh bị spam hoặc tấn công.
4. Dễ dàng thay đổi hoặc nâng cấp AI model
Nếu sau này muốn đổi từ OpenAI sang Claude hoặc Google Gemini, chỉ cần thay đổi
trong service mà không ảnh hưởng đến toàn bộ hệ thống. •
Có thể tạo abstraction layer để hỗ trợ nhiều mô hình AI cùng lúc.
3.1.3. Đạt các tiêu chuẩn nào thì có thể thực hiện viết mã nguồn?
Đảm bảo tính đúng đắn: API trả về dữ liệu chính xác theo đầu vào, không phát sinh lỗi runtime. •
Đảm bảo hiệu suất: API phản hồi nhanh, không làm chậm hệ thống.
Sử Dụng Caching – Giảm Số Lần Gọi API
Thay vì tính toán lại mỗi lần request, ta có thể cache dữ liệu để trả về kết quả nhanh hơn.
🔥 Redis Cache – Lưu Kết Quả API
Lưu dữ liệu thường truy vấn nhiều (ví dụ: danh sách sản phẩm hot).
Lưu kết quả từ API AI (nếu câu hỏi đã từng được xử lý).
Xử Lý Bất Đồng Bộ – Không Chờ Đợi Quá Lâu
Thay vì chặn API chờ xử lý, ta có thể xử lý request bất đồng bộ, giúp API phản hồi nhanh hơn.
Bảo mật dữ liệu: Không để lộ thông tin khách hàng, sử dụng JWT Authentication cho API. Spring Security
Framework bảo mật mạnh mẽ giúp xác thực và phân quyền trong Spring Boot. lOMoAR cPSD| 58833082 •
Hỗ trợ authentication (xác thực)authorization (phân quyền). •
Dễ dàng tích hợp với JWT, OAuth2, LDAP, Database, API Key,...
JWT (JSON Web Token)
Token-based authentication – không cần lưu session trên server. •
Token chứa thông tin user, quyền hạn (roles), thời gian hết hạn. •
Dùng để xác thực API request mà không cần gửi lại username/password mỗi lần.
OAuth2 (Open Authorization 2.0)
Chuẩn mở cho xác thực và ủy quyền. •
Cho phép ứng dụng xác thực thông qua Google, Facebook, GitHub,... mà không cần lưu password. •
Kết hợp với JWT để cấp quyền cho API nhanh chóng.
3.1.4. Các nguyên tắc
SOLID Principles: Ví dụ: S (Single Responsibility) - API chỉ xử lý yêu cầu gợi ý sản
phẩm, không kiêm nhiệm quá nhiều logic. •
Clean Code: Đặt tên biến, method có ý nghĩa (getRecommendedProducts() thay vì
getData()),Viết code không lặp lại, giúp dễ bảo trì, Chỉ Viết Code Khi Cần, Code càng đơn giản
càng tốt
, tránh code phức tạp không cần thiết. •
Logging rõ ràng: Sử dụng @Slf4j để ghi log khi gọi API AI.
Nếu tiêu chuẩn được đảm bảo, Unit Test sẽ dễ dàng kiểm tra logic của hệ thống.
3.1.5. Công nghệ mã hóa và chuẩn mực mã hóa áp dụng cho phần mềm này
Công nghệ sử dụng: SpringBoot(Viết RESTful API,MongoDB(Lưu lịch sử gợi ý), Feign
Client / WebClient(Gọi API AI), Lombok(Giảm boilerplate code), MapStruct(Chuyển đổi DTO). •
Chuẩn mực mã hóa: RESTful API chuẩn (sử dụng GET, POST đúng quy tắc), Spring
Security để bảo mật API, Swagger để tài liệu hóa API. •
Nếu tuân theo chuẩn RESTful, việc viết API Test sẽ dễ dàng hơn, Security Test cần được
thực hiện để đảm bảo API không bị lộ thông tin.
3.1.6. Công nghệ mã hóa và chuẩn mực mã hóa áp dụng cho phần mềm này
GitHub/GitLab/Bitbucket để quản lý mã nguồn •
GitFlow để kiểm soát phiên bản lOMoAR cPSD| 58833082 •
Khi phát hiện ra lỗi, có thể dùng Git để có thể quay lại phiên bản cũ
3.2. Tích hợp liên tục (Continuous Integration - CI)
3.2.1. Thực hiện tích hợp mã nguồn thường xuyên Mục đích:
Giúp phát hiện xung đột mã nguồn giữa các thành viên khi làm việc nhóm.  Phát
hiện lỗi tích hợp sớm, giảm thời gian sửa lỗi sau này. Cách thực hiện:
Quy trình commit thường xuyên: Mỗi thành viên push code lên Git ít nhất 1 lần/ngày. •
Merge vào branch develop thường xuyên để tránh xung đột lớn. •
Sử dụng Pull Request (PR) với Code Review trước khi merge code vào main.  Chạy
test tự động
sau mỗi lần merge để đảm bảo không làm hỏng hệ thống.
Liên hệ với dự án gợi ý sản phẩm:
Khi cập nhật API gọi AI model, cần kiểm tra xem có ảnh hưởng đến các API khác hay không. •
Khi thay đổi cách lưu lịch sử gợi ý vào database, cần kiểm tra có làm hỏng truy vấn dữ liệu cũ không.
3.2.2. Sử dụng hệ thống CI để tự động hóa quá trình build, kiểm thử đơn vị, và
kiểm tra chất lượng mã
Công cụ CI/CD phổ biến:GitHub ActionsGitLab CI/CDJenkinsCircleCI
Quy trình CI trong dự án:
Khi có commit mới vào Git, hệ thống CI sẽ tự động thực hiện:
1. Build ứng dụng: Kiểm tra xem mã nguồn có thể biên dịch không.
2. Chạy kiểm thử đơn vị (Unit Test): Kiểm tra từng chức năng nhỏ có hoạt động đúng không.
3. Chạy kiểm thử tích hợp (Integration Test): Kiểm tra các API hoạt động đúng khi gọi lẫn nhau.
4. Phân tích mã nguồn (Code Quality Check): Sử dụng SonarQube để kiểm tra lỗi code. lOMoAR cPSD| 58833082
Liên hệ với dự án gợi ý sản phẩm:
Kiểm thử API gợi ý sản phẩm có trả về kết quả đúng không? •
Nếu thay đổi thuật toán gợi ý, CI cần kiểm tra có gợi ý sai sản phẩm không? •
Nếu cập nhật database, kiểm tra có ảnh hưởng đến dữ liệu lịch sử không?
3.2.3. CI/CD trong dự án này nằm ở đâu?
CI (Continuous Integration - Tích hợp liên tục):
o Khi developer push code lên Git, CI sẽ tự động kiểm tra lỗi. o Nếu lỗi Unit Test hoặc
Integration Test → Cảnh báo ngay lập tức để sửa lỗi trước khi merge. •
CD (Continuous Deployment - Triển khai liên tục): o Khi tất cả bài test đều đạt → hệ
thống tự động triển khai lên môi trường staging. o Sau khi kiểm tra trên staging → có thể triển
khai lên production một cách an toàn. •
Ứng dụng CI/CD vào dự án gợi ý sản phẩm:
o CI giúp kiểm tra API AI Model: Đảm bảo API luôn trả về kết quả đúng. o CI giúp
kiểm tra database: Tránh lỗi khi thay đổi schema của MongoDB.
o CD giúp triển khai nhanh: Khi có cập nhật mới, có thể đẩy lên môi trường thực tế ngay lập tức. Kết luận
CI giúp phát hiện lỗi sớm, đảm bảo code luôn ổn định. •
CD giúp triển khai nhanh chóng, không bị gián đoạn khi cập nhật hệ thống. •
Dự án gợi ý sản phẩm cần CI/CD để đảm bảo hệ thống luôn hoạt động chính xác khi cập nhật
dữ liệu và thuật toán AI.
4. Kiểm thử (Testing)
4.1. Kiểm thử đơn vị (Unit Testing)
Unit Testing (Kiểm thử đơn vị) là một kỹ thuật kiểm thử phần mềm, trong đó từng đơn vị nhỏ
nhất của mã nguồn (thường là một hàm, phương thức hoặc lớp) được kiểm tra độc lập để đảm
bảo rằng nó hoạt động chính xác. 4.1.1. Mục đích
Kiểm tra xem mô hình AI trả về kết quả dự đoán có đúng với mong đợi không (dựa trên dữ liệu mẫu). •
Đánh giá logic tiền xử lý dữ liệu đầu vào của AI trước khi đưa vào mô hình. •
Kiểm tra API có gửi đúng dữ liệu đầu vào cho mô hình không. •
Kiểm tra API có nhận và xử lý đúng dữ liệu đầu ra từ mô hình không. lOMoAR cPSD| 58833082 •
Đảm bảo hệ thống không bị sai lệch khi thêm tính năng mới hoặc cập nhật thuật toán dự đoán. •
Giảm thiểu lỗi logic trong xử lý dữ liệu (ví dụ: lấy sản phẩm từ database, tính toán điểm đánh giá…). •
Khi có thay đổi trong mô hình AI hoặc thuật toán, Unit Test giúp nhanh chóng phát hiện
lỗi mà không cần kiểm tra toàn bộ hệ thống. 4.1.2. Đặc điểm
Độc lập: Mỗi test chỉ kiểm tra một thành phần cụ thể như hàm tiền xử lý dữ liệu, hàm dự đoán AI. •
Tự động hóa: Sử dụng các framework như JUnit (Java), xUnit (.NET). •
Chạy nhanh: Giúp phát hiện lỗi trong quá trình phát triển mà không làm chậm quá trình CI/CD. •
Kiểm tra trên dữ liệu giả lập (Mock Data): Sử dụng Mockito (Java) hoặc Moq (.NET)
để tạo dữ liệu giả.
Hàm recommendProducts() sẽ gọi API của mô hình AI để lấy danh sách sản phẩm được gợi ý. lOMoAR cPSD| 58833082
4.2. Kiểm thử tích hợp (Integration Testing)
Kiểm thử tích hợp (Integration Testing) là quá trình kiểm thử sự tương tác giữa các thành phần
của hệ thống để đảm bảo chúng hoạt động cùng nhau một cách chính xác.
4.2.1. Khác với Unit Testing
Unit Testing chỉ kiểm tra từng đơn vị riêng lẻ (class, function). lOMoAR cPSD| 58833082
Mock API AI: Tránh gọi API thực, chỉ kiểm tra xem service có gọi đúng API không. lOMoAR cPSD| 58833082 •
Integration Testing kiểm tra sự phối hợp giữa các thành phần (services, database, API, message queue...).
Gửi HTTP Request đến Controller để kiểm tra:
o Controller nhận request → Gọi service → Nhận phản hồi từ API AI → Trả kết quả về frontend. Kiểm tra database:
o Sau khi gọi API, kiểm tra xem lịch sử gợi ý có được lưu đúng không.
4.3. Kiểm thử hệ thống (System Testing)
Kiểm thử toàn bộ hệ thống hoặc phần chức năng được xây dựng để đảm bảo đáp ứng các yêu
cầu chức năng và phi chức năng. lOMoAR cPSD| 58833082
4.3.1. Khác với Integration Test
Integration Testing: Kiểm tra sự kết hợp giữa Service và Repository hoặc API kết nối với nhau đúng không. •
System Testing: Cho phép người dùng kiểm thử sản phẩm để xác nhận rằng nó đáp ứng
các tiêu chí chấp nhận và nhu cầu của họ.
4.3.2. Ví dụ về System Testing • Mở trang web. • Tìm kiếm sản phẩm. •
Thêm sản phẩm vào giỏ hàng. • Thanh toán. lOMoAR cPSD| 58833082 •
Kiểm tra email xác nhận đơn hàng.
💡 Test này kiểm tra mọi thành phần cùng nhau: UI, API, database, thanh toán, email.
4.4. Kiểm thử mô hình (ML Testing)
So sánh hai mô hình:
LightGBM có ưu thế hơn một chút về Precision, điều này có thể quan trọng vì chúng
tôi muốn tối ưu việc gợi ý sản phẩm với độ chính xác cao hơn. •
Random Forest có kết quả gần tương đương, điều này cho thấy dữ liệu đã được xử lý
khá tốt và cả hai mô hình đều hoạt động ổn định,nhưng mà nhóm sẽ ưu tiên cho
LightGBM hơn vì độ chính xác cao hơn
LightGBM bị bias mạnh vào một sản phẩm
LightGBM dự đoán "Dress Skirt T-shirt" với xác suất 95%, trong khi các sản phẩm khác gần như 0%. •
Điều này có thể là do:
o Dữ liệu bị mất cân bằng → Kiểm tra lại tập huấn luyện sau khi dùng SMOTE. lOMoAR cPSD| 58833082
Random Forest có kết quả rời rạc
Xác suất của Random Forest khá đồng đều (~0.12, 0.11, 0.09), cho thấy mô hình chưa
phân biệt rõ giữa các lựa chọn. •
Sản phẩm gợi ý "Blouse T-shirt Socks Blouse Blouse Jeans Blouse Sweater" có thể
do lỗi trong Label Encoding hoặc cách gộp dữ liệu.
Từ các điều trên, ta cần: •
Kiểm tra lại phân phối dữ liệu sau khi dùng SMOTE. •
Xử lý lại các nhãn sản phẩm bị lỗi trong Label Encoding •
Xử lý lại các nhãn sản phẩm bị lỗi trong Label Encoding o Vấn đề: LightGBM bias mạnh vào một
sản phẩm → Điều chỉnh tham số để giảm overfitting.
o Vấn đề: Random Forest có kết quả không rõ ràng, xác suất các nhãn gần nhau.