Đạo/2026-10-15/7 phút
v2.1

Khi AI viết code, tôi đang làm gì?.

Tôi ngồi nhìn AI viết code và nhận ra tôi không còn là người viết nữa. Vậy thì tôi đang là gì?

#ai#coding agent#craft#reflection
fig.01 — review.svgtaste

Tôi gõ một câu mô tả vấn đề, nhấn Enter, rồi ngồi nhìn agent viết code. Có khi vài giây, có khi vài phút, và trong khoảng ấy tôi không gõ thêm gì. Mười ngón tay vẫn đặt trên bàn phím theo thói quen, dù chẳng còn gì để gõ. Lần đầu để ý tới khoảng lặng đó, tôi không gọi được tên cảm giác của mình.

Đầu tôi vẫn chạy, mắt vẫn theo từng dòng code hiện ra, nên gọi là rảnh hay chán thì đều không đúng. Gần nhất có lẽ là cảm giác đang đọc. Chỉ có điều tôi đang đọc một thứ mình chưa từng viết, và nó được viết ra nhanh hơn tốc độ tôi đọc kịp, nên tôi phải chọn chỗ nào đọc kỹ, chỗ nào lướt qua, như lúc phải review một PR vài nghìn dòng trước giờ họp.

Ai từng ngồi ghế phụ cạnh một người đang tập lái chắc nhận ra cảm giác này. Tay không cầm vô lăng, chân không đạp ga, vậy mà xuống xe thì mệt hơn cả tự lái. Người cầm lái là người đang tập, còn người chịu trách nhiệm cho chiếc xe lại là người ngồi bên. Mắt phải nhìn xa hơn người cầm lái một đoạn, còn chân thì lúc nào cũng hờ trên một cái phanh không có thật.

Trước đây tôi quen định nghĩa mình qua việc gõ phím. Code có mặt vì tôi viết ra nó, từng ký tự một. Giờ phần ấy đã có người làm thay, còn việc của tôi là nhìn kết quả và biết nó đúng chưa, còn thiếu gì, lúc nào thì phải hỏi lại. Vai trò vẫn còn đó, chỉ dời sang một chỗ khó nhìn thấy hơn.

Nhịp làm việc vì thế cũng đổi. Thời gian gõ phím ít đi, thời gian đọc nhiều lên: đọc diff, rồi đọc lại yêu cầu mình đã viết để xem agent có hiểu đúng ý không. Đọc code vốn khó hơn viết, vì người đọc phải dựng lại trong đầu những lựa chọn mà người viết đã làm mà không ghi ra. Khi người viết là một thực thể không biết mệt, toàn bộ sức nặng của việc đọc và ngẫm ấy đổ dồn về phía tôi.

Trên công trường, người thợ cả nhiều khi chẳng cầm bay. Họ đi dọc bức tường mới xây, nheo mắt một chút, rồi chỉ vào chỗ lệch mà người khác phải đặt thước mới thấy. Người mới học việc nhìn bức tường ấy chỉ thấy gạch và vữa, còn họ thấy cả những chỗ sẽ nứt sau mùa mưa đầu tiên. Công của họ nằm ở đôi mắt ấy, và đôi mắt ấy có được từ những năm họ tự tay đặt từng viên gạch.

Có một chữ tôi cứ nghĩ tới mãi là taste, khả năng phân biệt thứ tốt với thứ chỉ trông có vẻ tốt. Nó khác với kỹ năng viết code, cũng khác với tốc độ làm xong một tính năng. Một đoạn code chạy được và qua được test vẫn có thể là một lựa chọn sai cho cái hệ thống sẽ phải sống với nó vài năm. Tôi không nghĩ có thể khoán việc này cho AI, và càng ngày tôi càng tin đây là thứ đáng giữ, đáng mài nhất lúc này.

David Hume có một bài luận về chuẩn mực của thị hiếu, viết vào giữa thế kỷ mười tám. Theo ông, người thẩm định đáng tin cần một sự tinh tế được rèn qua luyện tập và hoàn thiện qua so sánh. Tôi thích chữ so sánh ở đó. Muốn biết một abstraction gọn thật hay chỉ gọn ngoài mặt, người ta phải từng thấy đủ nhiều cái gọn thật và cái gọn giả để đặt chúng cạnh nhau.

Vì thế tôi không thấy những năm viết code bằng tay trở nên vô ích. Chính vì từng viết đủ nhiều, tôi mới phân biệt được abstraction tốt với abstraction chỉ trông gọn gàng, và nhờ vậy mới đọc được những gì agent viết ra. Những lần ngồi lần một lỗi do chính mình gây ra, hay viết lại một module vì thiết kế ban đầu không chịu nổi yêu cầu mới, giờ hiện ra ở một chỗ tôi không ngờ, là lúc đọc code của người khác. Thứ kinh nghiệm ấy để lại hoá ra là phán đoán, nhiều hơn là ngón tay gõ nhanh.

