Viết tài liệu yêu cầu (Documentation) hiệu quả: Cách viết User Story và Acceptance Criteria khiến cả Dev và Stakeholder đều hiểu
7/19/2026 · 10p đọc
title: "Viết tài liệu yêu cầu (Documentation) hiệu quả: Cách viết User Story và Acceptance Criteria khiến cả Dev và Stakeholder đều hiểu"
series: "BA 4.0: Từ Phân tích đến Giải pháp"
part: "Phần 3 — Kỹ năng "Cầu nối" (Bridge Skills)"
order: 8
audience: "Business Analyst (BA) mới vào nghề & đang phát triển"
reading_time: "12 phút"
tags:
- business-analyst
- user-story
- acceptance-criteria
- agile
- documentation
- reso-case-study
Viết tài liệu yêu cầu (Documentation) hiệu quả: Cách viết User Story và Acceptance Criteria khiến cả Dev và Stakeholder đều hiểu
Sprint planning của đội Reso tuần đó, Huy — Tech Lead — cầm tờ backlog lên hỏi Minh một câu tưởng đơn giản: "Cái story 'đặt phòng kèm đưa đón sân bay' này, ý là khách chọn xe lúc đặt phòng, hay là hệ thống tự động gợi ý sau khi khách đã confirm booking?"
Minh khựng lại. Trong đầu Minh, bức tranh rất rõ: khách đặt phòng xong, thấy ngay một bước hỏi "Anh/chị có cần xe đón sân bay không?", điền giờ bay, xong. Nhưng dòng chữ Minh viết trong backlog — "Cho phép khách đăng ký dịch vụ đưa đón sân bay khi đặt phòng" — hoàn toàn có thể hiểu theo cả hai cách Huy vừa hỏi. Đội dev đã tranh luận với nhau cả buổi sáng trước khi hỏi lại Minh.
Đây chính là khoảnh khắc phân định một BA giỏi và một BA "ghi chép": khi Huy hiểu sai ý, phản xạ tự nhiên là đổ lỗi "dev không đọc kỹ" hoặc "yêu cầu vốn dĩ mơ hồ, ai hiểu sao chẳng được". Nhưng Minh biết: sai ở đây thuộc về mình. Bài này nói về cách để lần sau không phải trả giá bằng nửa buổi sáng của cả team.
Sự thật cơ bản (First Principle)
Mục đích của phần mềm là giải quyết vấn đề cho con người.
Nghe hiển nhiên đến mức dễ bỏ qua, nhưng đây là gốc rễ của mọi tranh cãi về tài liệu yêu cầu. Nếu mục đích của phần mềm không phải là "có một app đẹp" hay "có một tài liệu đầy đủ", mà là giải quyết vấn đề cho con người cụ thể trong tình huống cụ thể, thì mọi dòng chữ Minh viết ra chỉ có giá trị khi nó truyền tải được: ai đang gặp vấn đề gì, và giải pháp này giúp họ như thế nào.
Một User Story không đạt được điều đó — dù format đẹp, dù đúng chuẩn Agile — vẫn là một tài liệu thất bại, bất kể Huy có đọc kỹ hay không.
Phân tích
Vấn đề của Minh không nằm ở chỗ thiếu chi tiết kỹ thuật. Nó nằm ở một ngộ nhận phổ biến: coi tài liệu là mục tiêu, trong khi thứ thực sự là mục tiêu là kết quả kinh doanh — khách đặt phòng tại Reso yên tâm rằng lúc xuống sân bay đã có xe chờ sẵn, không phải lo tìm taxi giữa đêm ở Đà Nẵng.
Nhớ lại bài 5 (Jobs-to-be-Done): công việc thật sự khách đang "thuê" Reso làm không phải là "đặt phòng", mà là "để tôi yên tâm rằng mọi thứ đã được lo, tôi không phải bận tâm gì thêm khi đi du lịch". Dịch vụ đưa đón sân bay chính là một mảnh ghép trực tiếp phục vụ JTBD đó. Nếu User Story không truyền tải được JTBD này, Huy — dù là một Tech Lead giỏi — sẽ chỉ implement đúng chữ, không đúng ý. Và bản thân "đúng chữ" của Minh, như đã thấy, lại mơ hồ đủ để hiểu theo hai hướng khác nhau.
Đây là lúc cần thẳng thắn với chính mình: nếu Dev hiểu lầm ý của BA khi đọc User Story, đó là lỗi của BA, không phải lỗi của Dev. Huy không có nghĩa vụ đọc được suy nghĩ của Minh. Huy chỉ có nghĩa vụ implement đúng những gì được viết ra một cách rõ ràng, đầy đủ ngữ cảnh, và có thể kiểm chứng. Trách nhiệm truyền tải đúng ý định kinh doanh — từ cái đầu của chị Lan Anh, qua Minh, đến tay Huy — thuộc về người đứng giữa. Đó là lý do BA tồn tại.
Nói cách khác: nếu bạn viết một User Story và để lại chỗ hở cho hai cách hiểu, bạn đã không làm xong việc của mình — dù đội dev có "hỏi lại kịp thời" hay không. May mắn là Minh phát hiện ra khoảng hở này trước khi code được viết sai hướng. Không phải lúc nào cũng may mắn như vậy.
Giải pháp
Công thức kinh điển cho User Story:
As a [user] — tôi là ai
I want [action] — tôi muốn làm gì
So that [value] — để đạt được giá trị gì
Ba dòng này nghe đơn giản, nhưng phần quan trọng nhất — phần hay bị BA mới bỏ qua — là So that. Nó chính là câu trả lời cho "vì sao", là cầu nối giữa hành động kỹ thuật và mục đích kinh doanh. Thiếu "So that" rõ ràng, Dev buộc phải tự đoán ý định, và tự đoán chính là nguồn gốc của mọi hiểu lầm.
Áp dụng lại cho tính năng đưa đón sân bay của Reso:
As a khách đã đặt phòng tại Serene Hotels,
I want đăng ký dịch vụ đưa đón sân bay ngay trong lúc đặt phòng,
So that tôi không phải lo tìm phương tiện di chuyển khi đến nơi.
Đã tốt hơn nhiều so với câu gốc Minh viết ban đầu — nhưng vẫn chưa đủ để tránh được câu hỏi của Huy. "Đăng ký ngay trong lúc đặt phòng" vẫn có thể là một bước riêng biệt sau khi xác nhận, hay một phần của cùng một luồng thanh toán. User Story chỉ nêu ý định; nó không, và không nên, tự gánh việc mô tả hành vi chi tiết. Việc đó thuộc về Acceptance Criteria (AC) — tiêu chí chấp nhận.
AC là nơi biến ý định mơ hồ thành hành vi có thể kiểm chứng được — cái mà Huy và đội dev có thể build đúng, và cái mà QA có thể test pass/fail rõ ràng, không cần đoán. Một bộ AC chuẩn mực cần:
- Cụ thể — mô tả đúng một hành vi, không lẫn nhiều ý.
- Kiểm tra được — có thể trả lời đạt/không đạt, không có tính từ mơ hồ ("nhanh", "thân thiện", "tiện lợi").
- Bao trùm cả trường hợp phụ (edge case) — không chỉ happy path.
- Độc lập với cách implement — mô tả cái gì xảy ra, không ép cách làm (trừ khi có ràng buộc kỹ thuật thật sự).
- Dùng ngôn ngữ Given – When – Then khi cần mô tả hành vi theo luồng, giúp cả BA, Dev, QA cùng đọc một kịch bản.
Áp dụng cho story đưa đón sân bay:
- AC1: Trong bước xác nhận đặt phòng (trước khi thanh toán), hệ thống hiển thị lựa chọn "Thêm dịch vụ đưa đón sân bay" như một hạng mục có thể tick chọn, kèm giá hiển thị rõ theo loại xe.
- AC2: Given khách đã tick chọn dịch vụ đưa đón sân bay, When khách tiếp tục sang bước điền thông tin, Then hệ thống bắt buộc nhập số hiệu chuyến bay và giờ hạ cánh dự kiến trước khi cho phép thanh toán.
- AC3: Given khách đã thanh toán thành công có kèm dịch vụ đưa đón sân bay, When đặt phòng được xác nhận, Then khách nhận được email/SMS xác nhận có đầy đủ: điểm đón, thời gian dự kiến tài xế có mặt, thông tin liên hệ tổng đài hỗ trợ.
- AC4: Given khách muốn huỷ riêng dịch vụ đưa đón sân bay (giữ nguyên phòng), When khách thao tác huỷ trong vòng 24 giờ trước giờ bay, Then hệ thống cho phép huỷ và hoàn tiền dịch vụ này theo chính sách, không ảnh hưởng đến đặt phòng.
- AC5: Given khách thay đổi giờ bay sau khi đã đăng ký, When khách cập nhật số hiệu chuyến bay/giờ hạ cánh mới trước 6 giờ so với giờ đón ban đầu, Then hệ thống cập nhật lịch đón mới và gửi thông báo xác nhận lại cho cả khách và bộ phận vận hành.
Với 5 tiêu chí này, câu hỏi ban đầu của Huy đã không còn chỗ để hiểu lầm: AC1 đã trả lời rõ ràng — chọn dịch vụ diễn ra ngay trong luồng đặt phòng, ở bước xác nhận, trước khi thanh toán, không phải một gợi ý sau đó.
📎 Actionable Template
Bảng dưới đây là khung "User Story Backlog" bạn có thể copy nguyên để quản lý backlog cho bất kỳ dự án nào — ví dụ điền sẵn theo case Reso:
| ID | User Story | Acceptance Criteria (tóm tắt) | Priority | Status |
|---|---|---|---|---|
| RESO-101 | As a khách muốn đi nghỉ tại Đà Nẵng/Hội An/Đà Lạt, I want đặt phòng trực tiếp trên Reso mà không qua OTA, So that tôi được giá tốt hơn và Serene Hotels chăm sóc tôi trực tiếp | 1) Hiển thị phòng trống theo ngày thực tế đồng bộ PMS; 2) Giá hiển thị thấp hơn hoặc bằng giá OTA cùng thời điểm; 3) Xác nhận đặt phòng tức thời qua email/SMS; 4) Đồng bộ trạng thái phòng về PMS trong vòng 1 phút | Must-have | Done |
| RESO-118 | As a khách đã đặt phòng tại Serene Hotels, I want đăng ký dịch vụ đưa đón sân bay ngay trong lúc đặt phòng, So that tôi không phải lo tìm phương tiện di chuyển khi đến nơi | (xem 5 AC chi tiết ở mục Giải pháp phía trên) | Must-have | In Progress |
| RESO-124 | As a khách đang xem lại đặt phòng của mình, I want nhận gợi ý dịch vụ spa phù hợp với ngày lưu trú, So that tôi có thể lên kế hoạch thư giãn mà không phải tự tìm hiểu | 1) Gợi ý hiển thị trong vòng 24h sau khi đặt phòng thành công; 2) Gợi ý ưu tiên slot còn trống trong thời gian khách lưu trú; 3) Khách đặt spa được xác nhận ngay, không cần gọi điện; 4) Không hiển thị gợi ý nếu khách đã từ chối trước đó trong cùng kỳ nghỉ | Should-have | Backlog |
| RESO-131 | As a chị Lan Anh (COO), I want xem báo cáo tỷ lệ đặt phòng trực tiếp so với qua OTA theo tháng, So that tôi có số liệu thuyết phục ban giám đốc về hiệu quả giảm phụ thuộc OTA | 1) Báo cáo tách riêng theo từng kênh (Reso trực tiếp / Booking.com / Agoda / Traveloka); 2) Cập nhật dữ liệu theo ngày, xem được theo khoảng thời gian tuỳ chọn; 3) Xuất được file Excel/PDF; 4) Có biểu đồ xu hướng 6 tháng gần nhất | Should-have | Backlog |
🧠 Tư duy phản biện: Khi Stakeholder nói "yêu cầu này rõ ràng rồi, không cần AC chi tiết đâu" — liệu họ đang tiết kiệm thời gian cho bạn, hay đang đẩy rủi ro hiểu lầm sang cho giai đoạn test, nơi chi phí sửa lỗi đắt hơn gấp nhiều lần?
🔗 Case Study & Bài viết liên quan
Đây là một chương trong hành trình xuyên suốt của dự án Reso — case study được theo dõi từ bài 1 đến bài 12 của series "BA 4.0: Từ Phân tích đến Giải pháp". Tính năng đưa đón sân bay ở bài này bắt nguồn trực tiếp từ JTBD đã phân tích ở Thấu hiểu người dùng với Jobs-to-be-Done, và các số liệu về tỷ lệ direct booking trong template ở trên liên hệ chặt với Phân tích dữ liệu để ra quyết định.
Kết
User Story không phải là văn bản để "có cho đủ thủ tục" trước khi vào sprint — nó là hợp đồng ý định giữa người hiểu nghiệp vụ và người xây giải pháp. Khi Huy hiểu đúng ngay từ lần đọc đầu tiên, đó không phải may mắn — đó là kết quả của việc Minh đã làm đúng vai trò cầu nối của mình. Nhưng viết đúng tài liệu chỉ là một nửa câu chuyện: nửa còn lại là cách Minh nói ra những điều này trước cả đội — với chị Lan Anh, với Huy, và đôi khi với cả những stakeholder không đồng tình với nhau. Bài tiếp theo sẽ đi vào phần đó.
Bài trước: Phân tích dữ liệu để ra quyết định · Bài tiếp theo: Kỹ năng giao tiếp & Thuyết phục