Menu
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Đang tải...

Bài 16 — Backlog Refinement và Story Slicing

Technical Product Manager Bài 16/60

Mở đầu — vì sao bài này quan trọng

Hãy tưởng tượng bạn là Technical PM của một đội phát triển ví điện tử tại Việt Nam. Sprint Planning bắt đầu, đội kỹ thuật mở backlog ra, và item đầu tiên là: "Làm tính năng thanh toán hóa đơn". Câu hỏi đầu tiên của tech lead: "Cái này estimate bao nhiêu?" Cả phòng im lặng. Hóa đơn điện, nước, internet, truyền hình cáp? Có lưu hóa đơn yêu thích không? Có nhắc hạn thanh toán không? Tích hợp bao nhiêu nhà cung cấp? Không ai biết, và item đó "to" đến mức không ai dám đụng vào. Sprint trôi qua, item vẫn nằm đó, "in progress" mãi mãi.

Vấn đề không phải đội yếu. Vấn đề là backlog chưa được chuẩn bị (refinement) và story chưa được cắt nhỏ (slicing) đúng cách. Đây chính xác là phần việc mà một Technical PM phải làm chủ. Ở Bài 14 bạn đã học cách estimate, ở Bài 15 bạn đã học Sprint Planning với ràng buộc kỹ thuật. Nhưng cả hai đều giả định rằng backlog đã sẵn sàng để đưa vào sprint. Bài 16 này lấp đầy khoảng trống đó: làm thế nào để biến những ý tưởng mơ hồ, to lớn thành những story nhỏ, rõ ràng, estimate được và giao được trong một sprint.

Story slicing không phải kỹ năng "nice-to-have". Nó là kỹ năng phân biệt một PM kỹ thuật giỏi với một người chỉ biết viết yêu cầu. Khi bạn cắt story tốt, đội giao hàng đều đặn, đo được tiến độ, và quan trọng nhất: tạo ra giá trị cho người dùng sớm thay vì chờ một "big bang" sau ba tháng. Khi bạn cắt kém, mọi thứ khác — velocity, cam kết, niềm tin của stakeholder — đều sụp đổ theo.

Khái niệm cốt lõi

Backlog Refinement là gì

Backlog Refinement (còn gọi là backlog grooming) là hoạt động liên tục giữ cho backlog luôn ở trạng thái "sẵn sàng". Cụ thể, refinement bao gồm: làm rõ yêu cầu, bổ sung acceptance criteria, cắt nhỏ những story quá to, ước lượng sơ bộ, sắp xếp lại độ ưu tiên, và loại bỏ những item không còn liên quan.

Điểm mấu chốt cần nhớ: refinement KHÁC với Sprint Planning. Refinement chuẩn bị "nguyên liệu" trước; Sprint Planning là lúc "nấu ăn" — chọn nguyên liệu đã sơ chế để cam kết cho sprint. Nếu bạn cố refine ngay trong Sprint Planning, buổi planning sẽ kéo dài lê thê và đội sẽ kiệt sức. Nguyên tắc thực hành phổ biến là dành khoảng 5–10% năng lực (capacity) của đội mỗi sprint cho refinement, thường là một hoặc hai buổi 60–90 phút.

Một khái niệm hữu ích đi kèm là "Definition of Ready" (DoR) — tiêu chí để một story được coi là đủ điều kiện đưa vào sprint: có mô tả rõ, có acceptance criteria, đã được team estimate, các dependency đã được xác định, và đủ nhỏ để hoàn thành trong một sprint. Refinement chính là quá trình đưa story đạt tới trạng thái Ready.

Story Slicing — cắt dọc, không cắt ngang

Đây là khái niệm quan trọng nhất của bài. Khi cắt một story lớn (epic) thành các story nhỏ, có hai cách: cắt ngang (horizontal) theo tầng kỹ thuật, hoặc cắt dọc (vertical) theo giá trị.

