Vai trò của năng lực lập trình viên trong lập trình tác tử
(martinfowler.com)- Khi các trợ lý lập trình dạng tác tử ngày càng trở nên năng lực hơn, phản ứng cũng rất đa dạng, và một số người thậm chí còn khẳng định rằng "trong vòng 1 năm nữa sẽ không còn cần lập trình viên"
- Những người khác lại bày tỏ lo ngại về chất lượng của mã do AI tạo ra và cách chuẩn bị cho các lập trình viên junior thích nghi với môi trường đang thay đổi này
- Trong vài tháng qua, tác giả đã sử dụng các trợ lý lập trình dạng tác tử như Cursor, Windsurf, Cline, và thấy chúng rất hiệu quả trong việc thay đổi codebase hiện có
- Tác giả đặc biệt ấn tượng với mức độ tích hợp vào IDE: từ chạy test và tự động sửa lỗi, phát hiện và sửa lỗi lint/biên dịch, cho đến tìm kiếm web và tính năng xem trước trên trình duyệt
- Trải nghiệm cộng tác giữa lập trình viên và AI rất ấn tượng, góp phần giải quyết vấn đề nhanh và triển khai tính năng hiệu quả
- Tuy vậy, vẫn luôn cần sự can thiệp, chỉnh sửa và định hướng liên tục từ lập trình viên
- Cũng có nhiều trường hợp không dẫn tới commit thực tế, và AI vẫn chưa đủ khả năng tự chủ để viết mã cho các tác vụ không hề tầm thường
- Vì vậy, kỹ năng và kinh nghiệm của lập trình viên vẫn rất quan trọng, và trong tương lai vẫn cần tiếp tục được rèn luyện
Những lúc lập trình viên buộc phải trực tiếp can thiệp
- Các công cụ AI luôn cho thấy điểm yếu cố hữu ở một số lĩnh vực nhất định, và điều này đã được xác nhận lặp đi lặp lại
- Một số vấn đề có thể giảm nhẹ phần nào bằng prompt bổ sung hoặc rule tùy biến, nhưng không thể kiểm soát hoàn toàn
- LLM thường không tuân thủ chính xác chỉ dẫn trong prompt
- Càng kéo dài phiên làm việc lập trình, độ nhất quán của kết quả càng giảm
- Vì vậy, các trường hợp dưới đây là những vấn đề hoàn toàn có thể xảy ra bất kể prompt hay cấu hình ra sao
- Tác giả phân loại các lỗi của AI thành 3 nhóm theo phạm vi ảnh hưởng
- a. Làm chậm tốc độ phát triển và thời gian tới commit
- AI thậm chí còn làm chậm tiến độ
- Có trường hợp kém hiệu quả hơn cả lập trình không có hỗ trợ
- b. Gây ma sát trong quy trình làm việc của nhóm
- Phát sinh xung đột hoặc vấn đề cộng tác trong một iteration
- c. Làm suy giảm khả năng bảo trì mã về lâu dài
- Ban đầu có vẻ không thành vấn đề, nhưng sẽ nảy sinh rắc rối khi thay đổi hoặc mở rộng sau này
- a. Làm chậm tốc độ phát triển và thời gian tới commit
- Phạm vi ảnh hưởng càng lớn, vòng lặp phản hồi để cả nhóm nhận ra và sửa vấn đề đó càng dài
Phạm vi ảnh hưởng: trì hoãn thời gian tới commit
- Nhóm này gồm những trường hợp AI gây cản trở hơn là hỗ trợ
- Vì đây là dạng thất bại dễ nhận thấy nhất nên thường không quá nghiêm trọng
- Trong đa số trường hợp, lập trình viên có thể nhận ra và chặn vấn đề trước khi commit
-
Mã không chạy được
- Mã do AI tạo ra về cơ bản không hoạt động
- Lập trình viên phải tự sửa, hoặc kết thúc phiên AI và giải quyết thủ công
- Lập trình viên có kinh nghiệm có thể nhanh chóng xác định chỗ sai và xử lý
-
Chẩn đoán sai vấn đề
- AI xác định sai nguyên nhân và thử giải pháp theo một hướng hoàn toàn lệch
- Dựa trên kinh nghiệm trước đó, lập trình viên có thể kéo AI trở lại đúng hướng
Ví dụ: AI hiểu nhầm lỗi build Docker là vấn đề cấu hình kiến trúc và sửa cấu hình
Nguyên nhân thực sự là sao chépnode_modulesđược build trên sai kiến trúc
Vì đây là vấn đề tác giả từng gặp nhiều lần, nên có thể nhanh chóng nhận ra và sửa lại
Phạm vi ảnh hưởng: quy trình làm việc của nhóm trong một iteration
- Nhóm này bao gồm các trường hợp gây ma sát trong nhóm trong thời gian iteration do thiếu review hoặc thiếu sự can thiệp của lập trình viên
- Nhờ kinh nghiệm từng làm việc ở nhiều nhóm khác nhau, tác giả có thể nhận ra và điều chỉnh trước khi commit
- Các lập trình viên mới vào nghề cũng có thể học được những bài học này thông qua quá trình thử-sai khi làm việc cùng AI
- Nhưng nếu tốc độ lập trình tăng lên nhờ AI, nhóm có thể không đủ sức hấp thụ những vấn đề này
-
Làm quá nhiều việc ngay từ đầu
- AI có xu hướng triển khai cả tính năng theo diện rộng trong một lần, thay vì làm dần từng bước
- Vì vậy, nếu lựa chọn kỹ thuật không phù hợp hoặc hiểu sai yêu cầu tính năng, rất nhiều công sức có thể bị lãng phí
Ví dụ: khi migrate frontend stack, AI cố chuyển đổi toàn bộ UI component cùng lúc
Đúng ra nên áp dụng dần bắt đầu từ một component có tích hợp với backend
-
Giải quyết bừa mà không phân tích nguyên nhân
- AI không phân tích nguyên nhân gốc rễ của vấn đề mà chỉ cố sửa lỗi bề ngoài đang nhìn thấy
- Điều này khiến thành viên khác tiếp nhận việc sau đó phải tự phân tích lại vấn đề mà không có ngữ cảnh
Ví dụ: khi build Docker bị lỗi bộ nhớ, AI chỉ tăng cấu hình bộ nhớ thay vì tìm nguyên nhân
-
Làm phức tạp workflow của lập trình viên
- Cách build/chạy do AI tạo ra làm giảm trải nghiệm phát triển
- Nếu commit ngay, điều đó có thể ảnh hưởng xấu tới workflow của các thành viên khác
Ví dụ: tách riêng lệnh chạy frontend và backend
Ví dụ: thiếu tính năng hot reload
Ví dụ: cấu hình build phức tạp khiến cả lập trình viên lẫn AI đều bối rối
Ví dụ: không phát hiện sớm lỗi Docker, mà cố xử lý lỗi ở giai đoạn cuối của quá trình build
-
Yêu cầu bị hiểu sai hoặc chưa đầy đủ
- Nếu không đưa ra yêu cầu tính năng rõ ràng, AI có thể hiểu sai và triển khai tính năng theo hướng lệch hẳn
- Việc can thiệp sớm để chỉnh hướng là lý tưởng nhất, nhưng với cả AI tự chủ lẫn lập trình viên thiếu suy xét, chi phí sửa về sau đều tăng lên
- Những triển khai sai như vậy thường chỉ được phát hiện khi story đã tiến triển, dẫn tới nhiều công sửa đổi và chi phí giao tiếp
Phạm vi ảnh hưởng: suy giảm khả năng bảo trì về lâu dài
- Đây là phạm vi ảnh hưởng âm thầm và nguy hiểm nhất
- Ban đầu mã có thể chạy ổn, nhưng về sau sẽ khó thay đổi và mở rộng
- Những vấn đề như vậy thường chỉ được phát hiện sau vài tuần đến vài tháng
- Đặc biệt ở mảng này, hơn 20 năm kinh nghiệm phát triển của tác giả phát huy tác dụng mạnh nhất
-
Mã test dài dòng và trùng lặp
- AI tạo test khá tốt, nhưng thường phát sinh các vấn đề như:
- Tạo thêm hàm test mới thay vì tích hợp vào test hiện có
- Thêm quá nhiều assertion cho cả những phần đã được cover
- Điều người mới dễ hiểu lầm là: nhiều test hơn ≠ test tốt hơn
- Càng nhiều trùng lặp thì càng khó bảo trì, và khi code thay đổi thì nguy cơ hàng loạt test bị fail càng cao
- Dù đã thử giảm nhẹ bằng lệnh tùy biến, tình trạng này vẫn xảy ra thường xuyên
- AI tạo test khá tốt, nhưng thường phát sinh các vấn đề như:
-
Thiếu khả năng tái sử dụng
- Mã do AI viết ra thường thiếu tính module hóa, nên khó tái sử dụng
Ví dụ: không nhận ra UI component đã tồn tại mà lại triển khai trùng
Ví dụ: lạm dụng inline style thay vì dùng CSS class
- Mã do AI viết ra thường thiếu tính module hóa, nên khó tái sử dụng
-
Mã quá phức tạp hoặc dài dòng
- AI thường tạo ra nhiều mã hơn mức cần thiết, khiến lập trình viên phải xóa bớt thủ công những phần thừa
- Điều này làm tăng chi phí bảo trì và nâng xác suất phát sinh lỗi khi thay đổi
Ví dụ: khi sửa CSS, phải xóa thủ công rất nhiều style trùng lặp
Ví dụ: tạo một web component phức tạp không cần thiết chỉ để hiển thị dữ liệu JSON
Ví dụ: trong quá trình refactor, AI không nhận ra chuỗi dependency injection sẵn có,
rồi lại truyền giá trị đã được inject thành một tham số khác, làm thiết kế trở nên phức tạp- dạng
value = service_a.get_value(); ServiceB(service_a, value=value)
- dạng
Kết luận: AI có thể thay thế để viết toàn bộ mã hay không?
- Dựa trên kinh nghiệm cho đến hiện tại, việc AI tự chủ viết 90% toàn bộ mã trong vòng 1 năm tới là không thực tế
- Tuy vậy, với vai trò hỗ trợ viết mã, ở một số nhóm và codebase nhất định, AI có thể hỗ trợ tới 90%
- Trên thực tế, tác giả đang nhận được khoảng 80% hỗ trợ từ AI trong một dự án độ phức tạp trung bình, quy mô 15K LOC
Cách phòng tránh sai sót của AI
-
Những điều cá nhân lập trình viên có thể làm
- Luôn review cẩn thận mã do AI tạo ra
- Gần như không có trường hợp nào không cần chỉnh sửa
- Dừng ngay phiên AI nếu thấy nó đang rối
- Sửa lại prompt hoặc chuyển hẳn sang làm thủ công (còn được gọi là "handmade coding")
- Cảnh giác với những giải pháp "có vẻ hợp lý" được hoàn thành thần kỳ trong thời gian ngắn
- Có thể đang ẩn chứa chi phí bảo trì dài hạn
- Thực hành pair programming
- 4 con mắt, 2 bộ não sẽ cho ra phán đoán tốt hơn
- Luôn review cẩn thận mã do AI tạo ra
-
Chiến lược ứng phó ở cấp độ nhóm và tổ chức
- Tận dụng tích cực các công cụ giám sát chất lượng mã hiện có
- Ví dụ: Sonarqube, Codescene
- Khi dùng công cụ AI, cần theo dõi sát hơn các vấn đề như mã trùng lặp, code smell, v.v.
- Thiết lập pre-commit hook và review code tích hợp trong IDE
- Tăng cường chiến lược shift-left để bắt vấn đề ngay từ đầu quá trình phát triển
- Tái thiết lập các thói quen tốt về chất lượng mã
- Chia sẻ các trường hợp phát sinh vấn đề do mã AI ("nhật ký sai hỏng") trong các buổi retrospective hằng tuần của nhóm
- Tích cực sử dụng rule tùy biến
- Hầu hết các công cụ AI đều cho phép thiết lập bộ quy tắc được truyền kèm cùng prompt
- Cả nhóm có thể cùng cải thiện ruleset để giảm lỗi của AI
- Tuy nhiên, phiên làm việc càng dài thì khả năng AI phớt lờ rule càng tăng
- Xây dựng văn hóa nhóm dựa trên niềm tin và giao tiếp
- Việc đưa AI vào là một thay đổi mới, và cần nhận thức rằng mọi người đều là người mới bắt đầu
- Kiểu áp lực "đã có AI rồi thì làm nhanh hơn đi" sẽ làm tăng rủi ro về chất lượng
- Một đội ngũ có cảm giác an toàn về tâm lý sẽ chia sẻ vấn đề và học hỏi tích cực hơn
- Tận dụng tích cực các công cụ giám sát chất lượng mã hiện có
4 bình luận
Những người dùng công cụ đó dù năng lực ra sao thì vẫn đều là lập trình viên cả thôi.... Nhưng việc quảng bá theo kiểu sắp tới sẽ không cần lập trình viên nữa thì có vẻ hơi kỳ kỳ.
Không biết sau này sẽ thế nào, nhưng hiện tại có vẻ vẫn chưa đủ tốt để dùng một cách phổ biến... Gần đây tôi thử dùng Cursor, mà ngay cả import path cơ bản của file nó cũng không bắt đúng. Dù vậy, việc nó có thể phần nào dự đoán trước thứ tôi muốn làm vẫn khá đáng ngạc nhiên.
Khi xảy ra lỗi bộ nhớ trong lúc build Docker, thay vì hỏi ngay từ đầu vì sao lại dùng nhiều bộ nhớ đến thế thì lại tăng cấu hình bộ nhớ lên
-> Đây là vì.. trong vô số trường hợp trước giờ, chúng ta vẫn luôn làm như vậy.
-> AI hiện tại chính là chúng ta của ngày trước
Ý kiến trên Hacker News
Dạo này tôi dùng Cursor cho hầu hết công việc phát triển. Bài này rất giống với trải nghiệm của tôi
Tôi dùng AI theo cách này: như một công cụ hỗ trợ viết trong IDE, trả lời tôi như một con vịt cao su cực kỳ xịn và tinh vi
Tôi hoàn toàn không hiểu
Ví dụ: khi gặp lỗi bộ nhớ trong lúc build Docker, thay vì hỏi ngay từ đầu vì sao lại dùng nhiều bộ nhớ đến thế, nó lại tăng cấu hình bộ nhớ lên
Kỹ năng của lập trình viên vẫn là thứ thiết yếu — nếu không biết lái thì không thể điều khiển được. Nhưng còn năng lượng của lập trình viên thì sao? Trước thời AI, mỗi ngày tôi chỉ code được khoảng 2 tiếng (thời gian thực sự viết code). Nhưng với Claude Code, tôi có thể dễ dàng code liên tục 5 tiếng không nghỉ. Nó giống như đi xe đạp điện thay vì xe đạp thường. AI cho tôi cảm giác như ẩn dụ “chiếc xe đạp cho trí óc” của Steve Jobs — nó không thay thế tôi, nhưng giờ tôi có thể đi xa hơn và nhanh hơn rất nhiều
Sơ đồ này quá đúng với tôi — đội của chúng tôi đánh dấu được mọi mục ở đây. Mà còn chưa dùng AI nữa! Hãy tưởng tượng khi cuối cùng chúng tôi dùng AI thì sẽ thế nào...
Với tôi thì điều hiển nhiên không hiện ra rõ ràng: tôi dùng AI ở khắp nơi xung quanh
Tôi vẫn phải điều khiển AI rất nhiều, nhưng tôi lạc quan rằng prompt tốt hơn sẽ dẫn đến agent tốt hơn
Tôi muốn nói trước rằng các công cụ AI luôn tệ ở những điều tôi liệt kê
Martin Fowler giờ đang cho thuê chỗ trên website của ông ấy sao?