7 điểm bởi GN⁺ 2025-08-01 | 2 bình luận | Chia sẻ qua WhatsApp
  • Gần đây, trong đội, có thể dễ dàng nhận ra mã do LLM tạo ra
  • Những mã như vậy dù rõ ràng và kiểm thử tốt nhưng không tuân thủ quy ước riêng của dự án
  • Bỏ qua nhiều mẫu hoặc thư viện có sẵn và tự triển khai theo cách mới
  • Mối lo ngại về xu hướng trong phát triển phần mềm chỉ chạy theo tốc độ đang ngày càng tăng
  • Cuối cùng, điều quan trọng là chất lượng và tính nhất quán, cùng khả năng bảo trì

Dấu hiệu của vibe coding

  • Một số đoạn mã do đồng đội viết gần đây trông rõ ràng và hoàn chỉnh về chức năng, nhưng có thể nhận ra ngay là do LLM tạo ra vì không tuân theo quy ước riêng của dự án
  • Chẳng hạn, dù dự án đã có sẵn thư viện lấy dữ liệu, họ vẫn tự viết phần triển khai yêu cầu HTTP xử lý toàn bộ các trường hợp ngoại lệ
  • Liên tục tạo lại các hàm tiện ích của module đã có rồi, hoặc dù đã có cơ chế thay đổi cài đặt theo module vẫn thay đổi sang cài đặt toàn cục
  • Mặc dù văn hóa viết code theo phong cách hàm đã hình thành, họ vẫn lại viết code mới theo cách dựa trên lớp
  • Đây là phong cách code mà con người vài năm trước đã không bao giờ viết

Tầm quan trọng của bảo trì và nguyên tắc phần mềm

  • Trong phát triển phần mềm, chúng ta đã đầu tư nhiều công sức để xây dựng mẫu và chuẩn có thể duy trì trong thời gian dài
  • Thực ra, bất kỳ ai cũng có thể viết mã chỉ cần chạy được, nhưng đó mới là thách thức thật sự khi có một codebase dễ quản lý và chỉnh sửa lâu dài
  • Vấn đề không phải là bản thân việc triển khai tính năng, mà là một codebase có thể duy trì theo thời gian
  • “Vibe coding” có thể làm xói mòn những triết lý và tiêu chuẩn như vậy

Có nên xem tốc độ là ưu tiên hàng đầu?

  • So sánh với cảnh một nhân viên barista mới ở quán cà phê làm vội đến mức làm đổ cà phê, bài viết nhấn mạnh ám ảnh về tốc độ không mang lại kết quả đúng
  • Các đội phát triển ngày nay cũng tương tự: chạy quá nhanh để tạo phần mềm mới khiến chất lượng giảm sút
  • Điều mọi người thực sự muốn là một kết quả đúng đắn, dù có phải đợi thêm một chút
  • Tôi từng nghĩ việc chỉ chạy theo tốc độ vốn là chuyện của các nghề không phải phát triển, nhưng giờ lại thất vọng khi thấy cả đồng nghiệp phát triển cũng bỏ nguyên tắc để chỉ theo đuổi tốc độ

Điều thực sự cần

  • Cách bạn đưa mã vào IDE như thế nào không quan trọng
  • Điều quan trọng là thái độ của lập trình viên khi chú tâm đến chất lượng
  • Tác giả công nhận LLM là đổi mới kỹ thuật lớn, nhưng vẫn nhấn mạnh trách nhiệm tạo phần mềm thực tế vẫn thuộc về lập trình viên
  • Khuyến khích nắm vững và áp dụng các nguyên tắc sẵn có như “viết prompt tốt hơn”, “chỉ định đúng thư viện”, “cung cấp ví dụ”, “làm việc theo từng tệp nhỏ”
  • Nhắc nhở đừng giao chất lượng mã và khả năng bảo trì cho riêng ‘trọng số’ của mô hình