Cắt ngang nghĩa là chia theo layer: một story làm database, một story làm API, một story làm UI. Nghe có vẻ hợp lý với kỹ sư, nhưng đây là cái bẫy chết người. Vì sao? Vì khi story "làm database" xong, người dùng KHÔNG nhận được giá trị gì cả. Phải đợi cả ba story xong thì tính năng mới chạy. Bạn mất khả năng giao giá trị sớm và khả năng feedback sớm.

Cắt dọc nghĩa là mỗi story đi xuyên qua tất cả các tầng nhưng chỉ phục vụ một lát cắt nhỏ của tính năng. Ví dụ với tính năng "thanh toán hóa đơn": thay vì cắt thành DB/API/UI, ta cắt thành "thanh toán hóa đơn điện cho MỘT nhà cung cấp duy nhất" — story này có cả DB, API, UI, nhưng chỉ làm đúng một thứ. Khi xong, người dùng đã có thể thanh toán hóa đơn điện thật. Đó là một lát "bánh gato" hoàn chỉnh, có cả đế lẫn kem, chỉ là nhỏ thôi.

Tiêu chí INVEST — thước đo một story tốt

INVEST là từ viết tắt do Bill Wake đề xuất, mô tả sáu phẩm chất của một story tốt:

  • I — Independent (Độc lập): Story không bị block bởi story khác trong cùng sprint, và có thể được ưu tiên, phát triển một cách tương đối độc lập. Sự phụ thuộc chéo khiến việc lập kế hoạch trở thành cơn ác mộng.
  • N — Negotiable (Có thể thương lượng): Story là lời mời để trao đổi, không phải hợp đồng cứng nhắc. Chi tiết "làm thế nào" được thống nhất giữa PM và đội, có thể điều chỉnh.
  • V — Valuable (Có giá trị): Mỗi story phải mang lại giá trị rõ ràng cho người dùng hoặc khách hàng. Đây là lý do ta cắt dọc chứ không cắt ngang — một story "làm database" không có giá trị độc lập.
  • E — Estimable (Ước lượng được): Đội phải có khả năng ước lượng story. Nếu không estimate được, thường là do story quá to, quá mơ hồ, hoặc thiếu kiến thức kỹ thuật — đó là tín hiệu cần refine thêm.
  • S — Small (Nhỏ): Story đủ nhỏ để hoàn thành trong một sprint, lý tưởng là vài ngày. Story càng nhỏ thì estimate càng chính xác và rủi ro càng thấp.
  • T — Testable (Kiểm thử được): Phải có cách xác định story đã "done" hay chưa, thường thông qua acceptance criteria rõ ràng (kết nối với Bài 18).
Một mẹo thực hành: khi nhìn vào một story và thấy nó "khó chịu", hãy soi qua sáu chữ INVEST để tìm ra nó vi phạm tiêu chí nào, rồi sửa đúng chỗ đó.

Các kỹ thuật slicing phổ biến (SPIDR và biến thể)

Khi cần cắt nhưng không biết cắt theo chiều nào, có vài "mẫu" thực dụng:

  • Theo bước trong workflow: Tách quy trình thành các bước, làm từng bước. Ví dụ đăng ký tài khoản: nhập số điện thoại → xác thực OTP → thiết lập mật khẩu → hoàn tất hồ sơ.
  • Theo quy tắc nghiệp vụ (business rules): Làm trường hợp đơn giản trước, các quy tắc phức tạp sau. Ví dụ tính phí ship: ban đầu phí cố định, sau mới thêm quy tắc theo khoảng cách, theo khuyến mãi.
  • Theo biến thể dữ liệu: Một loại dữ liệu trước, mở rộng sau. Ví dụ thanh toán: thẻ nội địa trước, thẻ quốc tế và ví sau.
  • Theo nỗ lực / happy path trước: Làm luồng thành công trước, xử lý lỗi và edge case ở story sau.
  • Theo giao diện vận hành (operations CRUD): Tách Create, Read, Update, Delete thành các story riêng nếu hợp lý.
  • Spike: Khi story không estimate được vì thiếu hiểu biết kỹ thuật, tạo một "spike" — một story nghiên cứu có giới hạn thời gian (time-boxed) để giảm bất định, rồi mới cắt phần còn lại.

