Dùng AI để viết mã tốt hơn theo cách chậm rãi hơn
(nolanlawson.com)- Lập trình với AI không chỉ có thể được dùng để nhanh chóng tạo ra số lượng lớn mã chất lượng thấp, mà còn có thể được tận dụng để rà soát PR thật kỹ nhằm tạo ra mã chất lượng cao một cách chậm rãi hơn
- Tác nhân LLM rất mạnh trong việc phát hiện bug trong codebase, nhưng khó khăn thực sự nằm ở việc ưu tiên và kiểm chứng các mục đã phát hiện
- Một Claude skill dùng nhiều mô hình cùng lúc sẽ dùng Claude sub-agent, Codex và Cursor Bugbot để rà soát PR, rồi tạo báo cáo cuối cùng đã giảm bớt false positive
- Luồng xử lý là lặp đi lặp lại việc sửa các vấn đề critical/high, bỏ qua những mục có lợi ích thấp so với chi phí, và từ bỏ PR nếu có quá nhiều vấn đề nghiêm trọng
- Cách làm này coi trọng sức khỏe của codebase hơn tốc độ, đồng thời củng cố kiểu lập trình cẩn trọng bằng cách hiểu các failure mode và bug hiện hữu
Cách dùng AI coding theo hướng chậm lại
- Quan điểm chỉ xem AI coding là công cụ để nhanh chóng sản xuất hàng loạt mã chất lượng thấp đã đánh giá thấp tính linh hoạt của LLM
- LLM không chỉ hiệu quả trong việc sinh mã nhanh mà còn có thể được dùng hiệu quả để viết mã chất lượng cao hơn theo cách chậm rãi hơn
- Trái ngược với kiểu đổ ra các PR lớn chưa được kiểm chứng như slop cannons, cũng có thể áp dụng cách rà soát PR sâu hơn và kiên trì xác minh các khả năng thất bại
Kiểm chứng và ưu tiên còn quan trọng hơn phát hiện bug
- Mythos cho thấy các tác nhân LLM có thể tìm bug rất giỏi trong codebase
- Các trường hợp khác cũng cho thấy những mô hình không phải Mythos có thể tìm ra nhiều bug trong các codebase chưa được rà soát
- Các mô hình công khai mới nhất của Anthropic và OpenAI có khác biệt về khả năng phát hiện bug tinh vi và tránh false positive, nhưng đều có thể tìm ra đủ nhiều bug
- Khó khăn thực tế không nằm ở bản thân việc tìm bug mà ở xác định mức độ ưu tiên và kiểm chứng
Claude skill rà soát PR bằng nhiều mô hình
- Cách tiếp cận AI code review bằng cách cho nhiều mô hình so sánh và tranh luận tập trung vào việc dùng càng nhiều mô hình khác nhau thì càng giảm khả năng hallucination hoặc báo bug sai
- Claude skill đang được dùng sẽ chạy Claude sub-agent, Codex và Cursor Bugbot để rà soát PR
- Mỗi công cụ sẽ chấm mức độ bug trong PR theo các mức critical/high/medium/low, sau đó tổng hợp kết quả để tạo ra báo cáo cuối cùng đã loại bỏ false positive
- Phạm vi của “bug” có thể được mở rộng theo tiêu chuẩn của dự án
Workflow thực tế và tiêu chí đánh giá
- Cách làm này có thể tìm ra nhiều bug trong PR, đồng thời hạ tỷ lệ false positive xuống gần như bằng 0
- Các vấn đề được phát hiện rất đa dạng, từ bug nghiêm trọng liên quan đến bảo mật và tính đúng đắn, đến vấn đề hiệu năng, cho tới những lỗi mức độ thấp như “comment dễ gây hiểu nhầm”
-
Luồng xử lý điển hình
- Để tác nhân sửa các mục critical và high, nhưng con người sẽ hướng dẫn giải pháp phù hợp
- Lặp lại cho đến khi không còn mục critical/high
- Bỏ qua các vấn đề high/medium có lợi ích thấp so với chi phí sửa
- Một ví dụ điển hình là phải viết 100 dòng code chỉ để sửa một edge case hẹp
- Nếu có quá nhiều vấn đề critical đến mức cho thấy toàn bộ hướng tiếp cận là sai, thì sẽ bỏ PR
Tập trung vào sức khỏe codebase hơn là năng suất
- Kỹ thuật này không nhất thiết giúp tăng tốc độ phát triển
- Trong quá trình review, có thể phát hiện bug tồn tại từ trước cả trước khi PR được tạo, dẫn tới việc viết unit test và sửa các lỗi tinh vi
- Nó gần như đối lập với kiểu phát triển “năng suất gấp 10 lần” thường được liên tưởng đến khi nói về “vibe coding”
- Trong các kiến trúc phức tạp, failure mode còn đáng chú ý hơn cả luồng chạy bình thường, và quá trình hiểu rồi sửa những điểm lỗi đó có thể trở thành cách để làm quen với codebase
- Cách này hữu ích để vừa cải thiện sức khỏe tổng thể của codebase vừa học được những góc ít được biết đến trong hệ thống
Cách thực hành vibe coding chậm rãi
- Nếu là một lập trình viên đang dùng tác nhân để tạo ra các PR dài hàng trăm dòng mà chính mình cũng chưa hiểu hết, bạn có thể thử cách chậm hơn
- Có thể hỏi tác nhân PR đó hoạt động như thế nào và nó có thể thất bại ở đâu
- Nếu cần, có thể yêu cầu nó viết tài liệu Markdown có kèm Mermaid charts
- Có thể dùng skill
/grill-mecủa Matt Pocock cho đến khi hiểu PR từ đầu đến cuối - “Năng suất” tính theo số dòng code có thể sẽ không tăng, và sau khi tiêu tốn nhiều token, bạn vẫn có thể đi đến kết luận rằng kế hoạch ban đầu là sai
- Cách làm này gần với việc tăng cường kiểu lập trình cẩn trọng, có hệ thống và ám ảnh với chất lượng vốn đã được theo đuổi từ trước thời LLM
2 bình luận
Ý kiến trên Hacker News
Làm việc với AI giờ không còn là một quy trình một lần đơn giản nữa mà trở thành một vòng lặp review qua lại dài
Với các tính năng cỡ trung trải trên nhiều khu vực, trước tiên tôi dùng AI để phác thảo thiết kế triển khai rồi xem lại chi tiết, sau đó dùng Claude 4.7 Max, chậm nhưng cho kết quả tốt, để hiện thực hóa
Sau đó tôi review phần triển khai và đưa cho Codex GPT 5.5 xhigh fast review lại thì gần như lúc nào nó cũng tìm ra các điều kiện biên. Tôi để Claude sửa, vì Codex mạnh ở tìm bug và review nhưng hay over-engineer hoặc trộn vào những lối tắt, còn Claude thì viết code trực quan hơn và dễ bảo trì hơn
Tiếp theo tôi cho một instance Claude/Codex mới review lại các thay đổi đã staged, áp dụng phản hồi rồi thêm cả test. Vẫn nhanh hơn tự viết tay, nhưng phần lớn thời gian lại dùng cho review và xử lý điều kiện biên, nên cuối cùng tính năng v1 có cảm giác như một bản triển khai kiểu v3 đã được lặp đi lặp lại nhiều lần
Cảm giác rất hiệu quả, kết quả từ AI cũng tốt, và thường tôi vẫn hiểu được phần code tạo ra. Tranh luận với robot cả ngày về thiết kế và kiến trúc khiến tôi cảm thấy chính chỗ này mới là nơi cuộc cách mạng AI đã biến tôi thành một kỹ sư giỏi hơn
Cách của tôi là chạy 5 vòng nghiên cứu/lập kế hoạch/lập kế hoạch test, và ở mỗi quyết định quan trọng tôi đều tham gia vào vòng lặp. Bắt đầu từ hình khối lớn rồi đi xuống chi tiết; riêng phần lập kế hoạch có thể mất 2~3 ngày thời gian của tôi, còn agent triển khai (Opus 4.7) thì mất nhiều giờ
Việc triển khai được chia thành nhiều bước/nhiều commit, và ở mỗi bước đều có vòng lặp sửa theo review code. Lần review code sâu cuối cùng cũng có thể mất 1~2 giờ; khi mở PR thì Gemini sẽ review, tôi đọc rồi xử lý các nội dung đó
Dự án vẫn mất vài ngày hoặc vài tuần, nhưng vẫn nhanh hơn 5 lần so với tự mình làm hết
Bổ sung: skill đó có ở https://github.com/scosman/vibe-crafting
Có lúc tôi bỏ hẳn thứ AI tạo ra và tự làm luôn. Tôi nghĩ đây là kỹ năng mọi người phải học: đến một thời điểm nào đó phải biết cắt lỗ. Tôi từng thấy đồng nghiệp cãi nhau mãi với LLM để bắt nó làm gì đó, ngay cả với những thay đổi đơn giản
Đổi lại việc canh chừng các AI liên tục để nhanh hơn một chút, chẳng phải là kiến thức và khả năng kiểm soát về những gì AI đã làm sẽ giảm đi sao
Bài viết về việc để các LLM phê bình code review của nhau[1], công cụ magpie[2], và bài gần đây của Cloudflare về stack code review[3] khá thuyết phục
Tôi hoài nghi về AI, nhưng lý do nghiêng về phía “nó có tốt cho thế giới không” hơn là “nó có chạy được không”. Kiểu công việc review này hiếm hoi tạo cảm giác không phải là thuê ngoài tư duy hay làm suy giảm năng lực của người lao động. Nó không gióng lên cùng một hồi chuông cảnh báo như việc để AI viết code, hay để AI tự sửa các vấn đề mà chính AI tìm ra. Dĩ nhiên, các vấn đề môi trường và những lo ngại đạo đức khác vẫn còn rất lớn
Gần đây tôi khá ấn tượng với chất lượng review code của AI, nhưng trải nghiệm phải tương tác riêng với 3 reviewer AI trong GitHub PR thì thật kinh khủng. Tôi muốn có các vòng review thiên về local hơn và hiểu được jj/rebase
Bối cảnh: backend PHP/Laravel khá lớn và frontend Vue
[1]: https://milvus.io/blog/ai-code-review-gets-better-when-model...
[2]: https://github.com/liliu-z/magpie
[3]: https://blog.cloudflare.com/ai-code-review/
Trung bình thì thời gian dùng cho vòng lặp review/sửa với LLM còn lâu hơn tự tay viết code
Một phần vì khi vào guồng tôi viết code rất nhanh, thậm chí có lúc code tuôn ra nhanh hơn cả suy nghĩ. Thêm nữa, code mà LLM đưa ra trong vài lần đầu nhìn chung thật sự khá tệ
Dù vậy, điều thú vị là nếu tự mình xem xét rồi yêu cầu review và chỉnh sửa qua nhiều vòng, thì trung bình kết quả lại có chất lượng cao hơn phần code mà tôi có thể tự viết trong cùng khoảng thời gian. Khi nhìn code của người khác được lặp lại qua nhiều vòng, tôi có cảm giác hiểu mục tiêu mình đang hướng tới một cách tổng thể hơn so với sản phẩm bật ra khi đang ở trạng thái nhập tâm
Bài này không nói về việc dùng AI để viết code mà chỉ nói về code review
Vấn đề tôi gặp với kiểu coding tác tử là khi lập trình, mình đưa ra vô số quyết định kiến trúc vi mô. Gần như chẳng bao giờ có sẵn đặc tả hoàn chỉnh ngay từ đầu; mình vừa viết vừa hình thành đặc tả
Khi dùng Claude Code hay Codex thì quá trình đó biến mất. Claude Code quá háo hức muốn đi đến đích nên trải nghiệm code cùng nó giống như một cơn mộng sốt. Cuối cùng tôi thấy mình kém tự tin hơn về các điều kiện biên hoặc về việc nó có thực sự khớp với mục tiêu kiến trúc/thiết kế của dự án hay không
Hơn nữa, tôi thích lập trình, reverse engineering và những việc tương tự. LLM có thể giải quyết vấn đề hoặc chuyển giao tính năng, nhưng lại có cảm giác như lấy mất niềm vui đó. Tôi đang cố tìm một luồng làm việc có thể dùng một cách tự tin, nhưng lại lo rằng rốt cuộc luồng đó chỉ còn là chat, tìm kiếm, và vai trò rubber duck cho suy nghĩ của tôi mà thôi
Ngược lại, có những công ty đang thúc đẩy việc để tác nhân viết phần lớn mã production bằng cách làm vững chắc pipeline tác nhân tự đánh giá nơi kỹ sư đưa phản hồi của con người vào vòng lặp
CEO của Creao nói rằng vào tháng 1 năm nay họ đã tái kiến trúc toàn bộ hệ thống production chỉ trong 2 tuần. Ông ấy cũng khẳng định rằng các tác nhân đã triển khai quá nhiều tính năng quá nhanh đến mức phải chờ phía phát triển kinh doanh bắt kịp
Tôi tự hỏi nên đánh giá thế nào giữa lựa chọn tăng sản lượng lên gấp 100 lần bằng AI và lựa chọn phát triển tay nghề của chính mình nhờ AI
Trong khi đó, việc AI cải thiện năng suất là có thật. Ví dụ, một tổ chức kỹ thuật của Snowflake đã lần đầu tiên trong lịch sử công ty hoàn thành sớm toàn bộ OKR trong quý 1. Thông thường đạt được 70% OKR đã lên kế hoạch cũng đã được xem là thành tích, nên có thể tưởng tượng áp lực mà các kỹ sư cảm thấy khi chứng kiến kết quả như vậy
Tiêu đề bài này trông như sẽ có chiều sâu hơn, và tôi đã mong đợi có ví dụ mã thực tế
Nhưng nó lại giống các bài viết quan điểm khác. Chỉ ở mức đề xuất những prompt hiệu quả với tác giả, tức là cách bảo AI tìm lỗi, rồi khuyên mọi người cũng làm như vậy
Tôi dùng các công cụ này cả trong công việc lẫn dự án cá nhân nên đã hy vọng được xem và học hỏi, nhưng những bài viết quan điểm không có ví dụ giờ đã quá nhiều
Tác giả có thể viết hoặc ghép nhanh một bộ harness mã cho việc này, nhưng hiện giờ kiểu công cụ hóa đó có vẻ gần với phạm vi của bạn, một người làm thực tế, hơn. Nếu muốn tự động hóa để thử nghiệm, có lẽ tự đặc tả thứ mình muốn còn nhanh hơn là xử lý mã của ông ấy
Trong lúc đọc bài này tôi đang làm một tính năng khá dày, và đã cần lặp lại khá nhiều
Kết quả cuối cùng lại có ít mã hơn rất nhiều so với phần mã ở đoạn giữa. Vì vậy tôi đã tự hỏi liệu AI có thực sự giúp ích không, vì với từng ấy thời gian bỏ vào các vòng lặp thì có lẽ tôi cũng có thể tự viết mã
Nhưng nhờ AI tôi có thể nhanh chóng phác ra 4 biến thể tính năng mà mình không thích, và cũng không thấy tiếc khi loại bỏ chúng nhanh như vậy
Trước đây, trước khi bắt tay triển khai tính năng mới, tôi phải suy nghĩ rất nhiều về kế hoạch, và sự lệch pha với mã hiện có thường chỉ lộ ra sau khi đã viết kha khá phần triển khai. Giờ thì tôi có thể yêu cầu AI lập một kế hoạch triển khai chi tiết và tìm ra những vấn đề lặt vặt như vậy chỉ trong vài giờ, hoặc thậm chí ít hơn
Điều thú vị với tôi trong vài năm qua là theo dõi ranh giới của sự lười khi viết code của bản thân
Với tư cách lập trình viên, tôi ghét mã boilerplate. Tôi ghét cả việc viết lẫn bảo trì nó. Vì thế tôi thường định hình thiết kế và kiến trúc xoay quanh sở thích đó; đôi khi là khôn ngoan, đôi khi thì không. Dù sao đó cũng là sở thích của tôi, và tôi tránh những việc mình thấy khó làm
Vài năm trước, khi LLM bắt đầu có chút hữu ích cho việc lập trình, tôi nhận ra chúng cực kỳ giỏi với boilerplate, và vào khoảng năm 2023 thì gần như chỉ giỏi mỗi việc đó. Điều đó khiến tôi nghĩ về việc trong thiết kế và kiến trúc hệ thống, chúng ta đã ngầm hiểu điểm mạnh điểm yếu của những người cùng làm việc với mình và đã cân nhắc cho họ nhiều đến mức nào
Các mô hình mới nhất có những điểm mạnh và điểm yếu rất khác con người, và việc bố trí chúng là một bài tập thú vị đòi hỏi kiểu kỹ năng kiến trúc và kỹ thuật khác. Tôi thấy vui khi làm việc đó và hy vọng sẽ tiếp tục như vậy
So với việc quăng prompt cho LLM rồi không biết sẽ ra gì, tôi thích nhận đầu ra có tính quyết định từ
django-admin startproject,npm init,meteor createhơn nhiềuTrong hệ sinh thái web đã trưởng thành, boilerplate được giảm xuống mức tối thiểu. Giờ khi đã giao việc này cho LLM, tôi lo rằng nỗ lực phát triển để tạo ra các CLI kiểu
startprojectvà các giá trị mặc định tốt sẽ bị giảm điThích đấy. Tôi cũng dùng cách tiếp cận ralph-loop tương tự
Bắt đầu từ một kế hoạch đã được phê duyệt, chuyển cho bộ điều phối, và nếu đơn giản hóa thì xử lý qua 2 phiên là build và review, với mỗi phiên gắn một mô hình riêng
Điều cản trở tôi khi dùng tác nhân lập trình là phải phụ thuộc vào dịch vụ bên ngoài trả phí
Có mô hình cục bộ nào đủ ổn để dùng cho việc lập trình không?
Cái này cũng có thể hữu ích: https://hnup.date/hn-sota
Các mô hình Qwen là mô hình dùng hằng ngày của tôi trong tuần này
Ý kiến trên Lobste.rs
Ở chỗ làm của tôi, chúng tôi đã từ bỏ giấc mơ dùng AI để đi nhanh hơn. Trong trường hợp của chúng tôi, việc viết code không phải là nút thắt cổ chai
Dù vậy, điều hay ở coding agent là nó giúp tôi làm việc như kiểu một kỹ sư mà tôi luôn muốn trở thành
Ví dụ như dựng một test harness tử tế để có thể đẩy code đi xa thêm một chút, thêm bước CI để xác minh code được tạo ra có khớp với bản gốc hay không, và giám sát việc triển khai thay đổi cho ra hồn
Trước đây, những việc đó là thứ tôi không thể kham nổi trong tiến độ, vì phải đọc manual GitLab CI, học cách khớp điều kiện và hiểu kiểu làm rối rắm của công ty tôi, nhưng giờ thì làm được, và tôi nghĩ đó mới là tương lai
Tôi đã khá thành công khi dùng LLM như một người đồng hành làm spike hiểu API hoặc một cỗ máy refactor cơ học, đặc biệt hiệu quả trong các ngôn ngữ có kiểu mạnh. Nó cũng tốt để viết test, nhưng cần có quy trình nhiều lớp để đảm bảo những bài test đó thực sự có sức ràng buộc
Mutation testing khá hữu ích, và như bài gốc đề xuất, cũng cần nhiều vòng rà soát
Trước đây tôi tiêu cực với LLM hơn nhiều, đến mức nhìn lại thấy gần như phi lý, nhưng phần lớn là vì lượng phần mềm chất lượng thấp mà LLM từng tuôn ra
Khi tự đào sâu vào, tôi nhận ra cách đúng là dùng nó như một công cụ làm prototype bằng bìa carton và một người đánh máy nhanh hơn rất nhiều. Ví dụ, nếu tôi bảo “hãy tìm pattern này trong mọi theorem của project Lean này rồi đổi sang pattern kia, đánh dấu lại những chỗ không chạy ngay được và đưa tôi danh sách còn lại”, thì nó sẽ sửa hơn 100 theorem theo từng chunk trong khoảng thời gian mà tôi còn đang loay hoay thử một hai lần đầu bằng cách trộn vim, sed, awk và mấy mẹo tạm bợ
Với Lean thì đặc biệt tốt vì do đặc tính ngôn ngữ và loại công việc tôi làm, khoảng cách giữa “biên dịch được” và “chạy đúng” là khá hẹp; với Rust tôi cũng có cảm giác tương tự nếu gắn kèm một test suite tốt và mutation testing
Tôi nghĩ cái đuôi dài của các công cụ này không phải là kiểu “bấm nút là ra sản phẩm”, mà là để kỹ sư giỏi chấp nhận chúng, dồn năng lượng vào việc quan trọng, và giao phần lớn việc vặt trước đây cho máy móc
Ví dụ này khá thú vị: hồi còn làm ở một team framework JavaScript, tôi từng tự viết codemod cho các việc như nâng cấp hay migration. Đó là công việc cực nhọc của việc chỉnh AST
Giờ thì tôi nghĩ có thể giao cho LLM và đạt được cỡ 90%
Tôi thích góc nhìn này. Việc công cụ có tính linh hoạt và không nhất thiết phải tạo ra kết quả chất lượng thấp nghe có vẻ hiển nhiên, nhưng cả phe ủng hộ lẫn phe phản đối đều thường bỏ qua góc nhìn đó
Tôi vẫn chưa thử dùng LLM để review code, nhưng chắc nên đưa vào danh sách việc cần làm. Đến giờ tôi chủ yếu dùng nó để lên ý tưởng, hoặc nhờ giúp về SQL hay VimScript, còn code thì tự viết
Một rủi ro là review code cũng là một kỹ năng, nên nếu dựa quá nhiều vào model thì khả năng đó có thể bị mai một. Dù vậy, trong môi trường thương mại, ngay cả review code tốt nhất thường cũng chỉ là sự kết hợp giữa “thời gian hợp lý” và “có tin người này không”, chứ hiếm khi gần với độ chính xác toán học
Với bug phức tạp thì tôi thường vẫn tự suy nghĩ đến cùng, vì 1) ảo giác vẫn còn lẫn vào, và 2) dù sao hiểu hệ thống từ đầu đến cuối vẫn luôn có giá trị
Nói chuyện meta một chút, tôi không hiểu các lá cờ gắn vào bài này. 1 cái off-topic, 3 cái spam, nghe rất lạ
Bài trên cùng ở trang đầu cũng là bài về việc dùng LLM, mà còn là về viết lách nói chung nên có vẻ còn kém liên quan chủ đề hơn bài này vốn tập trung vào code, vậy mà hình như không bị gắn cờ nào
Thấy kiểu góc nhìn này trên Lobsters khá mới mẻ. Tâm lý chống AI một màu ngày càng làm tôi mệt mỏi. Tôi nghĩ ai cũng có thể đồng ý rằng không ai thích kết quả chất lượng thấp
Nhưng những người chọn tẩy chay AI hoàn toàn và giữ thái độ giáo điều sẽ khó chấp nhận tương lai hơn những người chọn cách tiếp cận thực dụng hơn
Ngay từ đầu tôi đã nói AI giống như sự ra đời của dụng cụ điện. Nếu bạn muốn thay lốp bằng cờ lê tay thì cũng được, nhưng khi máy khoan lực xuất hiện, thợ máy đâu có tẩy chay nó. Trong ngữ cảnh bài viết thì đây không phải phép so sánh hoàn hảo nhất, nhưng tôi vẫn nghĩ vậy
Tôi học được nhiều hơn khi dùng AI so với chỉ đọc tài liệu, vì tài liệu không cho phép tôi hỏi thêm khi cần ngữ cảnh, giải thích hay ví dụ. Dĩ nhiên cũng có thể bảo nó “cứ làm gì đó đi, đừng mắc lỗi”, nhưng tôi thích cách tiếp cận chậm hơn để thực sự học
Điều tôi thấy là sự chỉ trích đối với việc dùng LLM để thay đổi hàng triệu dòng code trong một lần rồi triển khai mà không có con người review. Cụ thể là những trường hợp như thread về việc port Bun từ Zig sang Rust
Bài này cũng đang phê phán điều đó