Viết mã chưa bao giờ là điểm nghẽn
(ordep.dev)- Trong phát triển phần mềm, điểm nghẽn không nằm ở việc viết mã mà ở nhiều quy trình lấy con người làm trung tâm như review mã, chuyển giao tri thức, kiểm thử, gỡ lỗi, hợp tác/giao tiếp
- Nhờ LLM, bản thân việc sinh mã đã trở nên rất dễ, nhưng chi phí và gánh nặng cho việc hiểu, xác minh, tạo dựng niềm tin lại còn lớn hơn
- Việc tạo mã nhanh mang lại nhiều gánh nặng hơn cho người review, người tích hợp và người phụ trách bảo trì, và tốc độ của cả đội trên thực tế không tăng lên
- Hiểu mã mới là phần khó nhất; dù LLM có tạo ra mã, chất lượng vẫn không thể được đảm bảo nếu thiếu niềm tin và ngữ cảnh được chia sẻ trong nhóm
- LLM rất mạnh cho tạo mẫu và tự động hóa, nhưng không thể thay thế những nền tảng cốt lõi của phát triển phần mềm như thiết kế cẩn trọng, review kỹ lưỡng, chia sẻ ngữ cảnh
Điểm nghẽn thực sự của việc viết mã
- Trong nhiều năm, bản thân công việc viết mã không phải là điểm nghẽn của kỹ nghệ phần mềm
- Điểm nghẽn thực sự nằm ở review mã, truyền đạt tri thức thông qua mentoring và pair programming, kiểm thử, gỡ lỗi, cùng chi phí của hợp tác và giao tiếp
- Quản lý ticket, họp lập kế hoạch, các buổi họp agile và những thủ tục phức tạp khác còn làm chậm tiến độ hơn nữa
- Những quy trình nhằm đảm bảo chất lượng này trên thực tế đòi hỏi nhiều thời gian và suy nghĩ hơn rất nhiều so với chính việc viết mã
- Tuy nhiên, nhờ LLM, chi phí để tạo ra mã chạy được đang tiệm cận 0
- Nhưng chi phí để hiểu mã, kiểm thử và tạo dựng niềm tin lại càng tăng
- Tốc độ triển khai ban đầu đã nhanh hơn, nhưng nhiều mã hơn phải được review/tích hợp/bảo trì, khiến gánh nặng gia tăng
LLM thay đổi bản chất công việc – chứ không loại bỏ nó
- Các công cụ LLM như Claude giúp tăng tốc triển khai ban đầu, nhưng rốt cuộc khi nhiều mã hơn đổ vào hệ thống trong thời gian ngắn hơn, chúng lại tạo gánh nặng lớn hơn cho những người phụ trách review và bảo trì
- Gánh nặng này đặc biệt trầm trọng trong các tình huống sau
- Không chắc người viết có thực sự hiểu đầy đủ đoạn mã mà chính họ đã gửi lên hay không
- Mã được tạo ra sử dụng các mẫu không quen thuộc hoặc vi phạm convention sẵn có
- Các điều kiện biên và tác dụng phụ ngoài ý muốn không được bộc lộ rõ ràng
- Vì vậy, dù việc sản xuất mã trở nên dễ hơn, độ khó của việc xác minh lại cao hơn, và kết quả là không thể làm tăng tốc độ của cả đội
- Trước đây trong giới lập trình từng có câu đùa về “copy-paste engineering”, nhưng với LLM, hiện tượng này còn bị khuếch đại hơn rất nhiều
Hiểu mã mới là điều thực sự khó
“Chi phí lớn nhất của mã không phải là viết ra nó, mà là hiểu nó”
- Nhờ LLM, bản thân việc tạo mã trở nên nhanh hơn, nhưng các công việc như suy luận cách nó vận hành, tìm ra các lỗi tinh vi, hay đảm bảo khả năng bảo trì dài hạn hoàn toàn không trở nên dễ hơn
- Điều này càng khó hơn khi người review không thể phân biệt mã được sinh ra với mã do con người tự viết, hoặc khó xác định lý do đằng sau cách giải pháp được chọn
Nhóm vẫn phụ thuộc vào niềm tin và ngữ cảnh chia sẻ
- Phát triển phần mềm về bản chất là hoạt động hợp tác, và phụ thuộc hoàn toàn vào sự thấu hiểu chung, sự đồng bộ (Alignment) và mentoring
- Khi mã được tạo ra nhanh hơn tốc độ thảo luận và review, nhóm có thể ngộ nhận rằng chất lượng đã được kiểm chứng, dù thực tế họ chưa hề xác nhận chất lượng
- Điều này làm tăng gánh nặng tâm lý cho reviewer và mentor, khiến tốc độ của cả đội có thể chậm lại theo một cách mới
LLM rất mạnh, nhưng không giải quyết được bản chất vấn đề
- LLM rất có giá trị cho prototyping, scaffold, tự động hóa, nhưng không xóa bỏ nhu cầu về tư duy rõ ràng, review cẩn trọng và thiết kế có chiều sâu
- Chi phí viết mã tự thân đã giảm xuống, nhưng chi phí để cả nhóm cùng hiểu mã và gán ý nghĩa cho nó thì không thay đổi
- Điểm nghẽn thực sự vẫn nằm ở "sự thấu hiểu và hợp tác"
7 bình luận
Tôi đúng là một lập trình viên đang thiếu những kỹ năng được giới thiệu trong bài này và phụ thuộc rất nhiều vào LLM.
Vì kiến thức kỹ thuật của tôi còn thiếu nên nếu không có AI thì rất khó làm việc theo WBS...
Nhưng dù vậy, để giảm thời gian các anh chị lập trình viên đi trước phải review, tôi nên làm gì thì tốt đây..?
Tiện thể nếu cũng có thể tích lũy thêm kiến thức cho bản thân thì càng tốt..
Để rút ngắn thời gian review, chính bạn phải là người quyết định và có thể giải thích được đoạn code mình viết ra xuất phát từ bối cảnh nào, cũng như vì sao đã chọn cách đó trong số nhiều phương án triển khai khác nhau. Muốn vậy thì bạn cần duy trì việc 3. vào cuối tuần hoặc thời gian rảnh, và sẽ rất hữu ích nếu thỉnh thoảng xem ngẫu nhiên các thư viện nổi tiếng hoặc code mà người khác đăng trên GitHub để phân tích những thứ như cấu trúc code và phong cách triển khai.
Cảm ơn bạn vì những lời chia sẻ hay!!
Thế mà nhìn cảnh vẫn cắt giảm nhân sự thì thật u ám... 12 dự án mà bắt 4 người làm sao xoay nổi.. lại còn một người vừa phải quản lý nữa..
Hu hu, chắc hẳn bạn đã vất vả lắm.
Ý kiến trên Hacker News
Với tư cách là một người cố vấn giàu kinh nghiệm, tôi từng hướng dẫn những thực tập sinh đầy tham vọng nhưng còn non tay, và chứng kiến họ tạo ra lượng code bằng cả một hoặc hai tuần chỉ trong một ngày. Nhưng công việc của tôi lại trở nên khó hơn trước. Khi review code, các thực tập sinh không suy nghĩ đủ sâu về phần code họ viết nên feedback của tôi không được tiếp thu tốt. Những lỗi đơn giản hay vấn đề nhỏ vặt gần như biến mất, nhưng các vấn đề còn lại thì tinh vi và phức tạp hơn, cũng khó giải thích hơn rất nhiều. Thêm vào đó, còn xuất hiện những kiểu bug hoàn toàn mới mà trước đây chưa từng thấy. Có những đoạn code nhìn bề ngoài hoàn toàn ổn nhưng thực tế không chạy chút nào, hoặc trông như đã hoàn thiện nhưng lại hỏng từ những phần cơ bản nhất. Các junior làm việc cùng LLM dường như có xu hướng tạo ra những khối code phức tạp, trông như đã hoàn chỉnh ngay từ đầu nhưng gây vấn đề cho cộng tác và bảo trì ở nhiều mặt, thay vì đưa ra đoạn code đơn giản hơn để có thể cùng thảo luận và cải tiến. Kết quả là cách “cải tiến dần dần” truyền thống để mài giũa một PR đến chất lượng cuối cùng có cảm giác không còn hoạt động hiệu quả nữa. Khi đưa feedback, họ có thể đề xuất hẳn một hướng tiếp cận mới thay vì sửa PR gốc — và thường lại tạo ra một loạt vấn đề mới khác. Vì vậy rốt cuộc senior lại phải dành nhiều thời gian hơn junior cho chính PR đó. Phía junior có thể cảm thấy mình rất năng suất, nhưng cũng xuất hiện hiện tượng feedback của reviewer senior ngày càng bớt ấm áp hay khích lệ như trước. Cuối cùng, điều tỏ ra hiệu quả nhất là bắt buộc phải có rất nhiều test case, nhưng ngay cả các test này cũng đang chạm tới giới hạn vì những vấn đề tương tự
Khi nhìn thấy kiểu code “trông như hoàn chỉnh nhưng hoàn toàn không hoạt động” này, tôi lại nhớ đến một dự án phát triển phần mềm offshore trị giá 250.000 USD mà tôi từng trải qua. Chỉ nhìn vào bản đặc tả thì mọi thứ có vẻ đều đúng, nhưng thực tế đó là một hệ thống hoàn toàn thiếu nhất quán. Họ chỉ bám vào cách diễn giải đặc tả mà bỏ lỡ những điều hợp lý theo lẽ thường, và cuối cùng chúng tôi phải loại bỏ toàn bộ dự án ngay lập tức. Điều gây ấn tượng với tôi là giờ những chuyện như vậy đang được LLM tự động hóa và biến thành miễn phí
Tôi hoàn toàn đồng cảm với vấn đề này. Theo kinh nghiệm cá nhân của tôi, dùng LLM thì đúng là có thể tạo ra hàng nghìn dòng code rất nhanh, nhưng việc thực sự khó là review code, sửa bug, kiểm tra lỗ hổng bảo mật, refactor, loại bỏ code thừa, v.v. Rốt cuộc nhiều khi tự tay code còn năng suất hơn. Cách dùng thực tế nhất với LLM là chỉ dùng cho autocomplete hoặc tạo ra các mảnh nhỏ đơn giản. Nếu junior kẹp thêm LLM vào giữa để rồi tôi còn phải truyền đạt lại một lần nữa thì hiệu quả có vẻ còn thấp hơn. Những người hiện tại cảm thấy mình năng suất hơn nhờ LLM thực ra có thể là vì họ đang bỏ qua hoàn toàn, hoặc không hề quan tâm đến những công việc quan trọng đó. Trên thực tế chỉ có một số ít người quan tâm đến chất lượng sản phẩm là phải gánh khối lượng code khổng lồ. Họ đôi khi còn bị hiểu lầm là người quá khó tính một cách không cần thiết, nhưng thực ra mới là những người hùng thật sự muốn mang đến sản phẩm tốt nhất cho người dùng. Tôi không thấy có giải pháp cải thiện rõ ràng nào, mà ngược lại tình hình có vẻ sẽ còn tệ hơn. Những lập trình viên chỉ được đào tạo bằng LLM sẽ tiếp tục đổ vào ngành, còn các công ty làm công cụ thì vẫn tiếp tục marketing thổi phồng. Cuối cùng cấu trúc này chỉ khiến gánh nặng duy trì chất lượng ngày càng tăng
Tôi cũng đang trải qua hiện tượng “effort inversion”, nơi senior phải đổ nhiều công sức hơn junior cho một PR. Trong trường hợp của tôi, các tác giả PR dùng AI để viết bài blog hay thông cáo báo chí, và khi tôi là chuyên gia chủ đề nhận kết quả thì thời gian làm việc tăng lên gấp 3, 4 lần chỉ để sửa đủ loại ảo giác AI và lỗi sai. Công việc của họ vốn là để hỗ trợ tôi, nhưng giờ lại thành ra tôi phải hỗ trợ họ. Thậm chí ảo giác AI còn khác nhau mỗi lần nên lần nào cũng phải vật lộn lại từ đầu. Tôi đã báo chuyện này với lãnh đạo rồi, và nếu cứ tiếp diễn thế này thì có lẽ một nửa nhân sự PR sẽ biến mất vào năm sau. Nếu vai trò của họ chỉ là copy email, dán vào ChatGPT rồi gửi lại cho tôi thì tôi hoàn toàn có thể tự làm
Tôi muốn hỏi liệu bạn có thể giải thích kỹ hơn về đoạn “feedback tôi đưa ra trong lúc review đã không được tiếp thu tốt” không. Tôi cũng đang gặp vấn đề tương tự nên nếu có giải pháp hay góc nhìn nào thì mong được chia sẻ
Nói thêm theo suy nghĩ của tôi, thế hệ trước đã tự nhiên tích lũy được sự hiểu biết sâu về cấu trúc và thiết kế phần mềm thông qua refactor hoặc unit test. Nhưng nếu về sau LLM còn tạo cả unit test, lập trình viên có thể mất cơ hội tự phản tư và học hỏi như kiểu “mình đang cần gì?”, “có cách nào đơn giản hơn không?”. Theo tôi, khác biệt giữa “developer”, “engineer” và “architect” chính là ở đây. LLM hay “vibe coding” không bao giờ nuôi dưỡng được kiểu mindset đó. Với những ngôn ngữ ít gánh nặng cú pháp như Go, các sai lầm thiết kế kiểu này lộ ra dễ hơn trong review. Cấu trúc unit test của Go cũng hữu ích để chẩn đoán độ phức tạp của code. Cuối cùng chúng ta cần những phương pháp test/review tốt hơn. Chỉ fuzz testing, unit test và integration test thôi là chưa đủ. Tôi nghĩ cần có các framework test tự động có thể kiểm tra một cách logic xem các nhánh trong code có thực sự được gọi đúng hay không, và các điều kiện thỏa mãn có thực sự được đáp ứng hay không
Nhờ LLM mà chi phí đưa phần mềm mới vào sử dụng đang tiến gần về 0, nhưng chi phí để hiểu sâu, kiểm thử và tin tưởng phần code đó lại có cảm giác cao hơn bao giờ hết. Tuy nhiên theo kinh nghiệm của tôi, code do LLM tạo ra không hẳn tệ hơn quá nhiều so với vô số đoạn legacy code do người đã nghỉ việc để lại mà chẳng thể hỏi han gì đàng hoàng, hay code trôi nổi trên mạng. Thậm chí LLM còn không ngại viết test như con người, cũng không vì mệt mà làm qua loa. Triết lý của tôi bắt đầu từ tiền đề rằng “mọi đoạn code đều là nợ tiềm ẩn”. Vì vậy tôi không quá lo về mức độ đáng tin của code. Trên thực tế tôi cũng đã xây dựng những codebase khổng lồ bằng AI và làm cho chúng chạy ổn — với điều kiện domain phải có thể kiểm chứng được, đồng thời phải có nhiều test và nhiều vòng lặp. Kết luận là sản xuất code bằng đầu ra của LLM đúng là nhanh hơn, nhưng cảm giác kích thích trí tuệ của việc code đã giảm đi, như thể bộ não của tôi cũng đang lười theo. Ngược lại, chúng ta đang bước vào thời kỳ mà lao động trí óc ở giai đoạn đầu như định nghĩa yêu cầu hay thiết kế trở nên quan trọng hơn nhiều
Ngay cả khi không có LLM thì ngành này vốn đã không thiếu code, mà tốc độ phát triển đã bị giới hạn bởi nhu cầu thị trường và giới hạn vốn. Tooling đã tốt đến mức bản thân việc coding không còn là trọng tâm nữa. Môi trường bây giờ hoàn toàn khác thời kỳ đầu. Tôi nhớ một giai thoại về Bill Gates thời thiếu niên, khi chỉ riêng năng lực “biết code” đã là một tài nguyên hiếm. Một công ty đang rất gấp đã thuê Gates 16 tuổi và Paul Allen, và họ thấy thật kỳ lạ chỉ vì hai người có thể viết code nhanh. Còn bây giờ, câu hỏi quan trọng hơn là “xây cái gì, và liệu ở đó có mô hình kinh doanh hay không?”
Video liên quan
Tôi đồng ý với lập luận rằng coding không phải nút thắt vì nhu cầu thị trường mới là yếu tố quyết định. Trước cơn sốt AI, Marc Andreessen cũng từng nói rằng “vốn thì dư thừa nhưng lại thiếu những ý tưởng đủ tốt để đầu tư”. Tôi không nghĩ câu đó phản ánh hoàn toàn đúng thực tế, nhưng ít nhất xét theo dữ liệu thì phát biểu đó có vẻ đáng tin
Giống như giai thoại cũ về Bill Gates, khả năng viết ra code chất lượng cao và hiểu nó một cách sâu sắc vẫn là một nguồn lực hiếm. Chỉ có điều khác trước là ngành công nghiệp hiện không còn tỏ ra coi trọng năng lực đó nữa
Xét từ góc độ phân tích tác động của AI, chúng ta có xu hướng quá tin vào hiệu suất. Nhưng nền kinh tế thực tế có cấu trúc phức tạp hơn nhiều và nút thắt xuất hiện ở những chỗ khác. Dù sản lượng code tăng gấp 100 lần thì vẫn chưa rõ liệu nó có thực sự hữu ích hay không
Mỗi khi đọc trải nghiệm của ai đó dạo này tôi đều thấy quá u ám. Nếu một junior giao cả một khối code khổng lồ không chạy được, không tự test/xác minh, không tinh gọn, lại chẳng có tài liệu, chú thích hay giải thích nào, thì bản thân điều đó đã có thể được mô tả là “phiên bản LLM được cài trên con người”. Cuối cùng điều quan trọng là tư duy phản biện và ý thức chịu trách nhiệm với kết quả. Thậm chí tôi còn nghĩ LLM có khả năng phản hồi feedback trung thành hơn một junior software engineer truyền thống
Bản thân tôi cũng từng nghĩ viết code là nút thắt, nhưng sau 10 năm tôi nhận ra điều thực sự khó là căn chỉnh công nghệ cho khớp với business. Ngay cả trong môi trường xử lý đống code phức tạp khác nhau theo từng khách hàng như B2B hay SaaS, nếu công nghệ được đặt đúng theo business thì mọi chuyện đều trôi chảy. Giờ đây công nghệ đã đủ phát triển, nên thứ thực sự then chốt là “cái tôi” của developer và thái độ tập trung vào giá trị khách hàng. Cần suy nghĩ về việc khách hàng thực sự muốn gì, họ có trả tiền cho thứ đó không, hay thậm chí có cần giao diện web hay không. Những “tính năng đồ chơi cho mèo” mà developer làm ra để tự thỏa mãn mới là nguyên nhân thực sự làm tăng chi phí cloud. Điều đáng buồn hơn là dù có ném vào đó incentive mạnh tay, stock option hay lương cao thì cũng không giải quyết được vấn đề bản chất này. Cần có ai đó, chỉ cần một người thôi, thực sự có “sứ mệnh” muốn làm phần mềm cho tốt và sẵn sàng giao tiếp trực tiếp với khách hàng để làm cho tử tế
Khoảnh khắc LLM thực sự hữu ích với tôi trong tổ chức lại là ở các dự án cá nhân hay side project. Khi phát triển ứng dụng để giải quyết những vấn đề nhỏ, vì thiếu thời gian nên việc viết code thực sự trở thành nút thắt lớn. Với các dự án như vậy, mức độ tận dụng LLM là 100%
Tôi cũng đồng cảm 100%. Chỉ cần đầu tư 1–2 giờ mỗi ngày vào Claude code, đến cuối tuần là có thể có một kết quả dùng được trong thực tế. Với lượng thời gian đầu tư ngắn, việc kiểm chứng ý tưởng hay thử nghiệm trở nên dễ hơn. Tôi nghĩ các công cụ LLM kiểu này thật sự tạo ra giá trị rất lớn ngay cả trong tổ chức chuyên nghiệp. Các công cụ quản trị hay hệ thống tự động hóa mà bình thường không có thời gian làm giờ cũng có thể được prototype rất nhanh. Nếu đồng nghiệp cần query DB hoặc một đoạn tự động hóa đơn giản, chỉ cần hỏi Claude, review lại rồi dán vào dùng ngay là được. Hỗ trợ để ngay cả người không phải engineer cũng có thể tự xử lý công việc lặp đi lặp lại trong phạm vi của mình chính là mục tiêu của dự án mcp-front[0] của tôi
GitHub mcp-front
Thành thật mà nói, ở giai đoạn sự nghiệp hiện tại của tôi thì rất khó dành nguyên cả tuần cho một việc, và nhờ kinh nghiệm lâu năm nên tôi luôn phải cân nhắc cả các yêu cầu phi chức năng lẫn góc nhìn dài hạn. Dù có bỏ qua mấy thứ như test thì rốt cuộc vẫn còn quá nhiều điều phải tiếp tục suy nghĩ
Tôi nhớ đến câu nói nổi tiếng của Robert C. Martin rằng “thời gian đọc code nhiều hơn thời gian viết code ít nhất 10 lần”
Trích dẫn liên quan
Đáng tiếc là phong cách clean code của ông ấy trong thực tế đôi khi lại làm bối cảnh bị phân mảnh, khiến ý đồ còn khó nắm bắt hơn
Tệ hơn nữa là có khi thời gian viết thì giảm nhưng thời gian đọc lại tăng, nên tổng khối lượng công việc chưa chắc đã giảm
Tôi muốn giới thiệu bài viết ngày 2 tháng 10 năm 2000 của Joel Spolsky mà chưa ai nhắc tới
Joel on Software: Painless Functional Specifications (2000)
Nút thắt thật sự không phải là code mà là đặc tả chức năng (spec). Công việc quan trọng hơn là tạo ra một bản đặc tả rõ ràng về cách phần mềm phải hoạt động, bằng tiếng Anh, sơ đồ, user story, v.v. Nếu spec được xác định tốt, LLM cũng có thể tạo ra cả solution, test và integration test rất tốt trong một lần. Nếu quá lớn thì spec không nên được quản lý như một file markdown duy nhất, mà nên được tách theo từng tính năng như wiki để quản lý bằng liên kết và tham chiếu. Năng lực cạnh tranh thực sự không nằm ở độ khó triển khai, mà ở mức độ công sức đã bỏ vào đặc tả
Người viết không đồng ý với quan điểm của tác giả. Có thể với doanh nghiệp lớn thì code không phải là nút thắt, nhưng với startup, khi nguồn lực có hạn thì việc lập kế hoạch hiệu quả quan trọng hơn. Nói cách khác, cũng có nhiều trường hợp mà chính việc tạo ra đoạn code thực sự chạy đúng mới là nút thắt lớn nhất. Cuối cùng, trong những thảo luận như thế này không thể khái quát hóa rằng “AI/LLM hữu ích đến mức nào”. Với đội này thì code là nút thắt, với đội khác thì không
Ai cũng biết code do LLM tạo ra nhiều khi rất tệ và thậm chí không thể review nổi. Khi code LLM do junior nộp lên có vấn đề và bị hỏi lý do thì chính họ cũng không biết, chỉ trả lời rằng LLM đã tạo ra nó. Cuối cùng xu hướng này chỉ làm tăng “nhiễu” và “overhead” trong bảo trì code. Nếu không thể tránh việc áp dụng LLM thì có lẽ cũng đành phải giao cả review và bảo trì cho LLM. Dĩ nhiên kết quả sẽ là một mớ spaghetti còn phức tạp hơn. Nhưng thực tế là trong phần lớn doanh nghiệp, chất lượng thường không thật sự quan trọng đến mức đó, và nếu code do LLM tạo ra chạy tạm ổn thì vậy là đủ. Hoặc chỉ cần tiếp tục chồng thêm LLM vào đến khi giải quyết được ở mức cần thiết thì cũng đã được xem là chấp nhận được