
Cách mình viết skill cho AI - một lần, dùng mãi
Tháng 11 năm 2025, anh Vũ PO ping mình: "Em viết PRD cho multi-AZ control plane của VKS nhé, deadline thứ tư."...
Jul 2026
✍️ Hana · 🗓️ Tháng 7/2026 📚 Series: Bộ công cụ 🔢 Order: 4
Sơ đồ mô hình TDD - vòng lặp Red Green Refactor áp dụng cho luồng PO/BA, Test, Dev
Ảnh minh họa tham khảo từ bài 5 Steps of Test-Driven Development - IBM Developer.
Sáng thứ bảy này (04/07), mình hẹn cà phê với anh sếp cũ - Technical Architecture Manager, người dẫn dắt mình vào nghề BA. Giờ anh đang tự build AIDeal.vn. Câu đầu tiên anh hỏi không phải "dạo này sao rồi" mà là "em có muốn xem mô hình TDD anh đang áp dụng để build sản phẩm không?".
Mình gật đại, kiểu "TDD à, ok anh, em có tìm hiều nhưng chưa chạy thực tế nữa". Anh cười, kéo laptop ra cho mình xem repo AIDeal.vn. Anh bảo từ ngày dùng AI viết code, cái ảnh sợ nhất không phải AI viết sai, mà là AI viết đúng cái ảnh hỏi nhưng sai cái ảnh cần. Rồi ảnh nói một câu mình nhớ nguyên văn: "yên tâm hơn khi giao task cho AI" - từ ngày team ảnh chuyển qua làm theo TDD.
Ảnh giải thích luồng team ảnh chạy bây giờ: PO/BA viết đặc tả trước, QC viết test case từ đặc tả đó trước chạy test qua, rồi mới tới Dev (hoặc AI) viết code để test đó pass, xong Test chạy lại lần nữa để confirm. PO/BA → Test → Dev → Test. Không có bước nào code được viết ra trước khi có một bài test chờ sẵn để chấm điểm nó.
Anh mở luôn board Lark team ảnh đang quản lý task theo đúng luồng đó cho mình xem - mỗi task nằm đúng cột PO/BA, Test, Dev hay Test lại, không có task nào nhảy cột khi chưa xong bước trước:
Board Lark quản lý task theo mô hình TDD - luồng PO/BA, Test, Dev, Test tại AIDeal.vn
Mình từng nghĩ TDD là chuyện nội bộ của dev - kiểu convention viết code, BA không cần biết, biết cũng không dùng được gì. Ngồi nghe anh sếp cũ xong mới vỡ ra là mình hiểu sai hoàn toàn.
TDD viết tắt của Test-Driven Development, tức là viết test trước, viết code sau. Vòng lặp của nó có ba bước: Red - viết một test case cho hành vi chưa tồn tại, chạy thử, nó fail (đỏ). Green - viết code tối thiểu để test đó pass (xanh). Refactor - dọn code cho sạch mà không đổi hành vi, chạy lại test để chắc chắn vẫn xanh.
Cái mình bỏ sót suốt bao lâu nay: cái test ở bước Red kia lấy nội dung từ đâu ra? Từ Acceptance Criteria. Tức là nếu AC mình viết mơ hồ kiểu "hệ thống xử lý đúng trường hợp lỗi", thì Test không viết được test case nào rõ ràng, cả vòng lặp TDD đứng hình ngay từ bước đầu. TDD không sạch code hộ ai cả - nó chỉ lộ ra ngay chỗ AC nào của mình chưa đủ rõ để chạy được.
Anh vẽ lại cho mình xem quy trình bốn bước ảnh đang chạy, có AI ở giữa Dev:
Đây là US-06 trong backlog thật của AIDeal.vn - đúng cái format Gherkin vừa nói ở bước 1:
US-06: Loại bỏ hoàn toàn GraphQL khỏi Dashboard
As a Technical Lead
I want to loại bỏ hoàn toàn các thư viện, mã nguồn và file cấu hình liên quan đến GraphQL trong aideal-dashboard
So that ứng dụng giao tiếp 100% bằng RESTful API phù hợp với định hướng kiến trúc của backend, giảm kích thước bundle và tránh dư thừa công nghệ.
Scenario 1: Không còn dependency liên quan đến GraphQL
Given source code của aideal-dashboard
When kiểm tra file package.json
Then không tìm thấy các thư viện như @apollo/client, graphql, hoặc các thư viện liên quan đến GraphQL trong dependencies và devDependencies
Scenario 2: Không còn file .graphql trong mã nguồn
Given source code của aideal-dashboard
When tìm kiếm toàn bộ các file trong thư mục dự án
Then không có bất kỳ file nào có định dạng đuôi .graphql
Scenario 3: Không còn GraphQL Query/Mutation trong code
Given source code của aideal-dashboard
When tìm kiếm các từ khóa useQuery, useMutation, gql (của apollo)
Then không trả về bất kỳ kết quả nào đang sử dụng cho mục đích gọi API GraphQL
And tất cả các tính năng fetch data phải được thực hiện thông qua REST (ví dụ: axios, fetch)
Scenario 4: Ứng dụng hoạt động bình thường qua RESTful API
Given hệ thống đang chạy ở môi trường phát triển (localhost)
When thực hiện các thao tác lấy dữ liệu hoặc cập nhật dữ liệu trên Dashboard
Then request Network gửi đi phải là các REST API calls
And không có request nào gửi đến endpoint GraphQL (thường là /graphql)
And các tính năng hiển thị và hoạt động chính xác
Scenario 5: Thực hiện luồng Auth (Đăng nhập) qua REST API
Given người dùng ở trang đăng nhập
When nhập thông tin tài khoản hợp lệ
Then request gọi đến REST API /api/v1/auth/login thay vì GraphQL
And hệ thống đăng nhập thành công và lưu token
When người dùng nhập thông tin tài khoản không hợp lệ
Then request vẫn gọi đến REST API /api/v1/auth/login
And hệ thống hiển thị thông báo lỗi đúng từ REST response
Scenario 6: Kiểm tra API danh sách sản phẩm (Products)
Given người dùng đã đăng nhập thành công
When truy cập vào trang danh sách Sản phẩm (Products)
Then request network gửi đi để lấy danh sách phải là REST call (vd: /api/v1/products)
And dữ liệu sản phẩm hiển thị chính xác như phiên bản GraphQL trước đây
Nhìn kỹ sáu scenario này sẽ thấy điểm chung: không cái nào chấm được bằng cảm tính. "Không tìm thấy @apollo/client trong package.json" - grep ra là biết đúng sai. "Request gọi tới /api/v1/auth/login thay vì GraphQL" - mở tab Network là chấm được ngay. Đó chính là thứ khiến bước Red ở trên chạy được: Test viết một kịch bản kiểm tra cụ thể như vậy, bấm chạy, nó đỏ vì GraphQL còn nguyên - không ai phải tranh cãi "vậy coi như xong chưa".
Anh cho mình xem luôn report chạy test của US-06 này - từng scenario pass/fail rõ ràng, không phải nói miệng:
Report chạy test US-06 tại AIDeal.vn - danh sách scenario pass/fail sau khi build xong
Bấm vào xem chi tiết một scenario thì thấy rõ hơn nữa - từng bước Given/When/Then chấm riêng, sai ở đâu là biết ngay ở đó, không phải đoán:
Chi tiết kết quả test từng bước Given When Then của một scenario trong US-06
Trước đây, AC mơ hồ thì hậu quả tới chậm - qua vài ngày dev code xong, tới lúc Test hoặc sprint review mới lộ ra là hiểu sai. Có thời gian đệm để sửa.
Giờ AI viết code trong vài phút. AC mơ hồ đưa cho AI, AI cũng ra code trong vài phút - chỉ có điều là code sai, và sai nhanh hơn nhiều so với dev viết tay. Tốc độ AI khuếch đại luôn cả tốc độ lan sai lầm nếu đầu vào (AC) không đủ rõ.
TDD, xét theo góc BA, chính là cái phanh tự nhiên cho tốc độ đó. Vì Test bắt buộc phải viết được test case trước khi Dev/AI đụng vào code, một AC mơ hồ sẽ bị chặn lại ngay ở bước 2, trước khi kịp biến thành code sai ở bước 3. BA không còn là người viết tài liệu để người khác diễn giải - BA là người viết đặc tả phải đủ rõ để chạy thành một bài test thật.
Ngồi hết buổi cà phê đó, mình biết ơn thật sự - không phải vì học được thêm một khái niệm mới, mà vì gặp được một người vẫn chịu nghiên cứu thật, làm thật, đo bằng test case cụ thể chứ không chỉ nói AI hay, giữa lúc ai cũng có thể generate ra một mớ code trong vài giây. Cảm ơn anh "TAM" vì buổi sáng đó.
TDD không phải chuyện của dev - đó là lúc AC của BA phải đủ rõ để trở thành một con test chạy được.
Lần gần nhất AC bạn viết ra, có ai đó - người hoặc AI - viết được một test case từ nó mà không cần quay lại hỏi bạn thêm câu nào không?

Tháng 11 năm 2025, anh Vũ PO ping mình: "Em viết PRD cho multi-AZ control plane của VKS nhé, deadline thứ tư."...

Kể thật nhé. Trước khi có skill, mình viết một PRD đầy đủ mất từ 2 đến 4 ngày. Không phải vì không biết viết – mà vì có quá nhiều thứ phải làm đồng thời, v...
Một hôm mình mở tab Claude mới, paste lại đúng đoạn instruction từ tuần trước - "viết PRD theo chuẩn VNG Cloud, cần có 8 sections, user story dùng Gherkin,...