2 bình luận

 
GN⁺ 2025-08-01
Ý kiến trên Hacker News
  • Tôi muốn được làm ở một đội mà không ai đi viết lại phần fetch HTTP nếu thư viện fetch dữ liệu đã có trong dự án đã bao phủ mọi trường hợp ngoại lệ, không ai làm lại khi đã có sẵn module hàm tiện ích, không ai sửa cấu hình toàn cục từ từng module riêng lẻ khi điều đó có thể làm được, và cũng không ai tự tạo class mới trong khi nhóm chủ yếu dùng phong cách hàm. Nhưng ngoài thực tế, rất nhiều lập trình viên lại thường xuyên lặp lại những việc như vậy.

    • Thành thật mà nói, trong các dự án lớn, nếu tài liệu kém thì những chuyện như trên xảy ra rất dễ. Tài liệu mã nguồn ở dự án nghiên cứu học thuật nơi tôi làm việc gần như chỉ nói rằng bản thân code đã đủ tự mô tả, rồi nhắc ngắn gọn về cấu hình CMake, cách build và benchmark. Những quy tắc hay tập quán nội bộ thì phải tự va chạm mới biết. Người mới vào thường xuyên làm lại những thứ đã có hoặc thay đổi cấu hình toàn cục. Cuối cùng, cách tốt nhất là lập chỉ mục codebase rồi hỏi trực tiếp LLM (vì những người chủ chốt của dự án либо đã rời đi, либо rất lâu sau mới trả lời).

    • Tôi nghĩ bạn đang bỏ lỡ ý chính của tác giả. Nếu tốc độ là đức tính tối thượng, thì những chuyện đó sẽ tiếp tục lặp lại. Nếu tốc độ là giá trị tuyệt đối, thì sản lượng phải tăng theo cấp số nhân mới bù nổi nợ kỹ thuật. Nếu còn các yếu tố khác cũng quan trọng, thì phải quản lý và trả nợ một cách khôn ngoan. Nhưng dạo này cảm giác như mọi người chỉ ôm một đống nợ rồi hy vọng somehow mọi thứ sẽ ổn, và rất nhiều người thật sự không giỏi quản lý nợ.

    • Nhiều người cứ có dịp là lại phát minh lại bánh xe, bỏ qua các quy ước có thể đoán trước hoặc dùng các pattern pha tạp. Tác giả có thể gọi đó là "vibe coding", nhưng thật ra đây không phải vấn đề riêng của LLM; ai vội vàng chỉ muốn ra kết quả hoặc thiếu kinh nghiệm thì đều dễ rơi vào như vậy. Cụm "đoạn code mà không ai trong team sẽ viết như thế" nghe giống một lời phàn nàn nhắm vào ai đó cụ thể. Cần cẩn trọng khi áp góc nhìn đó sang nơi khác.

    • Tôi cũng từng thấy lập trình viên thêm một thư viện ORM nữa, dù ORM đầu tiên đã đủ dùng, chỉ vì cái mới "đang hot". Dù là lập trình viên hay LLM thì đều có thiên kiến riêng. Việc nắm rõ quy tắc và pattern trong dự án rồi làm việc trong khuôn khổ đó là cực kỳ quan trọng. Tự làm theo kiểu của mình mà không xét đến ngữ cảnh là rất nguy hiểm. Với con người, có thể xử lý bằng văn hóa code review và khuyến khích đọc code; còn với LLM thì phải hướng dẫn rõ mọi pattern và quy tắc. Nếu không, nguy cơ tạo ra code lệch khỏi dự án là rất cao. Điều quan trọng là phải đặt ra một cách tường minh các giá trị và tiêu chí rõ ràng.

    • Tôi từng có trải nghiệm làm ở một team tốt như thế. Có nhiều dự án nhỏ (2-4 người) nhưng mức độ quan trọng cao. Trong môi trường đó, việc hình thành văn hóa phát triển cân bằng giữa chất lượng và tốc độ, cũng như đạt được đồng thuận, khá dễ. Ở những team như vậy, dù là người hay LLM thì cũng tuyệt đối không ai duyệt PR cho loại code như trên.

  • Cá nhân tôi xem LLM như một lập trình viên rất junior: muốn làm tốt việc, biết nghe chỉ dẫn, nhưng hiểu codebase và pattern còn kém. Bạn phải dẫn nó qua toàn bộ quá trình, giải thích cả những lỗi tiềm ẩn, giao việc thật cụ thể và nhỏ, rồi review code rất kỹ. Tôi cũng giống vậy: trước tiên hình dung mô hình dữ liệu trong đầu rồi mới bắt tay vào code. Mô tả cụ thể là rất quan trọng. Có một luật bất thành văn của tôi là luôn đặt block comment ở đầu file để giải thích file đó chứa gì. Nó đóng vai trò như prompt thứ hai khi phiên làm việc khởi động lại. Cách này vận hành khá ổn mà không tạo cảm giác "ma thuật", nhưng giữa chừng vẫn phải dành khoảng 30% thời gian để dọn code, đổi tên và refactor thì mới nhìn cho ra hồn. Dù vậy, có LLM vẫn nhanh hơn rất nhiều so với việc viết hoàn toàn bằng tay.

    • Cách gọi như "lập trình viên junior" hay "copilot" đôi khi không phản ánh đúng cả ưu lẫn nhược của LLM. Không giống con người bình thường, nó rất dễ quên và đôi khi phạm những lỗi hết sức cơ bản, nhưng cũng có những phần nó làm tốt hơn tôi (ví dụ như lỗi off-by-one liên quan đến mảng). Và nó biết gần như mọi thứ trên internet theo kiểu bách khoa. Sau khi dùng thật, tôi thấy LLM khá giống chó săn: người chủ phải dẫn dắt cuộc săn và tự mình kết thúc nó.

    • Khác biệt giữa LLM và lập trình viên junior nằm ở khả năng học. Junior có thể dần dần học hỏi và trưởng thành, còn LLM thì không. Càng nhét nhiều chỉ dẫn vào prompt, nó càng dễ quên nhiều hơn và quay về các câu trả lời chung chung. Mỗi khi bắt đầu prompt mới, bạn lại phải hướng dẫn từ đầu.

    • Tôi thấy LLM không khác nhiều so với việc lên internet tìm code rồi copy-paste. Cuối cùng, lập trình viên vẫn phải tự kiểm tra để chắc rằng code chạy đúng. Gần đây vì vấn đề mắt nên tôi phải làm việc theo chu kỳ 20 phút rồi nghỉ, vì vậy hiệu quả càng quan trọng hơn. LLM tạo code nhanh hơn con người rất nhiều, nên chỉ cần để nó xử lý phần cơ bản đã là một lợi thế lớn. Hiện tôi đang tạo struct cho SIMD bằng Unity C# và LINQ; chỉ cần nói cho LLM điều kiện mong muốn, tôi nhận được code hoặc chuỗi cần thiết nhanh hơn nhiều so với tự đi copy-paste. Cảm giác dùng AI như một HUD là rất rõ. Tôi cần một công cụ hỗ trợ phát triển mạnh ở cấp độ nhỏ, hơn là AI làm cả chương trình.

    • Với tôi, LLM là một lựa chọn thay thế StackOverflow tốt hơn hẳn. Tôi hỏi ngay điều mình thắc mắc và nó trả lời khá chính xác. Tôi có thể dựa vào câu trả lời để viết lại vào code của mình hoặc chỉ tạo ra một hàm. Trước khi sao chép, tôi luôn cố hiểu hoàn toàn đoạn code đó. Đôi khi tôi cũng từng nghĩ liệu việc ném một PR 400 nghìn dòng vào một dự án mã nguồn mở bằng ngôn ngữ mà mình không thật sự rành có mang lại lợi ích sự nghiệp hơn so với làm việc trung thực và đặt chất lượng lên trước hay không. Thực tế là số năm kinh nghiệm thường được đánh giá quan trọng hơn kỹ năng.

    • Để giao việc thành công cho LLM, tôi thấy tốt nhất là chỉ giới hạn nó ở giai đoạn coding thực tế, chứ không phải phần suy nghĩ. Cần chia nhỏ task và mô tả càng chi tiết càng tốt: đặc tả cụ thể, file cần sửa, vị trí ví dụ tham chiếu, v.v. Không cần đến mức vi mô, nhưng càng nhiều manh mối thì xác suất thành công càng cao. Với code được tạo ra, tôi vẫn tự kiểm từng mảng bằng git add -p. Có tốn thời gian chuẩn bị và rà soát, nhưng chắc chắn vẫn tiết kiệm thời gian và năng lượng hơn là tự viết hết hoặc để nguyên đống code cẩu thả.

  • Rủi ro lớn nhất của vibe coding là với lập trình viên giỏi thì nó chỉ giúp nhanh hơn đôi chút, nhưng với người yếu tay nghề thì nó cho phép tạo ra rất nhiều code tệ với tốc độ nhanh hơn nhiều. Vấn đề là những lập trình viên đó có thể tiến bộ nhờ vibe coding hay chỉ đơn giản là mắc kẹt ở đó.

    • Theo kinh nghiệm của tôi, ngay cả lập trình viên mediocore (mức trung bình) cũng có thể trở thành lập trình viên tệ rất nhanh. Lý do là sự tự tin sai chỗ và sản lượng code tăng đột biến. Code do AI tạo ra gần như không cân nhắc kiến trúc tổng thể, luồng thông tin hay nguyên tắc trách nhiệm đơn nhất. Nó thường được cấu trúc theo kiểu trả về placeholder thay vì ném exception để tạo cảm giác an toàn. Khi đó, code gọi hàm phải liên tục kiểm tra xem kết quả có phải placeholder hay không. Ngay từ đầu, nếu tham số đầu vào không tốt thì AI còn tự ý "sửa" luôn, bỏ qua cấu trúc gather_parameters → call → process_results. Và đến phần test thì vấn đề còn phình to hơn nữa.

    • Giờ đây nhiều lập trình viên sẽ tái khám phá khái niệm net-negative programmer (một lập trình viên mà sự hiện diện của họ làm giảm chất lượng dự án).

  • Theo tôi, thứ thiếu nhất ở đây là sự quan tâm. Vibe coding tự nó không phải nguyên nhân tạo ra sự thiếu quan tâm; AI chỉ là công cụ. Mọi vấn đề tác giả nêu ra đều áp dụng tương tự với lập trình viên junior là con người, và có thể cải thiện bằng cách hướng dẫn hoặc giao tiếp tốt hơn. Tôi không nghĩ AI làm giảm sự quan tâm đến chất lượng (ai vốn không quan tâm thì trước đây cũng đã thế rồi). Người ta hay phản biện rằng nó "làm mất cơ hội đào tạo junior", nhưng nhiều nơi thực sự không có đủ dư địa nên phải dùng AI như giải pháp tạm thời (startup của tôi khó tuyển người cũng vậy). Các công cụ AI có thể làm thay đổi tiêu chuẩn chất lượng phần mềm, và tôi nghĩ chỗ này sẽ còn thay đổi nhiều trong tương lai.

  • LLM không chỉ nên dùng trạng thái hiện tại mà còn phải tận dụng cả lịch sử commit làm ngữ cảnh. Nhiều codebase đang dần migrate từ pattern A sang B, nên có nhiều pattern cùng tồn tại. Việc migration không thể diễn ra một lần là xong, nên cái cũ và cái mới thường lẫn lộn trong thời gian dài. Như ví dụ HTTP, ngay cả khi LLM nhận ra pattern, chuyện nó sẽ theo cái nào vẫn khá hên xui.

    • Tôi từng làm ở một codebase lớn đã trải qua hơn 20 năm sáp nhập, đổi tên và thâu tóm. Vẫn còn những ví dụ gọi API từ rất lâu trước đây, trong khi thật ra có code mới hơn riêng biệt tồn tại song song, nhưng nhiều thứ vẫn được giữ lại cho khách hàng cụ thể. Cũng có nhiều API na ná nhau mà hoàn toàn không có tài liệu, nên phải tự lần mò xem dùng cái nào thì mới lấy được dữ liệu mình muốn.

    • Một cách là dùng file như CLAUDE.md để chỉ dẫn rõ ràng kiểu "hãy theo pattern này, tránh pattern kia".

    • Nhưng có lẽ hiệu quả hơn là chỉ thật cụ thể cách làm việc cho từng phần và đưa ví dụ rõ ràng.

    • Vấn đề là chính người làm vibe coding thường cũng thiếu năng lực nhận biết ngữ cảnh như vậy. Nhiều người vốn đã thiếu kinh nghiệm lập trình từ trước thời LLM.

    • Điều đó chỉ khả thi khi commit message được viết tử tế. Thực tế thì phần lớn chỉ là kiểu "sửa file này", "sửa bug".

  • Khi dùng LLM, các công cụ tự động như linter, formatter, kiểm tra kiểu chặt chẽ rất hữu ích. Đặc biệt khi có đóng góp code từ người không biết code style hay các quy tắc ngầm (hoặc từ LLM agent), ta có thể kiểm tra code theo cách tự động và sửa ngay những gì sửa được. Test cũng tương tự. Một hệ thống xác minh tự động rất hữu dụng để giữ chất lượng, dù là con người hay agent.

    • Tôi nghĩ trên thực tế các công cụ đó không ngăn được phần lớn các trường hợp vibe coding mà bài viết đề cập.

    • Những công cụ đó đôi khi chỉ làm bề mặt trông sạch sẽ hơn trong khi che đi vấn đề thực sự.

  • Tất cả các AI assistant lớn hiện nay đều đã tích hợp sẵn cách giảm nhẹ những vấn đề này, như /init của Claude Code hay /Generate Cursor Rules của Cursor, có thể áp dụng ở phạm vi toàn tổ chức theo cách tự động hơn thay vì chỉ context engineering đơn thuần. Xét cho cùng, việc các công cụ này chia tách cộng đồng phát triển như thế nào cũng là một chủ đề thú vị.

    • Nhưng trên thực tế, dù có quy định rõ trong CLAUDE.md đến đâu thì CC (Claude Code) vẫn thường bỏ qua. Càng trò chuyện lâu càng có cảm giác nó lặp lại cùng một vấn đề, và đến giờ tôi vẫn chưa tìm ra giải pháp nào thật sự thỏa đáng. Vì vậy tôi không nghĩ nên gạt bài viết này đi như một luận điệu chống AI đơn giản.

    • Tôi đang đánh giá lại Cursor. Lý do nó không đạt tốc độ như kỳ vọng không chỉ vì các lỗi lặt vặt (như LM đổi : thành ,) mà còn vì codebase quá lớn, quá cũ và chất lượng quá không đồng đều. LLM rốt cuộc sẽ hay bắt chước các pattern phổ biến nhất (= tệ nhất). Ngay cả khi chỉ rõ "hãy tham khảo phần này", nó vẫn bị ảnh hưởng bởi toàn bộ codebase. Dùng rule cũng có vẻ không khác mấy so với nhét thẳng vào prompt. Tôi tự hỏi có giải pháp nào cho chuyện này không.

    • Cốt lõi vấn đề không phải công cụ mà là kiểu "coder" coi trọng vibe, vừa thiếu quan tâm vừa viết code cẩu thả.

  • Theo kinh nghiệm của tôi, gần như mọi vấn đề đều xuất phát từ context window hữu hạn và việc "context engineering" chưa tối ưu. Nếu LLM được cung cấp đúng các ngữ cảnh quan trọng như hàm toàn cục, nó tận dụng tương đối tốt. Vấn đề là làm sao duy trì và cung cấp được ngữ cảnh nào một cách liên tục, không đứt đoạn. Tôi kỳ vọng tương lai sẽ có nhiều tiến bộ ở điểm này, chẳng hạn dưới dạng sub-agent.

    • Bạn nói rằng "nếu agent biết mô tả các hàm toàn cục thì nó dùng khá tốt", nhưng thật ra không có cái gì gọi là "agent" cả; nó chỉ là một hàm toán học nối đầu vào với đầu ra. So sánh LLM với con người là không chính xác. Con người và máy móc hoàn toàn khác nhau.
  • Tôi nghĩ tất cả những điều này đều đúng. Cách tốt nhất để dùng LLM là xem nó như thứ cung cấp một mức trừu tượng cao hơn assembly, giống như compiler vậy: nếu mô tả rõ yêu cầu cùng đầu vào/đầu ra, nó sẽ tạo code như một phép dịch logic. Vì vậy cần giảm tối đa sự nhiễu (entropy) ở đầu vào. Về bản chất, LLM là một translation engine. Dùng nó cho "dịch" thay vì "sinh" sẽ hiệu quả hơn. Dù vậy, định kỳ vẫn xuất hiện những model thông minh và trực quan hơn, nên kết quả ngày càng tốt hơn mà không cần phải chăm sóc quá nhiều. Rồi sẽ đến lúc LLM làm tốt hơn con người ở bất kỳ task nào của lập trình viên, và các vai trò khác của con người cũng vậy.

    • Đây là một phép so sánh sai. LLM không phải công cụ "biên dịch" ngôn ngữ tự nhiên thành mã cấp cao. Ngôn ngữ lập trình và mã máy đòi hỏi hệ ngữ nghĩa rõ ràng và nhất quán, trong khi ngôn ngữ tự nhiên vốn thuộc một tầng trừu tượng hoàn toàn khác. Cùng một LLM nhưng với seed mới hoặc phiên bản khác có thể cho kết quả khác, còn compiler thì với cùng đầu vào phải luôn cho cùng một đầu ra.

    • Tôi không thể đồng ý rằng LLM là một tầng trừu tượng giống compiler. Trên thực tế, LLM chỉ là một bộ sinh token mang tính ngẫu nhiên. Tôi chưa từng thấy sản phẩm nào làm ra bằng LLM mà thật sự dùng được cho ra hồn. Kiểu lạc quan công nghệ về singularity hay dữ liệu vô hạn đều thiếu cơ sở thực tế. Rốt cuộc, thu thập dữ liệu chất lượng cao là việc cực kỳ tốn kém. Ở thời điểm hiện tại, các dự đoán đầy hy vọng như vậy là vô nghĩa.

  • Tôi hiểu ra điều này còn muộn hơn cả tác giả: "nhiều người muốn cà phê nhanh và rẻ hơn là cà phê ngon". Trong thực tế, đa số coi trọng tốc độ và giá cả hơn là chất lượng.

    • Chỉ cần nhìn vào độ phổ biến của máy pha cà phê Keurig là thấy xu hướng đó.
 
dkmin 2025-08-02

Bài trên HN còn ngọt hơn cả bài gốc