Tình huống thực tế

Tình huống 1 — Ví điện tử và cái epic "thanh toán hóa đơn"

Quay lại đội ví điện tử ở phần mở đầu. PM nhận ra "thanh toán hóa đơn" là một epic, không phải story. Trong buổi refinement, đội cùng nhau cắt dọc:

  • Story 1: Thanh toán hóa đơn điện EVN cho một mã khách hàng nhập tay, dùng thẻ nội địa. (Có UI nhập mã, API gọi sang EVN, lưu giao dịch.)
  • Story 2: Lưu mã khách hàng yêu thích để lần sau không nhập lại.
  • Story 3: Thêm hóa đơn nước.
  • Story 4: Nhắc hạn thanh toán qua push notification.
  • Story 5: Thêm thanh toán bằng số dư ví (thay vì chỉ thẻ).
Bối cảnh con số: trước khi cắt, epic được "đoán mò" là 40 story point và không ai dám đưa vào sprint. Sau khi cắt, Story 1 chỉ còn 5 point và lọt gọn vào sprint kế tiếp. Quan trọng hơn: sau hai tuần, đội đã có người dùng thật thanh toán hóa đơn điện — một tính năng "sống" để thu feedback, thay vì chờ ba tháng cho "trọn gói".

Bài học rút ra: khi một item to đến mức "đông cứng" trong backlog, gần như chắc chắn đó là epic chưa được cắt. Hãy hỏi: "Lát cắt nhỏ nhất nào vẫn mang lại giá trị thật cho một người dùng thật?"

Tình huống 2 — Cái bẫy cắt ngang ở một startup logistics

Một startup giao hàng chặng cuối tại TP.HCM xây tính năng theo dõi đơn hàng real-time. Tech lead, vì quen tư duy kiến trúc, cắt thành ba story theo tầng: "Story A — thiết kế schema vị trí tài xế", "Story B — API stream vị trí", "Story C — màn hình bản đồ". Đội nhận cả ba vào một sprint.

Kết quả: Story A và B xong sớm trong tuần đầu, nhưng demo cuối sprint thì... chẳng có gì để xem. Story C bị block vì thiếu một số trường dữ liệu mà lúc làm schema chưa lường tới. Stakeholder dự buổi demo thấy "ba tuần làm việc mà bản đồ vẫn trắng", niềm tin sụt giảm. Velocity báo cáo "đẹp" (point đã done) nhưng giá trị giao cho người dùng bằng không.

PM can thiệp ở sprint sau, cắt lại theo chiều dọc: "Hiển thị vị trí tài xế cập nhật mỗi 30 giây cho MỘT đơn hàng đang giao." Lát cắt này mỏng nhưng đầy đủ schema-API-UI, demo được ngay. Sau đó mới mở rộng: cập nhật mỗi 5 giây, hiển thị tuyến đường dự kiến, xử lý mất sóng GPS.

Bài học rút ra: cắt ngang làm "velocity ảo" — điểm tăng nhưng giá trị không tăng. Mỗi story phải tự nó demo được. Nếu một story không thể demo cho stakeholder, hãy nghi ngờ ngay rằng bạn đang cắt ngang.

Tình huống 3 — Spike để gỡ bế tắc estimate ở một công ty EdTech

Một công ty EdTech muốn thêm tính năng "chấm điểm phát âm tiếng Anh tự động" bằng AI. Trong refinement, đội đụng tường: không ai estimate nổi vì chưa rõ dùng API bên thứ ba (như Azure Speech) hay tự host model, độ chính xác ra sao, độ trễ thế nào. Estimate dao động từ 3 đến 40 point — một dấu hiệu rõ ràng của bất định cao.

Thay vì cố ép estimate, PM đề xuất một spike time-box 3 ngày: dựng prototype gọi thử hai nhà cung cấp, đo độ trễ và độ chính xác trên 50 mẫu giọng người Việt. Sau spike, đội biết Azure Speech cho độ trễ chấp nhận được và độ chính xác đủ dùng cho MVP. Lúc này epic mới được cắt thành các story estimate được: tích hợp API chấm một từ → chấm một câu → hiển thị điểm chi tiết từng âm tiết → lưu lịch sử luyện tập.

