AI giúp code nhanh hơn? Mình vừa mất 6 tiếng debug một dòng code
Câu chuyện thật về việc tin tưởng AI quá mức và cái giá phải trả khi không hiểu code mình đang dùng.
Nguyễn Nhật Long
@nguyennhatlong1303
Mình đã từng nghĩ AI coding assistant là thứ sẽ thay đổi hoàn toàn cách mình làm việc. Và đúng là nó thay đổi thật nhưng không hoàn toàn theo hướng mình kỳ vọng.
Cách đây vài tuần, mình ngồi nhìn chằm chằm vào màn hình lúc 11 giờ đêm, đã uống hết cốc cà phê thứ ba, và vẫn không hiểu tại sao một đoạn code trông hoàn toàn bình thường lại khiến cả cái service của mình sập. Đoạn code đó do AI generate. Mình copy-paste vào mà không đọc kỹ. Và mình đã trả giá bằng 6 tiếng đồng hồ.
Cái bẫy của "nó trông có vẻ đúng"
Vấn đề với AI-generated code không phải là nó sai hoàn toàn mà là nó trông rất đúng. Syntax đẹp, naming convention chuẩn, thậm chí có comment giải thích đàng hoàng. Não mình tự động trust nó vì nó nhìn professional.
Hôm đó mình đang build một cái feature xử lý async job queue. Mình hỏi AI, nó cho ra đoạn code xử lý retry logic kiểu này:
1async function processWithRetry(job, maxRetries = 3) {2 let attempts = 0;3 while (attempts < maxRetries) {4 try {5 await processJob(job);6 return;7 } catch (err) {8 attempts++;9 await sleep(Math.pow(2, attempts) * 1000);10 }11 }12 throw new Error('Max retries exceeded');13}
Nhìn vào thì thấy ngay exponential backoff, clean code, có vẻ ổn. Mình paste vào, chạy test thấy pass, deploy lên staging. Xong.
Rồi production bắt đầu có vấn đề.
6 tiếng để tìm ra một dòng
Log cho thấy một số job bị stuck, không bao giờ được xử lý. Không crash, không throw error rõ ràng chỉ là... biến mất. Mình bắt đầu đào từng layer một.
Giờ đầu: check database connection, queue config, network timeout. Tất cả đều ổn.
Giờ thứ hai: thêm verbose logging vào khắp nơi. Phát hiện ra job có được pick up, nhưng sau đó không có gì xảy ra tiếp theo.
Giờ thứ ba: bắt đầu nghi ngờ cái retry logic. Nhưng test case vẫn pass nên mình bỏ qua.
Giờ thứ tư: mình mới ngồi đọc lại từng dòng code một cách cẩn thận. Và mình thấy nó.
Cái sleep function AI generate nó, mình dùng nó, nhưng mình không define nó ở đâu cả trong file đó. Trong môi trường test, có một sleep khác được import từ một test utility. Trong production, nó resolve về undefined, và await undefined trong JavaScript không throw error nó chỉ... tiếp tục. Không có delay gì cả. Kết quả là retry loop chạy gần như ngay lập tức, hammer cái external service đến mức bị rate limit, và job bị drop trong im lặng.
Một dòng. Một function call không được define. 6 tiếng.
AI không biết context của bạn và đó là vấn đề cốt lõi
Sau cái hôm đó mình ngồi nghĩ lại, vấn đề không phải AI viết code sai. Code logic đó về mặt kỹ thuật là đúng nếu sleep được implement đúng cách. AI không biết rằng trong codebase của mình, sleep chưa được define ở global scope. Nó không có context đó.
Đây là điểm mấu chốt mà mình nghĩ nhiều anh em đang bỏ qua khi dùng AI coding tools:
AI đang làm việc trong một cái bubble. Nó không biết bạn đang dùng Node version nào, team bạn có convention gì, hay codebase bạn có những global utility nào. Nó chỉ biết những gì bạn paste vào prompt.
| Thứ AI làm tốt | Thứ AI không biết |
|---|---|
| Viết boilerplate code | Context của codebase bạn |
| Suggest pattern phổ biến | Implicit dependency trong project |
| Explain concept | Business logic đặc thù |
| Generate test case cơ bản | Runtime environment của bạn |
| Refactor code đơn giản | Side effect của thay đổi |
Cái mình học được không phải "đừng dùng AI"
Mình không có ý định bỏ AI tools. Thật ra sau cái incident đó, mình vẫn dùng nhưng workflow thay đổi hoàn toàn.
Thứ nhất, không bao giờ paste code mà không đọc từng dòng. Nghe có vẻ hiển nhiên, nhưng cái tốc độ generate của AI tạo ra một cái áp lực tâm lý kỳ lạ nó generate nhanh quá nên não mình tự động nghĩ "chắc đúng rồi, dùng đi". Bây giờ mình có một rule cứng: AI generate xong, mình đọc như đang review PR của junior dev. Từng dòng.
Thứ hai, hỏi AI về những gì nó assume. Thay vì chỉ hỏi "viết cho mình retry logic", mình hỏi thêm "đoạn code này assume những dependency nào? Có function nào cần được define trước không?". Câu trả lời thường reveal ra những hidden assumption mà mình cần handle.
Thứ ba, test trong isolation trước. Cái sleep bug của mình sẽ bị catch ngay nếu mình test cái processWithRetry function trong một file hoàn toàn mới, không có bất kỳ import nào từ project. Nhưng mình test trong context của project nên nó accidentally pick up cái sleep từ test utility.
Theo kinh nghiệm của mình, AI giỏi nhất khi bạn dùng nó như một cái thought partner hơn là một code generator. Hỏi nó "approach nào tốt hơn cho bài toán này và tại sao" sẽ có giá trị hơn nhiều so với "viết code cho mình".
Productivity thật sự trông như thế nào
Mình đã track lại sau 2 tháng thay đổi workflow. Thật ra tốc độ code của mình không tăng nhiều nhưng thời gian debug giảm đáng kể. Và đó mới là thứ quan trọng.
Cái ảo tưởng "AI giúp code nhanh hơn" thường bỏ qua một phần của equation: code nhanh hơn nhưng debug lâu hơn thì net result vẫn là âm. Mình thấy cái này hay ở chỗ khi bạn thực sự hiểu code bạn đang dùng, dù nó do AI generate hay do bạn tự viết, tốc độ debug của bạn tăng lên rất nhiều vì bạn biết mình đang tìm gì.
Anh em lưu ý một điều: AI tools đang ngày càng tốt hơn, và mình tin là chúng sẽ còn tốt hơn nữa. Nhưng cái khoảng cách giữa "AI generate code" và "code chạy đúng trong production của bạn" cái khoảng cách đó vẫn cần một kỹ sư thật sự để bridge. Và kỹ sư đó phải hiểu đủ sâu để biết khi nào AI đang assume sai.
6 tiếng debug một dòng code là cái giá đắt. Nhưng lesson học được thì worth it.
Nguyễn Nhật Long
@nguyennhatlong1303Nguyễn Nhật Long is a Senior Frontend Engineer and Frontend Team Leader with 7 years of experience building real-time fintech platforms. Specializing in React, Next.js, TypeScript, and React Native, shipping 10+ products across Web, Mobile, Telegram Mini-Apps, and Web3.
Thấy hay? Chia sẻ cho bạn bè!