LLM không biết lười — và đó là vấn đề lớn
Khi AI viết code không biết mệt, người không biết lười đúng cách sẽ chìm trong đống rác.
Bụi WireLười biếng là một siêu năng lực
"Lười biếng là đức tính quan trọng nhất của lập trình viên." — Larry Wall nói câu này mấy chục năm trước, và bây giờ nó đúng hơn bao giờ hết. Nhưng khoan — không phải kiểu lười nằm dài xem TikTok. Đây là kiểu lười khiến bạn ngồi 2 tiếng nghĩ ra cách tự động hóa một việc tốn 10 phút mỗi ngày. Kiểu lười mà vì không muốn maintain 500 dòng code thừa, bạn viết 50 dòng abstraction gọn gàng.
Bryan Cantrill vừa chỉ ra một nghịch lý đáng suy nghĩ: LLM — công cụ mạnh nhất hiện tại để viết code — lại hoàn toàn thiếu đức tính này. Với LLM, "work costs nothing." Nó không bao giờ dừng lại tự hỏi "có cách nào ngắn hơn không?" Nó cứ thêm, thêm, và thêm — tạo ra cái mà Cantrill gọi là "layercake of garbage." Còn con người? Chính vì thời gian có hạn, chính vì lười maintain đống code cồng kềnh, mà chúng ta buộc phải nghĩ ra những abstraction sắc bén. Sự lười biếng đó là động lực tiến hóa của phần mềm.
Con đường cao tốc 12 làn dẫn vào ngõ cụt
Hình dung thế này: bạn cần đi từ nhà đến quán cà phê cách 2km. Một người bạn biết lười đúng cách sẽ chỉ bạn đường tắt qua hẻm — 5 phút là tới. Nhưng LLM thì khác — nó vẽ cho bạn con đường cao tốc 12 làn, xây thêm 3 cây cầu vượt, lắp đèn LED dọc hai bên, rồi… dẫn bạn đến đúng quán cà phê đó. Ấn tượng trên bản vẽ. Nhưng maintain mấy cây cầu kia ai lo?
Ví dụ cụ thể: giả sử team bạn 5 người đang build ứng dụng quản lý nội bộ. Một bạn junior dùng AI generate nguyên module authentication — đầy đủ OAuth, SAML, magic link, biometric. Nghe hoành tráng. Nhưng thực tế công ty chỉ cần đăng nhập bằng Google Workspace. Bốn kiểu auth còn lại trở thành code chết, nằm đó chiếm chỗ, tạo thêm attack surface, và mỗi lần upgrade dependency là một đống warning bay vào mặt.
Nói đơn giản thì: LLM không biết đau khi maintain code dở. Bạn mới là người đau.
20 — 60 — 20: Bạn đứng đâu trên sân?
Steve Yegge vừa chia sẻ một quan sát chua chát: dù ở Google hay ở John Deere (đúng, hãng máy kéo), tỷ lệ adoption AI trong engineering gần như giống nhau. Khoảng 20% là power user dùng agentic workflow xịn sò. 20% từ chối hoàn toàn. Và 60% ở giữa — dùng chat tool kiểu hỏi-đáp, generate code rồi paste vào.
Nhóm 60% này mới là chỗ nguy hiểm. Nhóm từ chối ít nhất không tạo thêm rác. Nhóm power user đã xây workflow review chặt chẽ. Nhưng 60% ở giữa — họ dùng AI đủ nhiều để generate hàng trăm dòng mỗi ngày, nhưng chưa đủ quy trình để phân biệt dòng nào cần giữ, dòng nào nên xóa. Giống đội bóng mà hơn nửa đội chạy rất hăng nhưng không ai nhìn bảng chiến thuật — tốn sức mà bóng vẫn không vào lưới.
Ví dụ thực tế khác: mình từng thấy một repo nội bộ mà mỗi lần merge PR có AI-generated code, diff lớn gấp 3 lần so với cùng feature viết tay. Không phải vì feature phức tạp hơn — mà vì LLM thêm error handling cho trường hợp không bao giờ xảy ra trong context đó, tạo utility function chẳng ai gọi lần thứ hai, viết comment giải thích điều đã quá hiển nhiên.
Cái bẫy vanity metrics — số đẹp, hệ thống rệu
Đây là chỗ nhiều team sập bẫy mà không hay. Dashboard sáng rực: số PR tăng vọt, lines of code tăng, code coverage xanh lè. Manager nhìn vào — tuyệt vời, team productive quá! Nhưng thực tế:
- PR nhiều hơn vì mỗi thay đổi nhỏ giờ kéo theo diff khổng lồ
- LOC tăng vì LLM không bao giờ tự hỏi "xóa bớt gì đi được không"
- Coverage cao vì AI generate test cho cả code không đáng test
Cantrill gọi đây là "perverse vanity metrics" — con số bóng bẩy nhưng phản ánh sai hoàn toàn sức khỏe thật của codebase. Hiểu nôm na: xe phình to bằng xe bus nhưng tốc độ thua xe đạp.
Thử ngay chiều nay: "Lazy Review" trong 30 phút
Bạn không cần đảo lộn cả quy trình. Thử một bước nhỏ:
- Chọn 1 PR gần nhất có code AI-generated trong team
- Hỏi ngược chính AI: "Đoạn code này có thể rút gọn bao nhiêu mà vẫn giữ đúng chức năng?" — Bạn sẽ bất ngờ khi chính nó thừa nhận đã viết thừa
- Áp dụng 3 câu hỏi cho mỗi function được generate:
- Function này có chỗ nào gọi chưa?
- Edge case này có thật sự xảy ra trong context dự án mình?
- Xóa đoạn này thì test nào fail?
- Theo dõi "deletion ratio": mỗi PR, ghi lại bao nhiêu dòng AI generate vs bao nhiêu dòng bạn cắt sau review. Đặt mục tiêu: cắt ít nhất 30%.
Nếu team dùng GitHub Copilot hay Cursor, hãy thử thiết lập convention: mỗi PR kèm AI-generated code phải có "pruning note" — ghi rõ đã xóa hay refactor gì và lý do. Chỉ một dòng ngắn trong PR description là đủ thay đổi mindset cả team.
Để AI viết nháp — nhưng bạn phải cầm kéo
Mình không nói AI viết code dở. AI viết rất nhanh, rất đầy đủ — đầy đủ đến mức thừa. Vấn đề không nằm ở tool, mà ở workflow quanh tool đó.
Nếu quy trình review hiện tại chỉ kiểm tra "code có chạy không" mà bỏ qua "code có cần thiết không" — bạn đang để LLM lái xe mà không ai đạp phanh.
Vài công cụ open-source giúp giữ codebase gọn:
- SonarQube (Community Edition miễn phí) — detect dead code, code smell tự động
- Semgrep — viết custom rule cho team, ví dụ: flag function chưa được gọi ở đâu
- git-sizer — theo dõi repo có phình bất thường không qua từng commit
Bản chất thật sự: hãy để AI viết bản nháp, nhưng bạn phải là biên tập viên. Và biên tập viên giỏi là người biết cắt — không phải người biết thêm.
---
Bụi Wire — nghiện đọc release notes lúc 2 giờ sáng