Bài học rút ra: khi estimate "nhảy múa" quá rộng, đừng đoán bừa — hãy mua thông tin bằng một spike có giới hạn. Spike không tạo giá trị trực tiếp cho người dùng, nhưng nó biến cái không estimate được thành estimate được, đó chính là giá trị của nó trong refinement.

Hướng dẫn từng bước

Đây là quy trình thực dụng để chạy một buổi backlog refinement và cắt story hiệu quả:

Bước 1 — Chuẩn bị trước buổi họp. PM (bạn) duyệt qua backlog, đánh dấu 5–10 item ở đầu hàng đợi sẽ được refine. Với mỗi item, viết sẵn bối cảnh và mục tiêu giá trị. Đừng mang cả backlog 200 item vào họp — chỉ tập trung phần sắp được kéo vào 1–2 sprint tới.

Bước 2 — Làm rõ giá trị và phạm vi. Với từng item, trả lời: Ai là người dùng? Họ đạt được gì? Tại sao bây giờ? Viết theo mẫu user story: "Là một [vai trò], tôi muốn [hành động] để [giá trị]." Mẫu này không bắt buộc nhưng giúp giữ focus vào giá trị.

Bước 3 — Kiểm tra kích thước. Hỏi đội: "Item này có hoàn thành trong một sprint không?" Nếu câu trả lời là "không chắc" hoặc "không", đó là epic cần cắt. Chuyển sang bước 4.

Bước 4 — Chọn đường cắt. Chạy qua bộ kỹ thuật slicing (workflow, business rules, biến thể dữ liệu, happy path trước, CRUD). Tìm "lát cắt mỏng nhất vẫn có giá trị" làm story đầu tiên, rồi liệt kê các lát tiếp theo. Luôn cắt dọc.

Bước 5 — Viết acceptance criteria sơ bộ. Với mỗi story đã cắt, viết vài tiêu chí chấp nhận để story trở nên Testable (chi tiết về Definition of Done sẽ học ở Bài 18). Đây cũng là lúc lộ ra các edge case ẩn.

Bước 6 — Estimate sơ bộ. Đội ước lượng từng story (point hoặc T-shirt size). Nếu một story vẫn quá to hoặc estimate phân tán quá rộng, quay lại bước 4 để cắt tiếp, hoặc tạo spike.

Bước 7 — Soi qua INVEST. Trước khi coi story là "Ready", kiểm nhanh sáu tiêu chí. Đặc biệt chú ý Independent (có dependency ẩn không?) và Valuable (story này tự nó demo được không?).

Bước 8 — Cập nhật backlog. Sắp xếp lại độ ưu tiên, gắn nhãn các story đã Ready. Những story này giờ là "nguyên liệu sạch" cho Sprint Planning.

Lỗi thường gặp & mẹo

Lỗi 1 — Cắt ngang theo tầng kỹ thuật. Đây là lỗi phổ biến nhất, đặc biệt với đội kỹ thuật mạnh. Mẹo: với mỗi story, tự hỏi "story này xong thì demo cho người dùng được cái gì?" Nếu câu trả lời là "chưa demo được gì", bạn đang cắt ngang.

Lỗi 2 — Biến refinement thành Sprint Planning hoặc thành buổi thiết kế kỹ thuật chi tiết. Refinement là để story đủ rõ và đủ nhỏ, không phải để chốt mọi chi tiết implementation. Mẹo: time-box mỗi item, và nếu một item ngốn quá nhiều thời gian, ghi nhận làm spike thay vì sa lầy tại chỗ.

Lỗi 3 — Cắt quá nhỏ thành "vụn". Cắt nhỏ là tốt, nhưng cắt một tính năng thành 30 mảnh siêu nhỏ, mỗi mảnh tự nó vô nghĩa, sẽ tạo overhead quản lý và làm mất bức tranh tổng thể. Mẹo: dùng tiêu chí Valuable làm phanh — nếu lát cắt không còn mang giá trị độc lập, bạn đã cắt quá tay.

