Mở đầu — vì sao bài này quan trọng
Hãy tưởng tượng bạn là BA trên một dự án ngân hàng số. Bạn viết một dòng yêu cầu trong tài liệu: "Hệ thống phải xử lý giao dịch nhanh." Sáu tháng sau, đội phát triển giao một hệ thống xử lý giao dịch trong 8 giây. Bạn phản ứng: "8 giây mà gọi là nhanh à?" Lập trình viên đáp lại tỉnh bơ: "Tài liệu anh viết là nhanh, có nói con số nào đâu." Và họ đúng. Cái dòng yêu cầu vô hại đó vừa thổi bay ngân sách, đẩy lùi go-live, và làm sứt mẻ niềm tin giữa các bên.
Đây chính là lý do bài học hôm nay quan trọng đến vậy. Trong toàn bộ vòng đời của một yêu cầu — từ khai thác (elicitation), phân loại, ưu tiên, đến kiểm tra — thì việc viết requirement ra giấy thành một câu chữ chất lượng cao là khâu dễ bị xem nhẹ nhất nhưng lại gây thiệt hại nặng nề nhất khi làm sai. Các nghiên cứu kinh điển trong ngành (Standish Group, các báo cáo của IIBA) đều chỉ ra rằng phần lớn lỗi phần mềm tốn kém nhất không bắt nguồn từ code, mà từ những yêu cầu mơ hồ, mâu thuẫn, hoặc thiếu sót ngay từ khâu đặc tả.
Bài này không bàn về cách lấy yêu cầu (đó là việc của elicitation), cũng không bàn về cách sắp xếp ưu tiên hay cách kiểm chứng — những phần đó có bài riêng. Bài này tập trung vào một kỹ năng cốt lõi và rất cụ thể: làm thế nào để biến một mong muốn mơ hồ của stakeholder thành một câu requirement rõ ràng, đo lường được, và không thể hiểu sai. Đây là kỹ năng phân biệt một BA nghiệp dư với một BA chuyên nghiệp.
Khái niệm cốt lõi
Một requirement chất lượng cao trông như thế nào?
Có hai trường phái tiêu chuẩn lớn mà mọi BA cần nắm, và điều thú vị là chúng bổ sung cho nhau chứ không loại trừ.
IEEE 830 / ISO 29148 (gốc Waterfall) đưa ra các tính chất mà một câu requirement riêng lẻ phải đạt. Bạn hãy nhớ chúng như một danh sách kiểm tra:
- Correct (Đúng) — phản ánh đúng nhu cầu thật của stakeholder.
- Unambiguous (Đơn nghĩa) — chỉ có một cách hiểu duy nhất, không phụ thuộc người đọc.
- Complete (Đầy đủ) — không để hổng tình huống, đặc biệt là các luồng ngoại lệ và điều kiện biên.
- Consistent (Nhất quán) — không mâu thuẫn với requirement khác trong cùng tài liệu.
- Verifiable / Testable (Kiểm chứng được) — có thể viết được một test case để chứng minh nó đã thỏa hay chưa.
- Feasible (Khả thi) — làm được trong giới hạn kỹ thuật, ngân sách, thời gian.
- Necessary (Cần thiết) — phục vụ một nhu cầu kinh doanh thật, không phải "thêm cho oai".
- Traceable (Truy vết được) — gắn được với một mục tiêu kinh doanh ở trên và một thiết kế/test ở dưới.
Điểm giao nhau quan trọng giữa hai trường phái — và là phần cốt lõi của bài này — chính là hai chữ chung: Clear (rõ ràng) và Testable/Verifiable (kiểm chứng được). Dù bạn làm Waterfall hay Agile, một requirement viết tốt luôn phải vượt qua hai bài kiểm tra này.
Phép thử "đơn nghĩa": loại bỏ từ ngữ cao su
Kẻ thù số một của requirement chất lượng là từ ngữ cao su (weasel words) — những từ co giãn theo cách hiểu của mỗi người. Hãy ghi nhớ danh sách đen này và tự động "báo động đỏ" mỗi khi thấy chúng trong tài liệu của mình:
nhanh, dễ dùng, thân thiện, linh hoạt, hiệu quả, tối ưu, đầy đủ, phù hợp, hợp lý, kịp thời, ổn định, an toàn, real-time, người dùng cần, hệ thống nên, càng nhiều càng tốt.
Mỗi từ trên đều là một câu hỏi chưa được trả lời. "Nhanh" là bao nhiêu mili-giây? "An toàn" là tuân theo chuẩn nào? "Người dùng" là vai trò cụ thể nào? Công việc của BA khi đặc tả là chuyển mỗi tính từ mơ hồ thành một con số hoặc một tiêu chí đo được.
Phép thử "kiểm chứng được": viết được test case không?
Một mẹo cực mạnh: với mỗi câu requirement, hãy tự hỏi "Tôi có thể giao cho tester viết một test case PASS/FAIL cho câu này không?". Nếu câu trả lời là không, hoặc tester phải đoán ý, thì requirement chưa đạt. "Hệ thống phải thân thiện" — tester không thể test. "Người dùng mới hoàn tất đăng ký trong tối đa 3 bước, không cần hướng dẫn" — tester test được ngay.
Mẫu câu chuẩn để viết
Để cấu trúc câu chữ không bị lan man, ba mẫu (template) sau đủ dùng cho 90% trường hợp:
- Mẫu Waterfall / functional: "[Tác nhân] phải có khả năng [hành động] [đối tượng] [trong điều kiện/ràng buộc]."
- Mẫu User Story (Agile): "Là một [vai trò], tôi muốn [mục tiêu] để [lợi ích]", kèm Acceptance Criteria dạng Gherkin: Given… When… Then…
- Mẫu EARS (Easy Approach to Requirements Syntax) — rất hữu ích cho NFR và logic điều kiện:
Tình huống thực tế
Ví dụ 1 — Timo (ngân hàng số Việt Nam): từ "nhanh" thành con số
Một nhóm BA tại một ngân hàng số phong cách Timo nhận yêu cầu từ trưởng phòng vận hành: "Màn hình chuyển tiền phải tải nhanh, đừng để khách bỏ đi." Đây là một nhu cầu hợp lệ, nhưng chưa phải requirement dùng được.
BA ngồi lại đào sâu cùng phòng vận hành và phòng kỹ thuật, rồi viết lại thành:
> "WHEN khách hàng nhấn vào tab Chuyển tiền, hệ thống SHALL hiển thị màn hình nhập thông tin chuyển khoản trong tối đa 1,5 giây ở điều kiện mạng 4G (≥ 5 Mbps), đo ở phân vị P95 của tất cả phiên trong giờ cao điểm 11h–13h và 19h–21h."
Hãy để ý điều gì đã thay đổi: "nhanh" → 1,5 giây; mơ hồ về mạng → 4G ≥ 5 Mbps; "trung bình" ngầm định nguy hiểm → P95 (nghĩa là 95% người dùng phải đạt, không lấy con số trung bình che giấu nhóm bị chậm). Bài học: một NFR về hiệu năng chỉ có giá trị khi gắn với con số + điều kiện đo + phân vị thống kê. Nếu thiếu P95, đội dev hoàn toàn có thể "đạt" yêu cầu bằng cách lấy trung bình trong khi 20% khách hàng vẫn chờ 6 giây.
Ví dụ 2 — Shopee-style: requirement "đầy đủ" phải bao gồm luồng ngoại lệ
Một BA trên sàn thương mại điện tử kiểu Shopee viết requirement cho tính năng áp mã giảm giá: "Người dùng nhập mã giảm giá và hệ thống áp dụng giảm giá vào đơn hàng."
Nghe có vẻ ổn, nhưng nó không Complete. Khi review, BA trưởng đặt loạt câu hỏi: Mã hết hạn thì sao? Mã không đủ điều kiện đơn tối thiểu? Mã đã dùng hết lượt? Nhập hai mã cùng lúc? Mã đúng nhưng sàn đang bảo trì khuyến mãi? Câu requirement gốc không trả lời được câu nào.
Sau khi viết lại bằng acceptance criteria dạng Gherkin, requirement trở thành một tập tình huống rõ ràng:
> - Given giỏ hàng đạt giá trị tối thiểu của mã, When người dùng nhập mã còn hiệu lực và còn lượt, Then hệ thống trừ đúng số tiền giảm và hiển thị dòng "Đã áp dụng mã X: -Y đ". > - Given mã đã hết hạn, When người dùng nhập, Then hệ thống hiển thị "Mã đã hết hạn" và giữ nguyên tổng tiền. > - Given giỏ hàng chưa đạt giá trị tối thiểu, When người dùng nhập mã hợp lệ, Then hệ thống hiển thị "Đơn tối thiểu Z đ để dùng mã này" và không áp dụng giảm.
Bài học: "Đầy đủ" (Complete) không có nghĩa là viết dài, mà là liệt kê đủ các luồng — luồng chính, luồng thay thế, và luồng lỗi. Một mẹo thực chiến: với mỗi requirement luồng chính, hãy hỏi "còn trường hợp nào khác?" ít nhất 3 lần.
Ví dụ 3 — FE Credit / công ty tài chính tiêu dùng: requirement "nhất quán" và "truy vết được"
Trong một dự án cho công ty tài chính tiêu dùng phong cách FE Credit, hai BA làm hai phân hệ khác nhau. BA phân hệ duyệt vay viết: "Khoản vay tối thiểu là 10 triệu đồng." BA phân hệ marketing lại viết: "Khách hàng có thể vay từ 5 triệu đồng cho gói trả góp điện thoại." Hai câu này mâu thuẫn (Inconsistent) và lọt qua review vì nằm ở hai tài liệu riêng.
Hậu quả: trang landing quảng cáo "vay từ 5 triệu", nhưng hệ thống core từ chối mọi hồ sơ dưới 10 triệu. Khách hàng nộp hồ sơ rồi bị từ chối hàng loạt, đội chăm sóc khách hàng ngập trong khiếu nại.
Vấn đề được phát hiện nhờ một thứ rất đơn giản: mỗi requirement đáng lẽ phải có mã định danh (ID) và truy vết (traceability) về cùng một business rule gốc. Khi cả hai câu cùng trace về rule "BR-LOAN-MIN: hạn mức vay tối thiểu theo từng sản phẩm", người ta lập tức thấy rule này chưa được định nghĩa rõ theo sản phẩm, dẫn đến hai BA tự suy diễn khác nhau.
Bài học: tính nhất quán không tự nhiên mà có — nó đến từ việc đặt ID duy nhất cho mỗi requirement và truy vết về một nguồn business rule chung. Khi nhiều BA cùng làm, đây là tấm lưới an toàn quan trọng nhất.
Hướng dẫn từng bước
Đây là quy trình bạn có thể áp dụng ngay khi ngồi xuống viết một requirement:
Bước 1 — Xác định nguồn và tác nhân. Trước khi viết, trả lời: requirement này phục vụ ai (vai trò cụ thể, không phải "người dùng" chung chung) và đến từ nhu cầu kinh doanh nào. Gắn nó với business need để đảm bảo tính Necessary và Traceable.
Bước 2 — Viết bản nháp bằng một mẫu câu. Chọn template phù hợp (functional, user story, hay EARS) và viết câu đầu tiên. Đừng cầu toàn ở bước này, cứ viết ra đã.
Bước 3 — Quét từ ngữ cao su. Đọc lại và khoanh tròn mọi tính từ/trạng từ mơ hồ (nhanh, dễ, an toàn, đầy đủ…). Với mỗi từ, thay bằng một con số, một chuẩn, hoặc một tiêu chí đo được.
Bước 4 — Áp phép thử test case. Tự hỏi: "Tester viết được test PASS/FAIL không?" Nếu không, làm rõ thêm điều kiện đầu vào, hành vi kỳ vọng, và kết quả mong đợi.
Bước 5 — Bổ sung luồng ngoại lệ. Hỏi "còn trường hợp nào khác?" ít nhất 3 lần: lỗi đầu vào, điều kiện biên (0, rỗng, tối đa), và lỗi hệ thống. Viết acceptance criteria cho từng luồng.
Bước 6 — Gán ID và truy vết. Đặt mã (ví dụ FR-PAY-012), liên kết lên business goal và xuống test case. Đây là khâu đảm bảo Consistent và Traceable khi rà soát toàn bộ tài liệu.
Bước 7 — Review chéo. Nhờ một người không tham gia viết đọc lại. Nếu họ hiểu khác ý bạn, requirement chưa Unambiguous. Người đọc lý tưởng nhất là chính lập trình viên và tester sẽ thực hiện nó.
Lỗi thường gặp & mẹo
Lỗi 1 — Trộn requirement với giải pháp thiết kế. "Hệ thống phải có một nút màu xanh ở góc phải để gửi đơn" mô tả giải pháp, không phải nhu cầu. Hãy viết "Người dùng phải gửi được đơn từ màn hình xem lại" và để phần nút màu gì, ở đâu cho khâu thiết kế. Trộn lẫn sẽ khóa cứng giải pháp quá sớm và làm requirement kém Negotiable.
Lỗi 2 — Gộp nhiều yêu cầu vào một câu. "Hệ thống cho phép đăng nhập, đặt lại mật khẩu và khóa tài khoản sau 5 lần sai." Đây là ba requirement bị nhồi làm một — không thể ưu tiên riêng, không thể test riêng. Tách ra: một câu một ý.
Lỗi 3 — Dùng "và/hoặc", "v.v.", "...". Những từ này là dấu hiệu của tư duy chưa hoàn chỉnh. "Hỗ trợ thẻ Visa, Mastercard, v.v." — "v.v." là gì? JCB có không? Amex có không? Liệt kê hết hoặc nêu rõ tiêu chí.
Lỗi 4 — Dùng câu phủ định mơ hồ. "Hệ thống không được chậm" khó test hơn nhiều so với "Hệ thống phản hồi trong ≤ 2 giây". Ưu tiên phát biểu khẳng định, đo được.
Mẹo 1 — Quy ước "shall / must / should". Dùng "phải" (shall/must) cho yêu cầu bắt buộc, "nên" (should) cho khuyến nghị. Đừng dùng "sẽ" (will) vì nó mô tả tương lai chứ không ràng buộc. Thống nhất quy ước này trong cả tài liệu để tránh hiểu nhầm mức độ bắt buộc.
Mẹo 2 — Một câu, một ID, một sự thật. Mỗi requirement là một đơn vị nguyên tử có thể được phê duyệt, ưu tiên, test và truy vết độc lập.
Mẹo 3 — Đọc to lên. Nếu khi đọc to bạn phải dừng lại giải thích "ý tôi là…", thì câu chữ chưa đủ rõ. Requirement tốt tự nó đã là lời giải thích.
Bài tập thực hành
Bài 1 — Chữa câu mơ hồ. Viết lại ba requirement sau cho đạt chuẩn Clear + Testable, bổ sung con số và điều kiện đo:
- "Ứng dụng phải tải nhanh."
- "Hệ thống phải bảo mật thông tin khách hàng."
- "Báo cáo phải dễ hiểu cho ban giám đốc."
Bài 3 — Tìm mâu thuẫn. Cho hai câu: (A) "Khách hàng có thể hủy đơn bất cứ lúc nào." (B) "Đơn đã chuyển sang trạng thái Đang giao không thể hủy." Hãy chỉ ra mâu thuẫn và viết lại thành một bộ requirement nhất quán, có ID và truy vết về cùng business rule.
Bài 4 — Tự chấm điểm. Lấy một requirement bạn từng viết trong công việc thật, chấm nó theo 8 tiêu chí IEEE và 6 chữ INVEST. Đánh dấu tiêu chí nào trượt và viết lại bản v2.
Tóm tắt
Viết requirement chất lượng cao là kỹ năng cốt lõi biến nhu cầu mơ hồ của stakeholder thành câu chữ mà lập trình viên và tester không thể hiểu sai. Hai bộ tiêu chuẩn — IEEE 830/ISO 29148 (Waterfall) và INVEST (Agile) — gặp nhau ở hai chữ vàng: Clear (đơn nghĩa) và Testable (kiểm chứng được).
Ba vũ khí thực chiến cần nhớ: (1) quét và tiêu diệt từ ngữ cao su, thay mỗi tính từ mơ hồ bằng một con số đo được; (2) áp phép thử test case — nếu tester không viết được PASS/FAIL thì requirement chưa đạt; (3) gán ID và truy vết để đảm bảo nhất quán khi nhiều người cùng viết. Ba ví dụ — Timo (P95 hiệu năng), Shopee (luồng ngoại lệ), FE Credit (mâu thuẫn xuyên tài liệu) — cho thấy mỗi tiêu chí lý thuyết đều có cái giá rất thật khi bị bỏ qua.
Quy trình bảy bước, từ xác định tác nhân đến review chéo, giúp bạn biến lý thuyết thành thói quen. Hãy nhớ nguyên tắc đơn giản nhất: một câu, một ý, một con số, một cách hiểu. Đó là ranh giới giữa một tài liệu requirement gây cháy dự án và một tài liệu mà cả đội tin tưởng làm theo.