Mở đầu — vì sao bài này quan trọng
Có một câu nói rất phổ biến trong giới phát triển phần mềm: "Chúng ta sẽ refactor sau." Và "sau" ấy, trong rất nhiều đội nhóm, không bao giờ đến. Là một Product Owner (PO), bạn đứng ở vị trí đặc biệt — bạn là người quyết định thứ tự công việc trong Product Backlog, là người chịu trách nhiệm tối đa hóa giá trị sản phẩm. Vì vậy, technical debt (nợ kỹ thuật) không chỉ là chuyện của Developers. Nó là chuyện của bạn.
Nhiều PO mới vào nghề nghĩ rằng: "Nợ kỹ thuật là việc kỹ thuật, để các bạn dev tự xử lý." Đây là một trong những hiểu lầm nguy hiểm nhất. Nếu bạn liên tục ép tiến độ, liên tục đẩy feature mới lên đầu backlog mà phớt lờ những cảnh báo về chất lượng nội tại của sản phẩm, bạn đang vô tình tích lũy một khoản nợ mà rồi chính sản phẩm của bạn sẽ phải trả lãi — bằng tốc độ giao hàng chậm dần, bằng bug ngày càng nhiều, bằng việc một thay đổi nhỏ cũng mất hàng tuần để hoàn thành.
Trong kỳ thi PSPO I và quan trọng hơn là trong thực tế công việc, bạn cần hiểu rằng technical debt là một yếu tố trực tiếp ảnh hưởng đến khả năng giao giá trị (value delivery) của Scrum Team. PO không cần viết code, nhưng PO bắt buộc phải hiểu, đối thoại và đưa ra quyết định đánh đổi (trade-off) về nợ kỹ thuật một cách tỉnh táo. Bài học này sẽ giúp bạn làm được điều đó.
Khái niệm cốt lõi
Định nghĩa gốc của Ward Cunningham
Thuật ngữ "technical debt" được Ward Cunningham — một trong những người ký Tuyên ngôn Agile — đặt ra vào đầu thập niên 1990. Phép ẩn dụ của ông rất đơn giản và sâu sắc: viết code vội vàng (shipping code nhanh) cũng giống như vay nợ. Bạn nhận được lợi ích ngay lập tức (ra mắt tính năng sớm, học được từ thị trường nhanh), nhưng bạn phải trả "lãi" (interest) dưới dạng công sức tăng thêm mỗi lần bạn quay lại sửa đoạn code đó trong tương lai.
Điều quan trọng mà nhiều người hiểu sai về định nghĩa gốc của Cunningham: ông KHÔNG nói nợ kỹ thuật là code dở, code cẩu thả. Ý ông là khi bạn đưa sản phẩm ra thị trường với hiểu biết chưa đầy đủ, rồi học hỏi và quay lại điều chỉnh — đó là vay nợ một cách có chủ đích và lành mạnh. Vấn đề chỉ xảy ra khi bạn vay mà không bao giờ trả, để lãi mẹ đẻ lãi con.
Lãi suất (interest) là gì trong thực tế?
Với PO, cách dễ hiểu nhất để hình dung "lãi" là: mỗi đơn vị tính năng mới sẽ tốn nhiều công hơn để xây dựng so với lẽ ra nó phải tốn. Ví dụ, một tính năng đáng lẽ mất 3 ngày, nhưng vì codebase đã rối, đã chắp vá, nên Developers phải mất 8 ngày — 5 ngày chênh lệch đó chính là tiền lãi bạn đang trả. Lãi này âm thầm bào mòn velocity (tốc độ giao hàng) của đội.
Các loại technical debt
Để đối thoại với đội kỹ thuật, PO nên nắm được nợ kỹ thuật biểu hiện ở nhiều tầng:
Code debt — code trùng lặp, đặt tên khó hiểu, hàm quá dài, không tuân theo chuẩn chung. Đây là loại dễ thấy nhất khi Developers than phiền "code chỗ này rối quá".
Architecture debt — những quyết định kiến trúc ở giai đoạn đầu nay đã không còn phù hợp với quy mô hiện tại. Ví dụ, một hệ thống monolith (khối nguyên) được thiết kế cho 1.000 người dùng nay phải gánh 1 triệu người dùng.
Test debt — thiếu kiểm thử tự động (automated test). Hệ quả là mỗi lần thay đổi, đội phải kiểm thử thủ công, vừa chậm vừa dễ sót lỗi, và càng ngại thay đổi vì sợ "đụng đâu hỏng đó".
Documentation debt — thiếu tài liệu, hoặc tài liệu lỗi thời, khiến thành viên mới mất nhiều thời gian để hiểu hệ thống.
Phân loại của Martin Fowler — ma trận nợ kỹ thuật
Martin Fowler đề xuất một cách phân loại rất hữu ích cho PO, dựa trên hai trục: cố ý/vô tình (deliberate/inadvertent) và thận trọng/liều lĩnh (prudent/reckless):
- Cố ý + thận trọng: "Chúng ta biết đây là giải pháp tạm, sẽ trả nợ sau Sprint này." Đây là nợ tốt, có kiểm soát.
- Cố ý + liều lĩnh: "Không có thời gian thiết kế đàng hoàng đâu, cứ làm đại đi." Đây là nợ nguy hiểm.
- Vô tình + thận trọng: "Giờ chúng ta đã hiểu rồi, lẽ ra nên làm thế này." Học hỏi tự nhiên, khó tránh.
- Vô tình + liều lĩnh: "Layered architecture là gì?" Đội thiếu năng lực, không biết mình đang tạo nợ.
Vai trò của PO trong câu chuyện nợ kỹ thuật
Điều then chốt cần nhớ theo Scrum Guide: PO sở hữu Product Backlog và quyết định thứ tự (ordering). Công việc xử lý technical debt — refactoring, nâng cấp hạ tầng, viết test — phải hiển hiện trên Product Backlog dưới dạng các Product Backlog Item (PBI), chứ không phải là công việc "lén lút" mà Developers tự làm sau lưng PO.
Tuy nhiên — và đây là điểm tinh tế — PO KHÔNG được phép áp đặt cách Developers giải quyết nợ kỹ thuật. Developers tự quản (self-managing), họ quyết định HOW (làm thế nào). PO quyết định WHAT và WHEN ở mức ưu tiên giá trị. Mối quan hệ này là đối thoại, không phải mệnh lệnh.
Tình huống thực tế
Tình huống 1: Startup fintech tại TP.HCM trả giá cho việc "đi nhanh"
Một startup ví điện tử giả định tên FastPay tại TP.HCM, trong năm đầu tiên, chạy đua với đối thủ để chiếm thị phần. PO của họ — anh Minh — liên tục đẩy tính năng mới: nạp tiền, chuyển khoản, thanh toán hóa đơn, mua mã thẻ, ví trả góp... Mỗi Sprint là một tính năng mới ra mắt. Developers nhiều lần cảnh báo rằng module xử lý giao dịch đang chắp vá, không có test tự động, nhưng anh Minh luôn trả lời: "Để sau, giờ ưu tiên giành user."
Đến tháng thứ 14, khi FastPay có 800.000 người dùng, hệ quả ập đến. Một tính năng đơn giản là "thêm hạn mức giao dịch theo ngày" lẽ ra mất 1 Sprint, nhưng kéo dài tới 3 Sprint vì đụng đến module giao dịch rối rắm. Tệ hơn, một thay đổi nhỏ làm phát sinh lỗi tính sai số dư cho khoảng 1.200 tài khoản, gây khủng hoảng niềm tin và đội phải bỏ 2 tuần chỉ để xử lý sự cố và xoa dịu khách hàng.
Bài học rút ra: Lãi của nợ kỹ thuật không trả ngay — nó dồn lại và "đòi" vào đúng lúc bạn cần đi nhanh nhất. PO Minh đã vay nợ kiểu "cố ý + liều lĩnh" mà không bao giờ lên kế hoạch trả. Đáng lẽ, ngay từ khi Developers cảnh báo, anh nên đưa các PBI về test tự động và refactoring module giao dịch vào backlog với mức ưu tiên hợp lý — không phải đầu tiên, nhưng cũng không phải không bao giờ.
Tình huống 2: PO biến nợ kỹ thuật thành ngôn ngữ kinh doanh tại một công ty e-commerce
Tại một công ty thương mại điện tử giả định ở Hà Nội tên ShopViet, PO tên chị Lan gặp tình huống ngược lại. Developers liên tục muốn dành 30% thời lượng mỗi Sprint để "dọn dẹp kỹ thuật", nhưng không giải thích được lý do bằng ngôn ngữ kinh doanh. Stakeholder bên kinh doanh phản đối vì họ chỉ thấy "feature ra chậm mà không hiểu để làm gì".
Chị Lan làm một việc thông minh: chị ngồi với Developers và quy đổi nợ kỹ thuật ra con số. Họ phát hiện trang checkout có thời gian tải trung bình 4,5 giây vì code cũ; mỗi giây chậm làm tỷ lệ bỏ giỏ hàng tăng khoảng 7%. Với doanh thu 50 tỷ đồng/tháng, việc tối ưu codebase để giảm thời gian tải xuống 1,5 giây có thể cứu được khoản doanh thu ước tính vài tỷ đồng mỗi tháng. Khi chị Lan trình bày với stakeholder bằng con số này, họ lập tức đồng ý ưu tiên một Product Goal về hiệu năng.
Bài học rút ra: PO giỏi không nói "chúng ta cần trả nợ kỹ thuật". PO giỏi nói "việc này đang khiến chúng ta mất X tỷ đồng/tháng". Nhiệm vụ của bạn là dịch nỗi đau kỹ thuật của Developers thành tác động giá trị mà stakeholder hiểu được. Đây chính là tinh thần maximizing value của vai trò PO.
Tình huống 3: Nợ kỹ thuật "tốt" trong một dự án giáo dục
Một nền tảng học trực tuyến giả định tên EduGo cần ra mắt tính năng livestream lớp học gấp trước mùa tựu trường. PO quyết định: "Chúng ta dùng dịch vụ bên thứ ba (third-party) tích hợp nhanh trong 2 Sprint, dù biết phí cao và khó tùy biến. Nếu tính năng được học viên đón nhận, Sprint sau chúng ta sẽ đầu tư xây dựng giải pháp riêng."
Đây là nợ kỹ thuật "cố ý + thận trọng" rất đẹp. Họ vay nợ một cách có ý thức, có điều kiện trả nợ rõ ràng (nếu được đón nhận), và ghi nhận khoản nợ này thành một PBI cụ thể trên backlog. Kết quả: tính năng thành công, 3 tháng sau họ thay thế bằng giải pháp tự xây và tiết kiệm 60% chi phí.
Bài học rút ra: Không phải mọi nợ kỹ thuật đều xấu. Vay nợ có chủ đích để học hỏi nhanh và validate giả thuyết thị trường là một chiến lược PO khôn ngoan — miễn là bạn luôn biết mình nợ bao nhiêu và có kế hoạch trả.
Hướng dẫn từng bước
Dưới đây là quy trình thực tế để một PO quản lý technical debt một cách lành mạnh:
Bước 1 — Làm cho nợ kỹ thuật hữu hình (visible). Cùng Developers đưa các khoản nợ kỹ thuật lên Product Backlog dưới dạng PBI rõ ràng. Một số đội tạo nhãn riêng (ví dụ "tech-debt") để dễ theo dõi. Nguyên tắc vàng: cái gì không nhìn thấy thì không quản lý được. Nợ kỹ thuật ẩn trong đầu Developers là nợ nguy hiểm nhất.
Bước 2 — Đối thoại để hiểu tác động, không phán xét. Trong Product Backlog Refinement, hỏi Developers: "Nếu chúng ta không xử lý khoản này, điều gì sẽ xảy ra trong 3-6 tháng tới?" Mục tiêu là hiểu interest — lãi suất — của từng khoản nợ.
Bước 3 — Quy đổi sang ngôn ngữ giá trị. Với mỗi khoản nợ, cố gắng trả lời: nó làm chậm việc giao tính năng nào? Nó tạo ra bao nhiêu bug? Nó ảnh hưởng trải nghiệm người dùng ra sao? Hãy gắn con số khi có thể.
Bước 4 — Đưa vào ordering của backlog một cách cân bằng. Đừng dồn 100% cho feature mới, cũng đừng dừng mọi thứ để trả nợ. Nhiều đội duy trì một "ngân sách" ổn định, ví dụ dành 15-20% năng lực mỗi Sprint cho việc cải thiện chất lượng nội tại. PO không áp đặt con số này một mình mà thống nhất cùng cả Scrum Team.
Bước 5 — Phòng ngừa nợ mới qua Definition of Done. Cách tốt nhất để không tích nợ là có Definition of Done (DoD) chặt chẽ — bao gồm cả test tự động, code review. DoD do Scrum Team sở hữu, nhưng PO nên ủng hộ một DoD đủ mạnh thay vì gây áp lực làm loãng nó để "ra hàng nhanh".
Bước 6 — Theo dõi và inspect định kỳ. Dùng Sprint Retrospective (của cả đội) và các buổi refinement để liên tục đánh giá: nợ đang tăng hay giảm? Đây là tinh thần inspect & adapt của empiricism.
Lỗi thường gặp & mẹo
Lỗi 1 — Coi technical debt thuần túy là việc của Developers. Như đã nói, nợ kỹ thuật ảnh hưởng trực tiếp đến giá trị và tốc độ giao hàng, nên nó thuộc trách nhiệm của PO trong việc cân nhắc ưu tiên. Phớt lờ nó là phớt lờ một phần công việc của chính bạn.
Lỗi 2 — Áp đặt cách Developers giải quyết nợ. PO quyết định ưu tiên giá trị, không quyết định giải pháp kỹ thuật. Nói "tuần này refactor module thanh toán bằng cách X" là vượt quyền và phá vỡ tính tự quản của đội.
Lỗi 3 — Dồn toàn bộ một "Sprint dọn dẹp" (cleanup Sprint). Đây là chống chỉ định. Trong Scrum, mỗi Sprint phải tạo ra một Increment có giá trị, đáp ứng được. Một Sprint chỉ dọn nợ mà không có đầu ra dùng được cho người dùng đi ngược tinh thần này. Thay vào đó, hãy lồng việc trả nợ vào đều đặn từng Sprint.
Lỗi 4 — Để Developers "giấu" việc trả nợ trong ước lượng. Một số đội âm thầm cộng thêm thời gian vào mỗi tính năng để lén trả nợ. Điều này phá vỡ tính minh bạch (transparency) — một trụ cột của empiricism. Tốt hơn là làm mọi thứ hiển thị trên backlog.
Lỗi 5 — Không bao giờ trả, chỉ vay. Nếu mỗi quý bạn đều nghe "code đang nợ nần chồng chất" mà không có khoản nợ nào được trả, hãy báo động. Đội của bạn đang trượt dần đến điểm mà chi phí thay đổi vượt quá giá trị tạo ra.
Mẹo 1 — Dùng phép ẩn dụ tài chính với stakeholder. Hầu hết stakeholder kinh doanh hiểu rất rõ khái niệm vay nợ và trả lãi. Hãy tận dụng nó: "Chúng ta đang trả 30% lãi mỗi tính năng. Đầu tư trả bớt nợ giờ giúp mọi tính năng sau rẻ hơn."
Mẹo 2 — Gắn việc trả nợ với một mục tiêu giá trị cụ thể. Thay vì "refactor cho sạch", hãy đóng khung "tối ưu hệ thống đặt hàng để chuẩn bị cho chiến dịch khuyến mãi 11/11 dự kiến gấp 5 lần lưu lượng". Việc trả nợ gắn với value sẽ dễ được ưu tiên hơn nhiều.
Mẹo 3 — Lưu ý cho kỳ thi PSPO I. Đề thi thường kiểm tra việc bạn có hiểu rằng PO chịu trách nhiệm tối đa hóa giá trị và technical debt ảnh hưởng đến giá trị đó; rằng việc kỹ thuật phải nằm trên Product Backlog và do PO sắp xếp thứ tự; nhưng cách thực hiện do Developers tự quyết. Đáp án nào ngụ ý PO ra lệnh về kỹ thuật, hoặc PO hoàn toàn "không liên quan" đến tech debt, thường là đáp án sai.
Bài tập thực hành
- Lập danh mục nợ. Hãy ngồi với Developers (hoặc tự hình dung nếu bạn chưa có đội) và liệt kê ít nhất 5 khoản technical debt trong một sản phẩm bạn biết. Với mỗi khoản, ghi rõ: loại nợ (code/architecture/test/documentation) và "lãi suất" — tức tác động cụ thể nếu không xử lý.
- Phân loại theo ma trận Fowler. Đặt từng khoản nợ ở trên vào một trong bốn ô của ma trận Fowler (cố ý/vô tình × thận trọng/liều lĩnh). Khoản nào ở ô "cố ý + liều lĩnh"? Điều gì trong cách làm việc của đội đã dẫn đến nó?
- Viết một PBI cho nợ kỹ thuật. Chọn khoản nợ nghiêm trọng nhất và viết nó thành một Product Backlog Item, kèm phần mô tả tác động giá trị bằng ngôn ngữ kinh doanh (lý tưởng là có con số). Mục tiêu: nếu trình PBI này cho stakeholder, họ phải hiểu vì sao nên ưu tiên.
- Soạn kịch bản đối thoại. Hãy viết ra 3-4 câu bạn sẽ nói với một stakeholder đang phản đối việc dành 20% năng lực Sprint cho việc cải thiện chất lượng nội tại. Dùng phép ẩn dụ tài chính và gắn với một rủi ro kinh doanh cụ thể.
- Tự kiểm tra kiến thức thi. Trả lời nhanh: Ai sở hữu quyết định đưa công việc trả nợ kỹ thuật vào thứ tự ưu tiên của Product Backlog? Ai quyết định cách thức kỹ thuật để giải quyết khoản nợ đó? Hai câu trả lời này phải khác nhau — và đó chính là ranh giới vai trò bạn cần nắm vững.
Tóm tắt
Technical debt — theo phép ẩn dụ gốc của Ward Cunningham — là việc vay một lợi ích ngắn hạn hôm nay để rồi trả lãi trong tương lai dưới dạng công sức tăng thêm, tốc độ chậm lại và bug nhiều hơn. Nó tồn tại ở nhiều tầng: code, kiến trúc, test, tài liệu; và có thể được phân loại theo ma trận cố ý/vô tình × thận trọng/liều lĩnh của Martin Fowler.
Với một Product Owner, ba điều cốt lõi cần khắc ghi:
Thứ nhất, technical debt là chuyện của bạn, không chỉ của Developers, vì nó ảnh hưởng trực tiếp đến giá trị và khả năng giao hàng của sản phẩm. Công việc trả nợ phải hiển hiện trên Product Backlog và do bạn sắp xếp thứ tự.
Thứ hai, ranh giới vai trò phải rõ: PO quyết định WHAT và WHEN ở mức ưu tiên giá trị; Developers tự quản quyết định HOW về kỹ thuật. Vượt ranh giới này là phá vỡ Scrum.
Thứ ba, nghệ thuật của PO giỏi là dịch nỗi đau kỹ thuật thành ngôn ngữ giá trị mà stakeholder hiểu được — biến "code rối" thành "mất X tỷ đồng/tháng", biến refactoring thành "chuẩn bị cho chiến dịch lớn sắp tới". Và quan trọng nhất: không phải nợ nào cũng xấu — vay nợ có chủ đích, có kế hoạch trả, là một chiến lược khôn ngoan. Chỉ có vay mà không bao giờ trả mới là con đường dẫn sản phẩm đến chỗ trì trệ.