Lỗi 4 — Bỏ qua dependency. Hai story tưởng độc lập nhưng cùng đụng một module, một bảng dữ liệu. Mẹo: trong refinement, vẽ nhanh sơ đồ dependency. Nếu Story B chắc chắn cần Story A xong trước, hãy cân nhắc gộp hoặc sắp xếp thứ tự rõ ràng để không vi phạm tiêu chí Independent trong cùng sprint.

Lỗi 5 — Để PM tự cắt một mình rồi áp xuống. Story slicing là hoạt động tập thể; kỹ sư thường nhìn ra đường cắt kỹ thuật mà PM không thấy. Mẹo: PM dẫn dắt về giá trị và ưu tiên, đội đóng góp về cách cắt khả thi về mặt kỹ thuật. Negotiable trong INVEST chính là tinh thần này.

Mẹo vàng: Khi bí, hãy hỏi một câu duy nhất: "Đâu là phiên bản nhỏ nhất, xấu nhất, nhưng vẫn dùng được của tính năng này?" Phiên bản đó thường chính là story đầu tiên cần làm.

Bài tập thực hành

Bài tập 1 — Cắt epic. Cho epic sau của một sàn thương mại điện tử: "Người dùng có thể đánh giá và xếp hạng sản phẩm đã mua, kèm ảnh, và lọc đánh giá theo số sao." Hãy cắt epic này thành tối thiểu 5 story theo chiều dọc, sắp xếp theo thứ tự ưu tiên giao hàng. Với mỗi story, viết một câu giá trị theo mẫu user story.

Bài tập 2 — Soi INVEST. Cho story: "Là một admin, tôi muốn hệ thống tự động tối ưu toàn bộ hiệu năng dashboard để mọi báo cáo tải nhanh hơn." Hãy chỉ ra story này vi phạm những tiêu chí INVEST nào và đề xuất cách viết lại cho đạt chuẩn.

Bài tập 3 — Quyết định spike hay cắt. Đội của bạn cần làm "đăng nhập bằng VNeID (định danh điện tử)". Estimate dao động từ 5 đến 30 point. Hãy quyết định: bạn sẽ tạo spike hay cắt thẳng thành story? Nếu spike, hãy viết mục tiêu và giới hạn thời gian. Nếu cắt, hãy đề xuất lát cắt đầu tiên.

Bài tập 4 — Thiết kế Definition of Ready. Viết một danh sách 5–7 tiêu chí "Definition of Ready" cho đội của bạn, để dùng làm cổng kiểm tra trước khi story được đưa vào Sprint Planning.

Tóm tắt

Backlog Refinement là hoạt động liên tục giữ cho backlog luôn ở trạng thái "sẵn sàng" — tách biệt rõ với Sprint Planning, thường tốn 5–10% năng lực mỗi sprint. Trái tim của refinement là Story Slicing: cắt những epic to thành các story nhỏ.

Nguyên tắc sống còn là cắt dọc, không cắt ngang — mỗi story phải đi xuyên các tầng kỹ thuật và tự nó mang lại giá trị demo được cho người dùng, thay vì chia theo database/API/UI. Thước đo một story tốt là INVEST: Independent, Negotiable, Valuable, Estimable, Small, Testable. Khi bí cách cắt, hãy dùng các mẫu thực dụng: theo bước workflow, theo quy tắc nghiệp vụ, theo biến thể dữ liệu, làm happy path trước; và khi không estimate được, dùng spike time-box để mua thông tin.

Ba tình huống — ví điện tử cắt epic hóa đơn, startup logistics dính bẫy cắt ngang, EdTech dùng spike gỡ bế tắc — cho thấy cùng một bài học: lát cắt mỏng nhất vẫn có giá trị chính là story đầu tiên bạn nên làm. Một Technical PM giỏi không phải người viết yêu cầu hay nhất, mà là người cắt được giá trị thành những miếng nhỏ, giao được, đo được, và tạo ra dòng giá trị đều đặn cho người dùng.