Aristotle có nói tới một loại hiểu biết ông gọi là phronesis, thường được dịch là sự khôn ngoan thực tiễn, tức là biết nên làm gì trong một tình huống cụ thể. Ông nhận xét người trẻ có thể giỏi hình học và toán, nhưng khó có được thứ khôn ngoan này, vì nó cần kinh nghiệm với rất nhiều trường hợp riêng lẻ. Đọc đoạn ấy, tôi nghĩ tới việc review code. Thuộc các nguyên tắc thiết kế thì nhanh, còn biết nguyên tắc nào nên phá ở đúng chỗ này thì phải mất nhiều năm.

Michael Polanyi có một câu hay được nhắc: chúng ta biết nhiều hơn những gì ta nói ra được. Taste trong code có lẽ thuộc loại hiểu biết ấy. Nhiều khi tôi thấy một đoạn code có gì đó không ổn trước khi giải thích được vì sao. Lời giải thích chỉ tới sau vài lượt đọc lại, khi tôi chỉ ra được cái mà người trong nghề hay gọi là "có mùi", như một hàm biết quá nhiều về những thứ xung quanh nó, hay một điều kiện bị lặp lại ở vài chỗ.

Cái khó nhất với tôi hoá ra lại là những lúc mọi thứ êm. Khi agent làm đúng nhiều lần liền, tôi bắt đầu đọc nhanh hơn, lướt hơn, và có khi gật đầu trước cả lúc đọc hết. Người ngồi ghế phụ cũng thế, người tập lái chạy êm được một quãng dài là lúc họ bắt đầu nhìn ra cửa sổ. Chiếc xe thì không biết người ngồi cạnh đã thôi để ý.

Để giữ con mắt ấy, thỉnh thoảng tôi vẫn tự viết một đoạn khó từ đầu, dù biết agent làm nhanh hơn. Thường đó là một chỗ xử lý đồng thời, hoặc một đoạn migrate dữ liệu mà sai một dòng là phải khôi phục từ backup. Viết xong, tôi đem so với bản agent viết, và thường thấy ít nhất một chỗ hai bên chọn khác nhau. Những chỗ khác nhau ấy chính là kiểu so sánh Hume nói tới, chỉ là giờ nó nằm gọn trong một cái diff.

Cũng có lúc tôi thấy hơi bất an. Người thợ cả có con mắt ấy nhờ những năm đặt gạch, còn một người mới vào nghề hôm nay, bắt đầu từ ghế phụ, sẽ học nhìn từ đâu? Tôi không lo cho mình nhiều, vì con mắt của tôi đã được mài từ trước khi có agent. Tôi chỉ hơi lo cho những người vào nghề sau này, những người sẽ quen nhìn code tốt hiện lên ngay từ đầu, trước khi kịp nếm trải thế nào là viết ra những dòng code dở.

Người vào nghề trước đây học nhìn qua những lần PR bị trả về với cả chục comment. Có những lỗi chỉ thấm khi chính mình viết ra rồi bị người khác chỉ vào, như một vòng lặp gọi database ở từng lượt, hay một biến dùng chung khiến hai request giẫm nhau. Những bài học ấy đến từ code dở do chính tay mình viết. Tôi nghĩ phần viết dở ấy là chỗ không bỏ được, và tôi chưa biết nghề mình sẽ giữ nó lại bằng cách nào.

Có một thứ thì không dời đi đâu cả, là cái tên trên commit. Agent viết, nhưng người bấm merge là tôi, và khi hệ thống lỗi lúc nửa đêm thì người bị gọi dậy cũng là tôi. Lịch sử git sẽ ghi tên tôi ở dòng approve, và một năm sau, ai đọc lại đoạn code ấy sẽ tìm tới tôi để hỏi vì sao nó được viết như thế. Cái tên ấy làm việc ngồi nhìn nặng hơn nhiều so với vẻ ngoài của nó.

Một người review code giỏi có lẽ gần nhất với việc tôi đang làm bây giờ. Họ không có tên trong phần lớn commit, nhưng một codebase tốt thường mang dấu tay của họ ở những chỗ người dùng không thấy, như một abstraction bị gỡ đi trước khi kịp lan ra, hay một trường hợp biên được hỏi lại. Họ đọc code của người khác kỹ hơn cả người viết đọc code của chính mình, vì trong đầu họ không có sẵn điều người viết định làm. Người dùng chỉ thấy sản phẩm chạy, còn những lần nó suýt hỏng thì chỉ người review biết.

Nên giờ, khi ngồi nhìn agent viết code, tôi biết mình đang làm phần việc khó nhất của nghề này, là nghĩ. Việc ấy khó thấy hơn gõ phím, và mệt theo một kiểu khác. Màn hình vẫn chạy chữ, tôi vẫn ngồi yên, và mắt tôi luôn nhìn trước người cầm lái một đoạn.

Trạm Dev · 2026-10-15 · v2.1 · EOF
#ai#coding agent#craft#reflection
$ ls ./dao6 / 6 · bài mới nhất