
Buổi 3 — Phát triển và đảm bảo chất lượng với AI
Buổi 3 — Phát triển và đảm bảo chất lượng với AI
Một câu trên slide 3 gánh cả ngày học:
AI chỉ mạnh khi Specification đủ tốt.
Buổi 1 và Buổi 2 là lập luận cho việc dựng ngữ cảnh. Buổi 3 là lúc bạn biết lập luận đó có đáng không. AI-Ready Specification Package gom được ở Buổi 2 thôi làm sản phẩm bàn giao, và trở thành đầu vào — đầu vào duy nhất — để viết code, viết test, và quyết định có phát hành hay không.
Về bài viết này
Đây là ghi chép của tôi từ Ngày 3 khoá AI-Driven Software Development Life-Cycle, giảng viên TS. Bùi Thị Mai Anh, Trường Công nghệ Thông tin và Truyền thông (SOICT), Đại học Bách Khoa Hà Nội, tháng 7/2026. Khung tư duy và thiết kế workshop là của cô; phần tóm tắt và câu chữ ở đây là của tôi. Các prompt trích bên dưới lấy nguyên từ workbook của khoá học — chúng là của cô, không phải của tôi.
Bài nối tiếp Buổi 1 và Buổi 2. Bài cũng có bản tiếng Anh.
Bài này nằm ở đâu
Hình dạng đáng chú ý: spec nằm ở giữa, không phải ở đầu. Mọi thứ của Buổi 2 tồn tại để tạo ra nó. Mọi thứ của Buổi 3 là tiêu nó. Và hai cái mốc kia là gate theo đúng nghĩa đen — mỗi cái kết thúc bằng một phán quyết của con người.
Phần 1 — Phát triển với AI
Từ specification context sang development context
Buổi 2 kết thúc với một tài liệu đóng gói. Buổi 3 không đưa nguyên tài liệu đó cho model rồi bảo làm cả feature. Nó lặp lại nước đi context engineering ở một tầng sâu hơn: với coding task đang làm, chỉ truy xuất đúng phần task đó cần.
Nguyên tắc được nêu thẳng:
AI không hiện thực toàn bộ feature trong một lần. Mỗi lần chỉ tập trung vào một coding task với đầy đủ ngữ cảnh cần thiết.
Đó là lý do bước đầu tiên của workshop là phân rã, không phải viết code.
Năm nước đi
| Bước | AI làm | Developer chịu trách nhiệm |
|---|---|---|
| Lập kế hoạch & phân rã | Chia feature thành các coding task độc lập, kèm dependency và độ phức tạp | Chọn task nào để làm, và cách chia có hợp lý không |
| Development context | Truy xuất story, rule, component, file và quy ước mà task này chạm tới | Xác nhận context và bắt các giả định AI tự bịa |
| Viết code | Sinh phần hiện thực, giải thích quyết định kỹ thuật | Tính đúng của business logic, chấp nhận hay từ chối code |
| Unit test | Viết test theo scenario, nêu rule mà mỗi test phủ, chỉ ra chỗ không phủ được | Test có thật sự kiểm chứng hành vi không |
| Code review | Báo cáo vấn đề theo mức độ, kèm tác động và đề xuất sửa | Chọn xử lý vấn đề nào — và bản code cuối cùng |
Hai ràng buộc trong bảng đó dễ bị lướt qua, mà lại chính là điểm của bài tập.
Unit test nhắm vào hành vi, không nhắm chi tiết cài đặt. Một test vỡ khi bạn đổi tên một private method thì chẳng kiểm chứng được gì về business rule cả.
Ở bước review, AI báo cáo chứ không sửa. Prompt review kết thúc bằng "không sửa mã nguồn cho đến khi Human xác nhận" — và chỉ sau khi nhóm chấp nhận từng issue cụ thể, model mới được yêu cầu xử lý đúng những issue đó.
Phần 2 — Đảm bảo chất lượng với AI
Nửa sau lặp lại đúng hình dạng đó một lần nữa, với QA là vai chính và vẫn nguyên tắc về ngữ cảnh:
Không đưa toàn bộ dự án vào AI, chỉ cung cấp đúng thông tin cần thiết cho nhiệm vụ.
Bốn bước: dựng QA context (phạm vi, rule cần xác minh, thành phần cần kiểm thử, integration point, rủi ro, và loại kiểm thử nào phù hợp); thiết kế và thực thi loại kiểm thử đã chọn — API, integration, end-to-end; phân tích kết quả thành defect kèm mức độ, rule bị ảnh hưởng, nguyên nhân khả dĩ và khuyến nghị regression; rồi đánh giá — quyết định mức độ sẵn sàng phát hành.
Chi tiết tôi thích: bước 3 cấm tường minh model kết luận bất cứ điều gì về release readiness. Phân tích và phán quyết bị tách ra có chủ đích, để bằng chứng được gom trước khi có kết luận, chứ không phải gom để phục vụ một kết luận đã có sẵn.
Phần 3 — Spec trở thành một file trong repo
Đây là chỗ tuyên bố khép lại Buổi 2 — spec không còn là tài liệu, nó là giao diện — được đem ra thử với một thứ cụ thể.
Đầu ra Buổi 2 xuất xưởng dưới dạng một file markdown tự chứa. Bạn thả nó vào repo tại doc/specs/waitlist-feature.md, và prompt chỉ còn là:
Đọc
doc/specs/waitlist-feature.mdvà implement theo mục 6.
Tám mục, mục nào cũng được viết để dùng chứ không phải để ngắm:
- Context & Scope — In/Out Scope, ràng buộc bắt buộc
- Frozen Business Rules — BR-01 → BR-08, kèm chi tiết kỹ thuật và lý do; AI Developer không được tự thay đổi
- User Stories & Acceptance Criteria — US-01 → US-07, Given–When–Then phủ happy path, alternative, exception, timeout và conflict
- Data Model — khối DDL SQL sẵn sàng đưa vào migration
- API Contract — method, path, role, request, response, error code, kèm ví dụ payload
- Component → File Mapping — mỗi component trỏ tới một file thật trong repo
- Non-Functional Requirements — NFR-01 → NFR-08, mỗi cái một ngưỡng đo được
- Open Questions — OQ-01 → OQ-06, cố ý nằm ngoài phạm vi implement
Cộng thêm một Handoff Checklist 12 tiêu chí xác nhận tài liệu đã AI-ready.
Hai thứ trong đó đáng chép về dùng luôn.
Mục 1 ghi lại các đính chính so với codebase thật. Spec nói thẳng rằng MedBook chưa có Notification Service và chưa có API đổi lịch — tức là thiết kế đã giả định những thành phần không tồn tại. Phần lớn tài liệu bàn giao thường lấp liếm chỗ này và để developer tự phát hiện.
Có một quy tắc ưu tiên tường minh. Khi Specification Package mâu thuẫn với bất cứ mô tả nào trước đó, Specification Package là bản có hiệu lực, vì nó ghi lại KẾT QUẢ đã chốt — trong đó không còn "Cần xác nhận" nào. Đúng một câu đó là thứ biến một đống tài liệu thành một giao diện.
Workshop: các bước thực hiện
Vẫn hệ thống của Buổi 2 — MedBook, và vẫn feature Dynamic Appointment Rescheduling & Waiting List Management. Cái đổi là giờ bạn có một spec đã đóng băng và được kỳ vọng cho ra code chạy được.
Activity 1 — Phát triển với AI (35 phút)
AI đóng vai AI-Assisted Developer: phân tích specification context, dựng development context, liên kết requirement với architecture và source code, đề xuất implementation strategy, sinh service, API, unit test và tài liệu kỹ thuật, giải thích code, đề xuất refactoring.
Developer chịu trách nhiệm: xác nhận development context, kiểm tra giả định của AI, quyết định implementation strategy, đánh giá business logic, review code AI sinh ra, chấp nhận hoặc từ chối đề xuất, và hoàn thiện package trước khi chuyển sang testing.
Bước 0 — Task Planning và Decomposition. AI đóng vai tech lead, chia feature thành các coding task triển khai độc lập được — mục tiêu, story và acceptance criteria liên quan, thành phần bị ảnh hưởng, dependency, mức ưu tiên, độ phức tạp — rồi đề xuất một task phù hợp với thời lượng workshop và giải thích lý do. Nó bị dặn tường minh là không sinh mã nguồn.
Prompt — Lập kế hoạch task
Bạn là một Technical Lead đang lập kế hoạch phát triển chức năng Dynamic Appointment
Rescheduling & Waiting List Management cho hệ thống MedBook.
Dựa trên:
- AI-Ready Specification Package
- Architecture Blueprint
Hãy phân rã feature thành các coding tasks có thể triển khai độc lập.
Không sinh mã nguồn.
Đối với mỗi task, hãy xác định:
- Mục tiêu của task
- User Story và Acceptance Criteria liên quan
- Thành phần chính bị ảnh hưởng (UI, API, Service, Database...)
- Các task phụ thuộc (nếu có)
- Mức độ ưu tiên
- Ước lượng độ phức tạp (Low / Medium / High)
Cuối cùng, đề xuất một coding task phù hợp nhất để thực hiện trong phạm vi
workshop và giải thích lý do lựa chọn.Bước 1 — Dựng Development Context. Với task đã chọn, chỉ truy xuất phần nó cần: story và acceptance criteria mà task thuộc về, business rule task phải hiện thực, module và UI component liên quan, service và API cần tái sử dụng hay thay đổi, entity và DTO bị ảnh hưởng, file hiện có cần xem, coding convention và ràng buộc kỹ thuật, dependency và rủi ro, cùng những gì còn thiếu cần con người xác nhận trước.
Phần human review của bước này là một checklist mười hai mục, và hai mục đáng giá nhất là: AI có đề xuất gì vượt ngoài phạm vi task không? và có assumption nào AI tự tạo mà chưa ai xác nhận không?
Prompt — Development Context
Bạn là một Senior Full-Stack Software Engineer chuẩn bị hiện thực hóa một coding
task của chức năng Dynamic Appointment Rescheduling & Waiting List Management
trên hệ thống MedBook.
Coding task
- Task ID: [Task ID]
- Task name: [Tên task]
- Task objective: [Mục tiêu của task]
- Related User Story: [User Story liên quan]
Dựa trên:
- AI-Ready Specification Package
- Architecture Blueprint
- Existing Source Code
- Existing APIs
- Existing Data Model
- Coding Standards
Hãy xây dựng Task Context cho coding task trên.
Không sinh mã nguồn và không lập kế hoạch coding ở bước này.
Chỉ truy xuất và trình bày những thông tin liên quan trực tiếp đến task:
- Requirement, User Story và Acceptance Criteria liên quan
- Business Rules cần hiện thực
- Module, màn hình hoặc UI component liên quan
- Service, API hoặc utility có thể tái sử dụng hoặc cần thay đổi
- Data entity, DTO và trạng thái dữ liệu liên quan
- Source code hoặc file hiện có cần xem xét
- Coding conventions và technical constraints
- Dependencies và technical risks
- Assumptions, thông tin còn thiếu hoặc câu hỏi cần Human xác nhận
Với mỗi nội dung, hãy chỉ rõ:
- Thông tin hoặc thành phần liên quan.
- Mối liên hệ với coding task.
- Cách dự kiến sử dụng, tái sử dụng hoặc thay đổi.
- Requirement, Business Rule hoặc Acceptance Criteria làm căn cứ.
Yêu cầu:
- Không đưa vào các thông tin không liên quan trực tiếp đến task.
- Không tự tạo thêm Business Rule, API contract hoặc giả định mới.
- Không đề xuất thay đổi ngoài phạm vi của coding task.
- Nội dung chưa có đủ căn cứ phải được đánh dấu Cần xác nhận.
- Nếu không tìm thấy thông tin cần thiết trong các tài liệu đầu vào, phải nêu rõ
thông tin còn thiếu thay vì tự suy luận.Bước 2 — AI-Assisted Coding. Trước khi sinh bất cứ thứ gì, model phải tóm tắt cái gì sẽ thay đổi hoặc tái sử dụng, business rule nào sẽ được hiện thực, và nó đang giả định gì. Rồi mới viết code, tóm tắt thay đổi, và liệt kê những gì chưa làm. Đầu ra là source code cộng coding-log.md.
Prompt — Viết code
Bạn là một Senior Full-Stack Software Engineer đang hiện thực hóa một coding task
của chức năng Dynamic Appointment Rescheduling & Waiting List Management trên hệ
thống MedBook.
Dựa trên:
- Development Context
- Existing Source Code
- Coding Standards
Hãy hiện thực coding task đã lựa chọn.
Trước khi sinh mã nguồn, hãy tóm tắt ngắn gọn:
- Những thành phần sẽ được thay đổi hoặc tái sử dụng.
- Những Business Rules sẽ được hiện thực.
- Những giả định hoặc thông tin cần Human xác nhận (nếu có).
Sau đó:
- Sinh mã nguồn cho coding task.
- Tóm tắt các thay đổi đã thực hiện.
- Liệt kê những nội dung chưa được hiện thực (nếu có).
Không mở rộng phạm vi ngoài Development Context.Bước 3 — AI-Assisted Unit Testing. Với mỗi test: scenario, business rule hoặc acceptance criteria đứng sau nó, hành vi mong đợi, và dependency nào cần mock. Rồi đến code test, tóm tắt phạm vi, và — phần hữu ích nhất — danh sách tường minh những gì nó không phủ được hoặc thấy khó kiểm thử.
Prompt — Unit Testing
Bạn là một Senior Software Engineer và Test Engineer.
Dựa trên:
- Development Context
- Source Code vừa được hiện thực
- Business Rules
- Acceptance Criteria
- Coding Standards
Hãy xây dựng Unit Tests cho coding task đã lựa chọn.
Đối với mỗi test, hãy chỉ rõ:
- Scenario được kiểm thử
- Business Rule hoặc Acceptance Criteria liên quan
- Expected behavior
- Dependency cần mock (nếu có)
Sau đó:
- Sinh Unit Test source code.
- Tóm tắt phạm vi kiểm thử.
- Chỉ ra những trường hợp chưa được bao phủ hoặc khó kiểm thử.
Không tạo Unit Tests ngoài phạm vi của coding task.Bước 4 — AI-Assisted Code Review. Xét trên functional correctness, tuân thủ business rule, tính nhất quán, maintainability, reliability, security và chất lượng test. Mỗi vấn đề có vị trí, mức độ (Critical / Major / Minor), tác động và đề xuất sửa.
Workbook nói thẳng rằng con người không bắt buộc phải chấp nhận gì cả: những đề xuất không phù hợp với yêu cầu, kiến trúc hay phạm vi task đều có thể điều chỉnh hoặc từ chối. Chỉ sau đó model mới được sửa các issue đã chấp nhận — rồi chạy lại test và xác nhận không phát sinh regression rõ ràng.
Prompt — Code Review
Bạn là một Senior Full-Stack Software Engineer đang review mã nguồn và Unit Tests
của một coding task thuộc chức năng Dynamic Appointment Rescheduling & Waiting
List Management trên hệ thống MedBook.
Dựa trên:
- Development Context
- Source Code
- Unit Tests
- Business Rules và Acceptance Criteria liên quan
- Coding Standards
Hãy review code và tập trung vào các vấn đề có ảnh hưởng đáng kể đến:
- Functional correctness
- Business Rule compliance
- Maintainability
- Reliability
- Security
- Unit Test quality
Với mỗi vấn đề, hãy trình bày:
- Vấn đề và vị trí liên quan
- Mức độ: Critical / Major / Minor
- Tác động
- Đề xuất cải thiện
Không sửa mã nguồn cho đến khi Human xác nhận.Bước 5 — Development Quality Gate. AI gom bằng chứng và chấm sáu tiêu chí đạt hay chưa đạt, rồi đề xuất PASS – Ready for QA hoặc FAIL – Not Ready for QA, kèm danh sách việc phải xong nếu FAIL. Nhóm mới là bên ra quyết định thật, và có quyền không đồng ý với model khi bằng chứng còn mỏng.
Prompt — Development Quality Gate
Bạn là Technical Lead của dự án MedBook.
Dựa trên:
- Task Plan
- Development Context
- Source Code và Coding Log
- Unit Tests và Unit Test Report
- Code Review Report
Hãy đánh giá mức độ sẵn sàng của coding task trước khi bàn giao sang Quality
Assurance.
Đối với từng tiêu chí sau, hãy đánh giá Đạt / Chưa đạt và nêu bằng chứng:
- Coding task được thực hiện đúng phạm vi.
- Business Rules và Acceptance Criteria liên quan đã được hiện thực.
- Unit Tests đã được thực thi và đạt yêu cầu.
- Code Review đã hoàn thành.
- Không còn Critical Issue chưa được xử lý.
- Các hạn chế, giả định và rủi ro còn lại đã được ghi nhận.
Cuối cùng, hãy:
- Tóm tắt những gì đã được hoàn thành.
- Chỉ ra các rủi ro hoặc vấn đề còn tồn tại.
- Đề xuất một trong hai kết quả:
- PASS - Ready for QA
- FAIL - Not Ready for QA
Nếu kết quả là FAIL, hãy chỉ ra những công việc cần hoàn thành trước khi bàn
giao.Activity sinh ra một bộ artifact có tên rõ ràng: task-plan.md, development-context.md, coding-log.md, unit-test-report.md, review-report.md, api-specification.md, development-handoff.md.
Activity 2 — QA và Release Readiness với AI
Đây là quyết định thiết kế làm workshop này chạy được: mỗi nhóm trở thành đội QA cho Development Package do một nhóm khác bàn giao. Việc bàn giao thôi mang tính giả định. Nếu package mỏng, bạn cảm nhận được ngay — và đó chính là bài học của Buổi 1 được truyền đạt bằng trải nghiệm thay vì bằng slide.
Bước 1 — Dựng QA Context. Phạm vi kiểm thử, thành phần cần kiểm thử, business rule và acceptance criteria cần xác minh, luồng nghiệp vụ và integration point quan trọng, vùng rủi ro cao, và chiến lược kiểm thử đề xuất. Chưa thiết kế test case; thông tin thiếu thì đánh dấu cần xác nhận chứ không giả định.
Prompt — QA Context
Bạn là một QA Lead chịu trách nhiệm chuẩn bị hoạt động kiểm thử cho một feature
trước khi bắt đầu Quality Assurance.
Dựa trên Business Context và Development Package, hãy xây dựng QA Context cho
feature.
Trong đó, hãy xác định:
- Phạm vi kiểm thử.
- Các thành phần cần kiểm thử.
- Business Rules và Acceptance Criteria cần xác minh.
- Các luồng nghiệp vụ và Integration Points quan trọng.
- Các rủi ro cần ưu tiên.
- Đề xuất loại kiểm thử phù hợp (API Testing, Integration Testing và/hoặc
End-to-End Testing).
Không thiết kế test cases ở bước này.
Nếu thiếu thông tin cần thiết, hãy đánh dấu Cần xác nhận thay vì tự đưa ra giả
định.Bước 2 — Test Design & Execution. Với mỗi scenario: mục tiêu, rule hoặc criteria đứng sau, test data và precondition, kết quả mong đợi. Sinh code test theo framework của dự án nếu phù hợp, rồi ghi nhận pass/fail và các hành vi bất thường.
Prompt — Thiết kế & thực thi test
Bạn là một Senior QA Engineer chịu trách nhiệm kiểm thử feature.
Dựa trên QA Context, hãy thiết kế và hỗ trợ thực hiện loại kiểm thử đã được lựa
chọn.
Đối với mỗi test scenario, hãy xác định:
- Mục tiêu kiểm thử.
- Business Rule hoặc Acceptance Criteria liên quan.
- Test data hoặc preconditions.
- Expected Result.
Nếu phù hợp, hãy sinh mã nguồn kiểm thử theo framework của dự án.
Sau khi thực thi (hoặc nhận kết quả thực thi từ Human), hãy:
- Tổng hợp kết quả.
- Chỉ ra các test pass hoặc fail.
- Ghi nhận các lỗi hoặc hành vi bất thường được phát hiện.
Không thiết kế các kịch bản ngoài phạm vi QA Context.Bước 3 — Test Analysis. Phân loại defect theo mức độ, xác định rule hoặc criteria bị vi phạm, đề xuất nguyên nhân khả dĩ, và khuyến nghị regression test cần chạy sau khi sửa. Và — có chủ đích — không đưa ra kết luận nào về release readiness ở bước này.
Prompt — Phân tích kết quả test
Bạn là một QA Lead chịu trách nhiệm phân tích kết quả kiểm thử của feature.
Dựa trên:
- Test Execution Report
- Business Context
- Development Package
Hãy phân tích kết quả kiểm thử.
Nếu phát hiện defects, hãy:
- Phân loại mức độ ảnh hưởng (Critical, High, Medium hoặc Low).
- Xác định Business Rule hoặc Acceptance Criteria bị ảnh hưởng.
- Đề xuất nguyên nhân có thể xảy ra.
- Đề xuất hướng xử lý và Regression Tests cần thực hiện sau khi sửa.
Nếu không phát hiện defects, hãy tóm tắt các bằng chứng cho thấy feature đã đáp
ứng phạm vi kiểm thử.
Không đưa ra kết luận Release Readiness ở bước này.Bước 4 — QA Assessment. Với mỗi rule và criteria đã kiểm thử: đã xác minh hay chưa, bằng chứng nào, rủi ro còn lại là gì. Rồi một trong ba phán quyết — Ready for next stage, Ready with known risks, hoặc Not ready — kèm căn cứ và việc cần làm tiếp.
Prompt — QA Assessment
Bạn là một QA Lead chịu trách nhiệm đánh giá kết quả Quality Assurance của feature.
Dựa trên:
- QA Context
- Test Execution Report
- Test Analysis Report
- Development Handoff
Hãy tổng hợp kết quả kiểm thử và đánh giá chất lượng của feature.
Đối với từng Business Rule hoặc Acceptance Criteria đã được kiểm thử, hãy chỉ rõ:
- Đã được xác minh hay chưa.
- Bằng chứng kiểm thử liên quan.
- Những rủi ro hoặc hạn chế còn tồn tại.
Cuối cùng, hãy đưa ra một trong các khuyến nghị sau:
- Ready for Next Stage
- Ready with Known Risks
- Not Ready
Giải thích rõ căn cứ cho khuyến nghị và các vấn đề cần được xử lý tiếp theo
(nếu có).Hai gate cùng một hình dạng, và nên gọi tên ra: artifact có tên đi vào, AI tổng hợp ở giữa, phán quyết của con người đi ra. Phần giữa là phần duy nhất AI làm chủ.
Tôi rút ra được gì
Spec là sản phẩm của hai ngày đầu, và là đầu vào của ngày thứ ba. Nếu nó mơ hồ, Buổi 3 không đổ vỡ ầm ĩ — nó cho ra code trông rất hợp lý nhưng dựa trên rule sai, và như thế còn tệ hơn.
Phân rã trước khi sinh code. "Implement cái feature này" là prompt cho ra một backlog review. Một task kèm đúng ngữ cảnh của nó mới là prompt cho ra code merge được.
Tách phân tích khỏi phán quyết. Cấm model kết luận "sẵn sàng phát hành" ngay trong lúc phân tích kết quả test giúp bằng chứng không bị gom để phục vụ một kết luận đã có trước.
Ghi lại những gì bạn không làm được. Gần như bước nào cũng đòi một danh sách những gì chưa hiện thực, chưa phủ, chưa kiểm thử. Chính danh sách đó biến gate kế tiếp thành một quyết định có căn cứ, thay vì một cái dấu đóng cho có.