Hai cách xây dựng phần mềm với AI
Hiện nay, trong mọi đội ngũ đang xây dựng sản phẩm với AI đều âm thầm tồn tại một cuộc tranh luận, và nó thường xuất hiện dưới dạng một cảm giác hơn là một cuộc đối thoại. Một người hoàn thành một ứng dụng chạy được chỉ trong một buổi chiều bằng cách mô tả điều mình muốn và chấp nhận bất cứ thứ gì mô hình tạo ra. Người khác thì nhất quyết đọc từng dòng, viết test và hiểu rõ thứ đó thực sự hoạt động thế nào. Cả hai đều dùng cùng một công cụ. Chỉ là họ đang chơi hai trò chơi rất khác nhau.
Giờ đây hai trò chơi này đã có tên gọi. Phong cách nhanh, thoải mái, mô tả rồi chấp nhận được gọi là vibe coding. Phong cách cẩn trọng, có hệ thống, xây dựng các hệ thống đáng tin cậy xoay quanh một mô hình thì gần với điều mọi người muốn nói khi nhắc đến agentic engineering. Rất dễ coi đây là một cuộc đối đầu, một bên đại diện cho tốc độ, bên kia cho sự chặt chẽ, rồi chọn phe. Cách nhìn đó đã bỏ lỡ điều cốt lõi. Chúng không phải đối thủ. Chúng là những công cụ khác nhau cho những thời điểm khác nhau, và kỹ năng thực sự là biết mình đang cầm công cụ nào.
Sự nhầm lẫn này đáng được làm rõ, bởi cái giá phải trả đang tăng lên rất nhanh. Ngày càng nhiều phần mềm được viết với sự trợ giúp đáng kể từ các mô hình, và những thói quen mọi người hình thành lúc này sẽ quyết định phần mềm đó là thứ chúng ta có thể xây tiếp lên trên, hay chỉ là một đống code không ai hiểu. Phân biệt đúng, AI sẽ giúp bạn nhanh hơn ở mọi việc, từ những thử nghiệm dùng một lần đến những hệ thống nghiêm túc. Phân biệt sai, bạn hoặc sẽ lê bước qua những bản prototype vốn không đáng được chăm chút đến vậy, hoặc sẽ đưa lên production những hệ thống được gắn kết bằng phỏng đoán.
Bài viết này sẽ đi qua toàn bộ vấn đề: mỗi chế độ thực chất là gì, vì sao vibe coding lại hấp dẫn đến vậy, mỗi cách phát huy giá trị ở đâu, làm sao phân biệt chúng ngay trong lúc làm việc, và làm sao dùng cả hai mà không tự lừa mình về việc một nhiệm vụ cụ thể đang đòi hỏi cách nào. Dọc đường sẽ có một bảng so sánh, một bước kiểm tra nhanh để ra quyết định, vài tình huống thực tế và hai danh sách kiểm tra bạn có thể giữ lại dùng.
Vibe coding là gì
Thuật ngữ vibe coding xuất phát từ Andrej Karpathy, người đã mô tả một cách làm việc mới: bạn dựa hẳn vào mô hình, nói chuyện với nó bằng ngôn ngữ thông thường, chấp nhận các gợi ý của nó mà không bận tâm đến chi tiết, và gần như quên rằng code tồn tại. Bạn không đọc diff. Bạn cứ thế lướt theo cảm hứng.
Hãy hình dung một phiên làm việc thực tế trông như thế nào. Bạn mở một cửa sổ chat hoặc một agent, mô tả thứ mình muốn, và code xuất hiện. Bạn chạy nó. Có gì đó chưa ổn, bạn dán lỗi vào và nhờ sửa, rồi code mới xuất hiện. Bạn không đọc kỹ, có khi chẳng đọc chút nào. Bạn chạy lại. Nó chạy, hoặc chạy tạm được, và bạn chuyển sang tính năng tiếp theo, làm y hệt như vậy. Vòng lặp này nhanh và gần như một cuộc trò chuyện, và không lúc nào bạn dừng lại để hình thành trong đầu một mô hình về cách mọi thứ khớp với nhau. Mô hình AI nắm giữ điều đó, hay đúng hơn, chẳng ai nắm giữ cả.
Ai từng làm vậy đều hiểu vì sao nó trở nên phổ biến. Nó thực sự thú vị. Bạn làm việc với tốc độ của suy nghĩ, khoảng cách giữa một ý tưởng và một prototype chạy được gần như biến mất, và bạn có thể tạo ra những thứ mà mình chẳng bao giờ đủ kiên nhẫn để tự tay viết. Một người hầu như không viết nổi một đoạn script giờ có thể dựng được một ứng dụng web hoạt động. Một kỹ sư giàu kinh nghiệm có thể thử năm hướng tiếp cận trong khoảng thời gian trước đây chỉ đủ để thiết lập một hướng. Với một dự án cuối tuần, một thử nghiệm nhanh hay một công cụ chỉ mình bạn dùng, nó có thể giống như một siêu năng lực, và quả thật gần như là vậy.
Tuy nhiên, đặc điểm cốt lõi không nằm ở tốc độ. Nó nằm ở sự buông bỏ. Trong vibe coding, bạn giao lại không chỉ việc gõ phím mà cả sự hiểu biết. Bạn tin code chạy đúng vì nó có vẻ chạy đúng, và bạn không mấy quan tâm nó chạy thế nào. Chính sự đánh đổi đó làm nên tốc độ, và cũng chính ở đó rắc rối bắt đầu. Hãy ghi nhớ từ này, buông bỏ, vì hầu như mọi điều tốt lẫn xấu của vibe coding đều bắt nguồn từ nó.
Vì sao nó mang lại cảm giác tuyệt vời đến vậy
Trước khi bàn đến chỗ vibe coding đi sai hướng, cần nghiêm túc nhìn nhận vì sao rất nhiều người giỏi lại sa vào nó, bởi sức hút là có thật và giả vờ như không thì chẳng ích gì.
Lý do đầu tiên đơn giản là tốc độ, và tốc độ thì gây nghiện. Có một niềm vui đặc biệt khi mô tả điều gì đó và nhìn nó thành hình ngay sau đó, và nó gãi đúng chỗ ngứa từng khiến công việc trở nên thú vị ngay từ đầu. Viết code bằng tay luôn có những quãng dài đầy ma sát: boilerplate, cấu hình, tra lại một interface bạn đã dùng cả trăm lần. Vibe coding thu nhỏ ma sát đó gần như về không, và cảm giác không còn ma sát giống như đang bay.
Lý do thứ hai là vòng phản hồi. Mỗi yêu cầu nhỏ nhanh chóng tạo ra một kết quả nhìn thấy được, và kết quả nhanh, nhìn thấy được gần như là thứ củng cố hành vi mạnh nhất mà bộ não có thể nhận. Đó cũng chính là vòng lặp khiến game và các bảng tin mạng xã hội trở nên gây nghiện. Bạn yêu cầu, bạn nhận được, bạn lại yêu cầu, và một giờ trôi qua lúc nào không hay. Vòng lặp thỏa mãn đến mức dừng lại để đọc code giống như một sự gián đoạn, như đang chạy tốt mà phải dừng lại kiểm tra tư thế.
Lý do thứ ba là bản demo. Phần lớn áp lực trong phát triển phần mềm là phải cho thấy tiến độ, và một prototype làm bằng vibe coding thể hiện tiến độ rất đẹp. Nó trông như đã xong. Nó bấm được, phản hồi được và gây ấn tượng trong cuộc họp. Khoảng cách giữa trông như đã xong và thực sự đã xong là vô hình từ bên ngoài, và những vấn đề vô hình thì không tạo ra sự cấp bách. Vì vậy, các động lực âm thầm khen thưởng thứ trông hoàn chỉnh hơn là thứ vững chắc, và các đội ngũ trôi dần về phía vibe coding mà chưa bao giờ quyết định như vậy.
Không điều nào trong số này là khiếm khuyết tính cách. Đó là phản ứng hợp lý trước những động lực có thật và một trải nghiệm thực sự tốt hơn. Mục đích của việc gọi tên nó không phải để cảm thấy mình hơn người. Mà là để nhận ra sức hút đó, từ đó bạn có thể quyết định khi nào nên cưỡng lại, thay vì bị cuốn theo một cảm giác mà mình chưa từng xem xét.
Agentic engineering là gì
Agentic engineering là thái độ còn lại. Nó cũng dựa nhiều vào AI, thường còn nhiều hơn cả vibe coding, vì nó đặt mô hình vào bên trong những hệ thống thực tế có khả năng tự hành động. Sự khác biệt không nằm ở việc bạn dùng AI nhiều hay ít. Mà nằm ở mức độ bạn giữ quyền kiểm soát đối với những gì AI tạo ra.
Một kỹ sư đối xử với kết quả của mô hình giống như một người review cẩn thận đối xử với pull request của một lập trình viên junior đầy tự tin. Công việc có thể rất xuất sắc, nhưng đó là bản nháp cần kiểm tra, không phải chân lý để chấp nhận. Trên thực tế, điều đó trở thành một số thói quen cụ thể. Có test, để hành vi bạn quan tâm được cố định và một thay đổi trong tương lai không thể âm thầm phá vỡ nó. Có cách để thấy hệ thống đã làm gì và vì sao, để khi có sự cố bạn có thể lần ra nguyên nhân thay vì đoán mò. Có giới hạn về những gì hệ thống được phép chạm vào, và những điểm rõ ràng nơi con người phê duyệt trước khi bất cứ điều gì tốn kém hoặc không thể đảo ngược xảy ra. Và khi công việc liên quan đến một agent tự hành, sẽ có eval, những bài kiểm tra lặp lại được xem toàn bộ hệ thống có thực sự làm đúng việc của nó trong các trường hợp quan trọng hay không, bởi một agent chạy được một lần trong bản demo gần như chẳng nói lên điều gì về việc nó có thực sự hoạt động hay không.
Trên hết là sự thấu hiểu. Có người biết thứ đó hoạt động thế nào, có thể sửa khi nó hỏng, có thể suy luận về các trường hợp biên của nó, có thể giải thích cho đồng nghiệp vì sao nó được xây dựng như vậy. Sự thấu hiểu được coi là một sản phẩm bàn giao đúng nghĩa, cũng là một phần của công việc như code đang chạy, bởi một hệ thống không ai hiểu là một hệ thống đã bắt đầu thất bại. Chỉ là nó chưa nhận ra mà thôi.
Nếu vibe coding là buông theo cảm hứng, thì engineering là từ chối điều đó. Nó giữ lại đúng thói quen mà vibe coding vứt bỏ, đó là thói quen kiểm chứng và thấu hiểu trước khi tin tưởng. Thói quen duy nhất đó chính là toàn bộ sự khác biệt, và đáng để xem xét trực tiếp.
Đây là một dải liên tục, không phải lựa chọn nhị phân
Trước khi đi tiếp, nên bỏ đi ý nghĩ rằng chỉ có hai lựa chọn. Vibe coding và engineering đầy đủ là hai đầu của một dải, và phần lớn công việc thực tế nằm đâu đó ở giữa.
Ở tận cùng bên trái là vibe coding thuần túy: bạn chấp nhận những gì mô hình đưa ra và không bao giờ đọc. Tiến vào một bước là điều hầu hết mọi người thực sự làm phần lớn thời gian, lập trình có AI hỗ trợ, khi mô hình viết và bạn review diff trước khi chấp nhận, giống như cách bạn review công việc của một đồng nghiệp. Xa hơn nữa là một cách làm kỷ luật hơn, phong cách dựa trên đặc tả, khi bạn viết rõ code phải làm gì, để mô hình triển khai, rồi kiểm tra phần triển khai so với đặc tả bằng test. Ở tận cùng bên phải là agentic engineering đầy đủ, khi mô hình được đan cài vào một hệ thống có eval, khả năng quan sát (observability) và cơ chế bảo vệ (guardrail), và toàn bộ được đối xử như phần mềm production, chỉ là tình cờ được viết với sự trợ giúp đáng kể từ AI.
Khi đi từ trái sang phải, bạn đánh đổi tốc độ thuần túy lấy quyền kiểm soát, sự thấu hiểu và độ bền vững. Không điểm nào trong số này là câu trả lời đúng cho mọi trường hợp. Sai lầm mọi người mắc phải không phải là chọn sai điểm. Mà là không nhận ra có một núm xoay, và để nó kẹt ở bất cứ đâu thói quen hay tâm trạng tình cờ đặt. Một người xây dựng giỏi chủ động xoay núm, sang trái để khám phá và sang phải để gia cố, và phần còn lại của bài viết này thực chất là về việc học cách cảm nhận núm xoay nên ở đâu.
Khác biệt cốt lõi: kiểm chứng và thấu hiểu
Dù bạn ở vị trí nào trên dải đó, thứ thay đổi khi bạn trượt dọc theo nó là một bước cụ thể. Đặt vibe coding thuần túy và engineering thực thụ cạnh nhau, sự tương phản đơn giản đến mức gần như đáng ngượng. Cả hai đều bắt đầu bằng việc mô tả điều bạn muốn và để mô hình tạo code. Rồi hai con đường tách ra. Vibe coding đi thẳng từ code được tạo ra đến việc phát hành. Engineering chèn thêm một bước ở giữa, bước bạn đọc, test và đảm bảo mình hiểu nó trước khi nó đi đến bất cứ đâu.
Bước bị bỏ qua đó không phải là một thiếu sót nhỏ. Đó là bước bắt được lỗi, phát hiện lỗ hổng bảo mật, nơi bạn biết được code thực sự làm gì thay vì điều bạn hy vọng nó làm. Đó cũng là nơi sự thấu hiểu được tạo ra, bởi đọc và test code là cách con người hình thành trong đầu một mô hình về nó. Bỏ qua bước này là bạn bỏ qua cùng lúc cả việc kiểm tra lẫn việc học hỏi. Bỏ qua nó khiến vibe coding nhanh, và giữ lại nó khiến engineering chậm. Hầu như mọi điều khác trong bài viết này đều bắt nguồn từ lựa chọn duy nhất này.
Cần thành thật rằng bước này có cái giá thực sự. Nó chậm hơn, kém vui hơn, và rất nhiều khi code được tạo ra vốn đã ổn và việc review chẳng phát hiện được gì. Đó chính là lý do mọi người bỏ qua nó. Câu hỏi không bao giờ là việc kiểm chứng có phiền hay không. Nó luôn phiền. Câu hỏi là thứ bạn đang xây dựng có phải loại mà một lỗi bị bỏ sót chỉ khiến người ta nhún vai, hay là một thảm họa, và câu hỏi đó có những câu trả lời khác nhau vào những ngày khác nhau.
Tổng quan nhanh
Trước khi đi sâu hơn, đây là toàn bộ sự tương phản gói gọn trong một màn hình. Hãy đọc nó như một bản tóm tắt, không phải một phán quyết. Không cột nào là cột tốt. Mỗi cột đều đúng ở đúng chỗ của nó.
| Vibe coding | Agentic engineering | |
|---|---|---|
| Tối ưu cho | Tốc độ và khám phá | Độ tin cậy theo thời gian |
| Động tác cốt lõi | Chấp nhận kết quả | Kiểm chứng và thấu hiểu trước |
| Phù hợp nhất cho | Prototype, thứ dùng một lần, công cụ cá nhân | Production và mọi thứ người khác phụ thuộc vào |
| Tốc độ | Rất nhanh lúc đầu | Chậm hơn lúc đầu, ổn định hơn về sau |
| Ai hiểu nó | Thường là không ai cả | Một người, một cách có chủ đích |
| Chi phí ẩn | Code bạn không thể thay đổi một cách an toàn | Thời gian dành cho kiểm chứng |
| Khi nào gây hại | Khi mức độ rủi ro tăng lên mà nó không dừng lại | Hiếm khi, chủ yếu khi áp dụng cho thứ dùng một lần |
| Thất bại điển hình | Lỗi âm thầm, lỗ hổng bảo mật, code thừa vô dụng | Thiết kế quá mức cho những thứ không cần đến |
Phần còn lại của bài viết chủ yếu là để giải mã bảng này: vì sao mỗi hàng đều đúng, chọn sai thì phải trả giá thế nào, và làm sao đưa ra quyết định đúng mà không phải đắn đo quá nhiều mỗi lần.
Vibe coding tỏa sáng ở đâu
Sẽ là sai lầm nếu hiểu tất cả những điều trên theo nghĩa vibe coding là lựa chọn lười biếng còn engineering là lựa chọn có trách nhiệm. Rất nhiều khi, vibe coding đơn giản là quyết định đúng, và áp dụng đầy đủ sự chặt chẽ của engineering sẽ chỉ lãng phí thời gian của mọi người.
Khi bạn đang khám phá, vibe coding là vô đối. Phần lớn ý tưởng đều sai, và cách nhanh nhất để biết là dựng một phiên bản thô rồi nhìn vào nó. Dành cả ngày viết test cho một prototype mà ngày mai bạn sẽ vứt đi không phải là kỷ luật, đó là sự trì hoãn khoác áo đức tính. Logic tương tự áp dụng cho cả một nhóm công việc: công cụ cá nhân, script dùng một lần, các bản vá tạm nội bộ, bài tập để học, và bất cứ thứ gì mà nếu hỏng thì chỉ mình bạn bị ảnh hưởng. Nếu trường hợp xấu nhất của một lỗi là bản thân bạn hơi bất tiện trong mười phút, thì chi phí của engineering cẩn thận đơn giản là không đáng.
Còn có một giá trị tinh tế hơn, điều mà ngay cả những kỹ sư kỷ luật cũng nên tôn trọng. Vibe coding thường là cách tốt nhất để tìm ra hình hài của một giải pháp. Không phải lúc nào bạn cũng biết mình đang xây gì cho đến khi đã dựng xong một bản nháp, và một mô hình cho phép bạn tạo ba phiên bản thô trong một giờ sẽ dạy bạn về vấn đề thực sự nhiều hơn một ngày thiết kế cẩn thận trên giấy. Phiên bản đầu tiên là một câu hỏi, không phải câu trả lời. Bạn dựng nó để biết mình thực sự cần gì, và sau đó, nếu thứ đó xứng đáng tồn tại, bạn xây lại nó một cách bài bản với tất cả những gì vừa học được. Dùng theo cách này, vibe coding không phải là thứ đối lập với engineering tốt. Nó là bước trinh sát mà engineering tốt phụ thuộc vào, và bỏ qua nó có thể là một kiểu lãng phí riêng, sự lãng phí của việc cẩn thận xây dựng sai thứ.
Nó thậm chí còn có chỗ đứng bên trong những codebase nghiêm túc, ở quy mô nhỏ. Một script dùng một lần để kiểm tra giả thuyết về dữ liệu, một biểu đồ trực quan nhanh để hiểu một lỗi, một bản triển khai nháp để cảm nhận một interface trước khi cam kết với nó. Đây là vibe coding bên trong một dự án được engineering bài bản, và chúng ổn chính vì phạm vi của chúng được giới hạn để không ảnh hưởng gì. Mối nguy không bao giờ nằm ở vibe coding. Mà nằm ở việc vibe coding một thứ hóa ra lại quan trọng mà không hề nhận ra điều đó.
Nó đổ vỡ ở đâu
Rắc rối bắt đầu khi mức độ rủi ro âm thầm tăng lên mà vibe coding không dừng lại. Một prototype được đưa cho một khách hàng xem, rồi thêm vài khách hàng nữa, và một ngày nó trở thành sản phẩm, vẫn được gắn kết bằng thứ code chưa ai từng đọc. Chế độ từng hoàn hảo cho thử nghiệm giờ đang vận hành một thứ thực sự, và hóa đơn cho bước bị bỏ qua đến hạn cùng một lúc.
Hóa đơn đó đến dưới nhiều hình thức, và sẽ hữu ích khi nhìn từng hình thức riêng biệt thay vì như một nỗi lo mơ hồ.
Thứ nhất là những lỗi bạn chưa bao giờ tìm kiếm. Bỏ qua review không làm lỗi biến mất, nó chỉ trì hoãn việc bạn gặp chúng cho đến khi chúng xuất hiện trước mặt người dùng thay vì trước mặt bạn. Mô hình giỏi nhưng không hoàn hảo, và những lỗi nó tạo ra thường thuộc loại âm thầm: lệch một đơn vị, trường hợp biên không được xử lý, giả định đúng trong một lần test duy nhất của bạn nhưng sai với dữ liệu thực. Bạn không bắt được chúng vì việc bắt chúng chính là bước bạn đã bỏ qua.
Thứ hai là bảo mật. Một mô hình sẽ vui vẻ viết code có lỗ hổng injection, lộ thông tin bí mật, thiếu kiểm tra phân quyền hoặc dùng cấu hình mặc định không an toàn, và nó làm vậy trong khi trông hoàn toàn tự tin và bình thường. Các vấn đề bảo mật chính là loại vô hình cho đến khi bị khai thác, điều đó có nghĩa vibe coding, nơi những vấn đề vô hình lọt qua dễ dàng, gần như được thiết kế để để chúng lọt vào. Với bất cứ thứ gì tiếp xúc với internet hoặc xử lý dữ liệu của người khác, chỉ riêng điều này thường đã đủ để loại vibe coding khỏi danh sách lựa chọn.
Thứ ba là bức tường gỡ lỗi. Vào ngày hệ thống làm bằng vibe coding hỏng theo cách không hiển nhiên, bạn ngồi xuống để sửa và phát hiện ra mình không thể, vì bạn chưa bao giờ hiểu nó hoạt động thế nào. Không có mô hình nào trong đầu để dựa vào, chỉ có một bức tường code được tạo tự động mà bạn đang đọc lần đầu tiên dưới áp lực, trong khi mọi thứ đang cháy. Tốc độ bạn có được lúc đầu giờ phải trả lại kèm lãi vào đúng thời điểm tồi tệ nhất.
Thứ tư là thuế bảo trì. Phần mềm không bao giờ hoàn thành. Nó cần thay đổi, và mỗi thay đổi với code bạn không hiểu là một canh bạc, vì bạn không thể đoán trước nó sẽ ảnh hưởng đến đâu. Nỗi sợ len lỏi vào. Mọi người không còn muốn đụng vào những phần mong manh, công việc tìm đường vòng qua chúng, và hệ thống dần dần vôi hóa thành một thứ về mặt kỹ thuật vẫn chạy nhưng không thể thay đổi được nữa, mà với phần mềm đang sống thì đó là một cái chết từ từ.
Thứ năm là bus factor. Khi mô hình viết ra rồi quên đi, và người duy nhất phát hành nó chưa bao giờ thực sự hiểu nó, thì sự hiểu biết về hệ thống chẳng tồn tại ở đâu cả. Không thể giúp một thành viên mới nắm bắt kiến thức vốn không tồn tại. Chính tác giả ban đầu, sáu tháng sau, thực chất đã là người lạ với code của chính mình. Tổ chức giờ sở hữu một hệ thống mà không con người nào hiểu, một thứ kỳ lạ và nguy hiểm để phụ thuộc vào.
Bên dưới tất cả những điều này là cùng một gốc rễ. Vibe coding tạo ra phần mềm bạn không hiểu, và code bạn không hiểu là code bạn không thể thay đổi an toàn, không thể tự tin bảo mật, và không thể sửa khi nó hỏng. Không điều nào là vấn đề khi thứ đó còn là đồ chơi, và tất cả trở thành vấn đề ngay khoảnh khắc người khác phụ thuộc vào nó. Đó không phải là một codebase, đó là một khoản nợ rủi ro với giao diện người dùng đẹp đẽ. Cảm hứng chưa bao giờ là vấn đề. Vấn đề là cứ lướt theo nó vượt quá điểm mà cái giá của việc sai trở thành thật.
Vì sao thiệt hại cứ tích lũy chồng chất
Mọi chuyện sẽ dễ quản lý hơn nếu những chi phí này vẫn nhỏ và cục bộ. Nhưng không phải vậy. Đặc điểm cốt lõi của sự thấu hiểu bị bỏ qua là nó tích lũy kép, và chính sự tích lũy kép khiến tình hình có thể đi từ ổn sang không thể cứu vãn mà không có một khoảnh khắc rõ ràng nào ở giữa.
Hãy coi nó như một khoản nợ, bởi nó hành xử y hệt như nợ. Mỗi lần chấp nhận code bạn không hiểu, bạn vay một chút tốc độ hôm nay đổi lấy một khoản thanh toán về sau. Một khoản vay nhỏ thì vô hại. Vấn đề là các khoản vay tích tụ lại, và tệ hơn, chúng chồng lên nhau. Những tính năng làm bằng vibe coding mới được xây trên những tính năng làm bằng vibe coding cũ mà cũng chẳng ai hiểu, nên sự thiếu hiểu biết không chỉ cộng dồn mà còn nhân lên. Cuối cùng bạn phải suy luận về một hệ thống mà mỗi lớp đều là một phỏng đoán đặt trên một phỏng đoán khác.
Sự thấu hiểu cũng tự phai nhạt, ngay cả với code bạn từng nắm rõ. Ký ức về cách một thứ hoạt động mờ dần sau vài tuần, và trong một hệ thống làm bằng vibe coding vốn đã chẳng có mấy hiểu biết ngay từ đầu, nên nó nhanh chóng phai về con số không. Khoảng thời gian bạn có thể học code với chi phí thấp lặng lẽ khép lại, và một khi đã khép, học code đồng nghĩa với việc dịch ngược nó từ đầu, điều có thể tốn kém hơn cả viết lại.
Phần tàn nhẫn nhất là hình dạng của đường cong chi phí. Lúc đầu, khi hệ thống còn nhỏ và thay đổi dễ dàng, vibe coding có cảm giác gần như miễn phí, và cảm giác đó là thật, chi phí lúc ấy đúng là thấp. Nhưng chi phí của một hệ thống không ai hiểu tăng vọt khi nó lớn lên và khi ngày càng nhiều thứ phụ thuộc vào nó, nên đến lúc nỗi đau trở nên rõ ràng, bạn đã ở sâu trong vùng đắt đỏ, nắm trong tay một hệ thống lớn mà bạn không hiểu và không dễ gì đủ sức sửa hay thay thế. Quyết định gây hại cho bạn đã được đưa ra một cách rẻ mạt từ nhiều tháng trước, khi việc dừng lại còn dễ dàng và chưa có gì buộc bạn phải hành động. Đó chính là lý do kỷ luật phải đến trước nỗi đau. Khi nỗi đau ập đến, thời điểm hành động với chi phí thấp đã trôi qua.
Chọn chế độ làm việc
Vì vậy, câu hỏi hữu ích không phải là cách nào tốt hơn. Mà là phần việc cụ thể này đòi hỏi cách nào, và điều đó hóa ra phụ thuộc vào hai yếu tố: thứ đó phải tồn tại bao lâu, và khi hỏng thì tốn kém đến mức nào.
Ở góc dưới, nơi thứ đó dùng một lần và rủi ro thấp, hãy vibe coding mà không áy náy rồi đi tiếp. Sự cẩn thận sẽ bị lãng phí, và tốc độ mới là điều cốt yếu. Ở góc trên, nơi thứ đó tồn tại lâu dài và cái giá của thất bại là có thật, hãy engineering bài bản, và chấp nhận sự chậm chạp như cái giá cho một thứ bạn có thể tin tưởng. Hai góc đó thì dễ. Những trường hợp thú vị nằm ở các vùng ranh giới. Một script dùng một lần chạm vào dữ liệu production thì tồn tại ngắn nhưng rủi ro cao, và đáng được cẩn thận ở mức mà bình thường nó không cần, bởi tồn tại ngắn không có nghĩa là vô hại khi phạm vi ảnh hưởng lớn. Một công cụ dùng lâu dài mà chỉ mình bạn dùng nằm ở vị trí khó xử còn lại, lâu dài nhưng rủi ro thấp, và có thể vui vẻ được vibe coding cho ra đời rồi chỉ chỉnh sửa gọn gàng ở những chỗ cụ thể nơi sự thô ráp của nó thực sự bắt đầu gây tốn kém cho bạn.
Có hai kiểu thất bại xuất hiện lặp đi lặp lại, và chúng là hình ảnh phản chiếu của nhau. Một là vibe coding thẳng lên production, khi tốc độ từng giống như một món quà lúc đầu biến thành một hệ thống không ai bảo trì nổi về sau. Hai là thiết kế quá mức cho một prototype cuối tuần, khi sự chặt chẽ vốn dành cho production bóp nghẹt một thử nghiệm lẽ ra nên giữ nhẹ nhàng và nhanh. Cả hai đều xuất phát từ cùng một lỗi gốc, đó là áp dụng một chế độ theo thói quen thay vì chủ động lựa chọn. Người kỹ sư cẩn thận viết test đầy đủ cho một thứ dùng một lần đang mắc cùng loại sai lầm với người làm vibe coding đưa code chưa đọc lên production. Cả hai đều để thói quen mặc định lấn át mức độ rủi ro thực tế trước mặt. Toàn bộ kỹ năng nằm ở việc dừng lại đủ lâu để nhận ra mình thực sự đang ở góc nào, rồi chọn chế độ phù hợp với góc đó thay vì với tính khí của mình.
Kiểm tra hai phút trước khi bắt đầu
Biểu đồ bốn góc là ý tưởng. Còn đây là phiên bản bạn có thể thực sự chạy trong đầu trước khi mở trình soạn thảo. Năm câu hỏi, mỗi câu vài giây, và câu trả lời sẽ chỉ ra chế độ phù hợp.
- Thứ này cần tồn tại bao lâu? Dùng một lần, vài tuần, hay vô thời hạn?
- Ai phụ thuộc vào nó? Chỉ mình bạn, đội của bạn, hay khách hàng và công chúng?
- Điều gì xảy ra nếu nó sai? Một chút phiền toái, mất ít thời gian hoặc tiền bạc, hay tổn hại thực sự như mất dữ liệu, sự cố bảo mật hoặc có người bị tổn thương?
- Nó có chạm vào thứ gì nguy hiểm không? Xác thực, thanh toán, xóa dữ liệu, dữ liệu cá nhân, hay bất cứ thứ gì trên production?
- Sau này bạn có cần thay đổi nó không? Không bao giờ, có thể, hay liên tục?
Đọc câu trả lời rất đơn giản. Nếu mọi câu trả lời đều nằm ở phía dễ, tồn tại ngắn, chỉ mình bạn, sai cũng vô hại, không chạm vào thứ gì nguy hiểm, thì cứ thoải mái vibe coding và đừng cảm thấy áy náy. Khi câu trả lời trượt dần về phía khó, hãy trượt chế độ làm việc về phía engineering tương ứng, và bạn không cần dịch chuyển cả dự án, chỉ những phần xứng đáng mà thôi.
Có một nguyên tắc ưu tiên vượt trên tất cả. Nếu công việc chạm vào thứ gì nguy hiểm, hoặc người khác sẽ phụ thuộc vào nó, hãy xử lý những phần đó cẩn thận bất kể các câu hỏi khác cho kết quả thế nào. Một script một dòng có thể tồn tại ngắn, chỉ dùng cá nhân, khó có khả năng bị thay đổi, nhưng vẫn đáng được đọc kỹ nếu chính dòng đó xóa dữ liệu production. Khi còn phân vân, cái giá của việc sai là câu hỏi quyết định, bởi đó là điều thực tế sẽ buộc bạn phải trả dù bạn có cân nhắc đến nó hay không.
Thực tế trông như thế nào
Những khái niệm trừu tượng sẽ thấm hơn khi gắn với tình huống cụ thể. Ba kịch bản ngắn, mỗi kịch bản cho một cách điều này thường diễn ra.
Bản prototype lặng lẽ trở thành sản phẩm. Một nhà sáng lập vibe coding một ứng dụng chạy được trong một dịp cuối tuần. Khách hàng thích nó, nhiều người đăng ký hơn, và chẳng ai quay lại đọc code, vì việc gì phải đọc, nó chạy mà. Một năm sau, một lỗi tính tiền trừ tiền hai lần của một loạt khách hàng, và khi đội ngũ ngồi xuống để sửa, không ai hiểu phần code thanh toán mà mô hình đã viết một năm trước. Việc sửa lỗi mất một tuần căng thẳng và làm tổn hại niềm tin thực sự. Bài học không phải là vibe coding gây ra lỗi. Vibe coding phiên bản đầu tiên là đúng. Sai lầm là không bao giờ nâng cấp nó lên, và lỗi đó không phải do xui xẻo, nó là khoản lãi có thể đoán trước của một năm bỏ qua sự thấu hiểu.
Script dùng một lần đã chạm vào production. Một kỹ sư cần dọn dẹp một số dòng dữ liệu lỗi trong cơ sở dữ liệu đang vận hành. Đây là việc dùng một lần, sẽ không bao giờ chạy lại, nên bản năng mách bảo cứ vibe coding rồi đi tiếp. Nhưng nó chạm vào dữ liệu production, nghĩa là phạm vi ảnh hưởng cực lớn dù script chỉ dùng một lần. Họ tạo script, chạy mà không đọc phần chọn các dòng, và nó khớp với nhiều dòng hơn dự định rất nhiều do một trường hợp biên họ chưa từng thấy. Dữ liệu thật đã mất. Bài học là tồn tại ngắn và rủi ro thấp không phải là một. Việc này thuộc về góc cần cẩn thận dù chỉ dùng một lần, và đọc mười dòng thực hiện việc xóa sẽ phát hiện ra vấn đề trong ba mươi giây.
Nâng cấp đúng cách. Một nhóm nhỏ vibe coding một tính năng để thử xem người dùng có thực sự muốn nó không. Họ muốn. Thay vì chồng thêm ba tính năng nữa lên nền móng lỏng lẻo, nhóm dành ra đúng một ngày có chủ đích: họ đọc phần lõi, viết test cho những phần quan trọng, thêm logging để thấy nó làm gì trên production, và ghi lại cách nó hoạt động để một thành viên mới có thể tiếp quản. Ngày hôm đó chậm và hơi nhàm chán. Rồi tính năng chạy suốt hai năm không chút trục trặc, được mở rộng mà không ai e ngại, và vẫn vững vàng khi tác giả ban đầu rời đi. Bài học nằm ở phép tính. Việc nâng cấp tốn một ngày và tiết kiệm một năm, và đó chính là bước các đội thường bỏ qua, đó là lý do bỏ qua nó là thói quen đắt giá nhất trong ngành phần mềm.
Bài toán nâng cấp
Trên thực tế, phần lớn phần mềm thực sự không bắt đầu ở một góc rồi nằm yên ở đó. Nó bắt đầu bằng vibe coding rồi được nâng cấp. Bạn vibe coding để khám phá, để tìm ra hình hài của thứ mình làm, và để chứng minh nó đáng được xây dựng. Sau đó, với những phần hóa ra quan trọng, bạn chuyển sang engineering: bạn đọc những gì mô hình đã viết, hiểu nó, test nó và biến nó thành thứ người khác có thể phụ thuộc vào.
Việc nâng cấp là phần các đội thường làm sai, và họ sai theo một cách rất cụ thể. Mối nguy không nằm ở việc vibe coding bản prototype. Đó là cách bắt đầu đúng đắn, và bắt đầu bằng engineering nặng nề mới là sai lầm chúng ta vừa bàn đến. Mối nguy là không bao giờ chuyển đổi, để thứ code khám phá nhanh lặng lẽ trở thành hệ thống production mà không ai dừng lại để gia cố nó. Sự chuyển tiếp hầu như không bao giờ tự báo trước. Không có khoảnh khắc nào bản prototype đứng dậy tuyên bố rằng giờ nó đang gánh vác trọng trách. Nó chỉ dần dần trở thành trụ cột trong khi mọi người bận rộn phát hành tính năng tiếp theo, và một ngày nó hỏng và bạn phát hiện ra, quá muộn, rằng nền móng của một thứ quan trọng chỉ là bản nháp viết trong một buổi chiều.
Lý do điều này phổ biến đến vậy là mọi động lực đều chỉ sai hướng đúng vào lúc bạn nên chuyển đổi. Bản prototype chạy được. Nó đang làm mọi người hài lòng. Dừng lại để viết lại hoặc gia cố thứ code rõ ràng đang hoạt động có cảm giác như đi lùi, như bỏ công sức mà không tạo ra tiến độ mới nào nhìn thấy được. Vì vậy lựa chọn có vẻ hợp lý luôn là tiếp tục thêm tính năng lên nền móng lỏng lẻo, và lựa chọn đó đúng cho đến tận khi nó trở thành thảm họa.
Biết khi nào và làm thế nào để nâng cấp
Phần khó của việc nâng cấp là không có đồng hồ nào báo cho bạn biết khi nào. Vì vậy, thay vì một quy tắc, hãy giữ hai danh sách ngắn: một để nhận ra thời điểm, và một cho những việc cần làm khi thời điểm đó đến.
Dấu hiệu cho thấy thứ đó đã vượt qua lằn ranh, dù bạn có quyết định như vậy hay không:
- Giờ đã có người khác ngoài bạn phụ thuộc vào nó.
- Nó chạm vào tiền thật, dữ liệu thật hoặc người dùng thật.
- Một sự cố ngừng hoạt động giờ sẽ gây tổn thất có thể đo lường được.
- Bạn bắt đầu thấy e ngại khi phải thay đổi nó.
- Một người mới không thể hiểu nó nếu không có bạn ở bên giải thích.
- Nó đã lặng lẽ tồn tại lâu hơn nhiều so với bạn từng dự tính.
Nếu có từ hai dấu hiệu trở lên là đúng, thứ đó đã được nâng cấp rồi, và câu hỏi duy nhất là bạn đối xử với nó đúng như vậy trước hay sau sự cố buộc bạn phải làm thế.
Gia cố thực sự có nghĩa là gì, xếp gần đúng theo mức độ hiệu quả:
- Đọc toàn bộ một lần, thật chậm, cho đến khi có một người thực sự hiểu nó.
- Đọc kỹ hai lần các phần nhạy cảm về bảo mật: bất cứ thứ gì liên quan đến xác thực, phân quyền, thanh toán, dữ liệu cá nhân hoặc xóa dữ liệu.
- Viết test cho những hành vi quan trọng, để một thay đổi trong tương lai không thể âm thầm phá vỡ chúng.
- Thêm logging hoặc tracing, để bạn thấy nó làm gì trên production thay vì phải đoán.
- Bật các bước kiểm tra tự động chi phí thấp: kiểu dữ liệu, linter và trình biên dịch.
- Ghi lại cách nó hoạt động và lý do, để sự thấu hiểu tồn tại ở nơi khác ngoài trí nhớ của một người.
- Thay thế những phần quá rối rắm để hiểu nổi thay vì vá víu xung quanh chúng.
Bạn không cần làm tất cả cùng lúc, và cố làm vậy có thể chính là một dạng thiết kế quá mức. Hãy bắt đầu bằng việc thấu hiểu và viết test cho những phần rủi ro nhất, những chỗ mà sai thì tốn kém, rồi để phần còn lại theo sau khi thứ đó chứng minh nó xứng đáng được đầu tư.
Cách vibe coding mà không bị bỏng tay
Tất cả những điều trên có thể khiến vibe coding nghe như một cái bẫy cần tránh. Không phải vậy. Đó là một công cụ mạnh mẽ mà bạn có thể dùng an toàn hơn nhiều với vài thói quen gần như không tốn gì và vẫn giữ được phần lớn tốc độ. Mục tiêu không phải là ngừng vibe coding. Mà là vibe coding theo cách không âm thầm thế chấp tương lai của bạn.
Giữ phạm vi ảnh hưởng nhỏ. Thói quen bảo vệ hiệu quả nhất là đảm bảo khi code làm bằng vibe coding sai, thiệt hại được khoanh vùng. Hãy chạy nó ở nơi không thể chạm vào dữ liệu production hay tiền thật, cấp cho nó quyền hạn hẹp nhất đủ để làm việc, và đặt ranh giới thực sự giữa phần bạn đã vibe coding và những phần bạn phụ thuộc vào. Phần lớn những câu chuyện kinh hoàng thực ra không phải về code tồi. Mà là về code tồi có quá nhiều quyền truy cập.
Mặc định coi nó là đồ dùng một lần. Hãy bắt đầu với giả định rằng bản prototype sẽ bị vứt đi, vì phần lớn đều nên như vậy, và bạn sẽ đưa ra những lựa chọn khác và lành mạnh hơn so với khi ngầm định giữ nó lại. Những bản xứng đáng có thể được nâng cấp sau, một cách có chủ đích, qua cánh cửa của engineering thực thụ. Điều bạn muốn tránh là thứ vô tình được giữ lại, bản prototype trở thành vĩnh viễn chỉ vì chưa ai từng quyết định rằng nó nên như vậy.
Đọc những phần có thể gây hại. Bạn không cần đọc mọi thứ để tránh những kết cục tồi tệ nhất. Bạn cần đọc những phần mà một sai sót sẽ tốn kém: bất cứ thứ gì liên quan đến xác thực, phân quyền, thanh toán, xóa dữ liệu hoặc dữ liệu người dùng. Phần còn lại lướt qua cũng được, nhưng hãy chậm lại và thực sự hiểu số ít những chỗ mà một sai lầm đầy tự tin của mô hình sẽ trở thành vấn đề thực sự. Đây là nguyên tắc 80/20 của vibe coding an toàn.
Bổ sung test sau đó cho bất cứ thứ gì bạn giữ lại. Ngay khi một phần làm bằng vibe coding có vẻ sẽ ở lại, hãy viết test cho những gì nó phải làm, kể cả khi bạn viết chúng sau code. Test là cách bạn cố định hành vi để sau này có thể thay đổi code mà không sợ hãi, và cũng là cách để biết bạn có thực sự hiểu code làm gì hay không, bởi viết một bài test thực sự cho code bạn không hiểu khó đến bất ngờ.
Dựa vào các bước kiểm tra tự động chi phí thấp. Trình kiểm tra kiểu, linter và trình biên dịch bắt được cả một nhóm lỗi của mô hình mà không tốn gì, không cần bạn đọc một dòng nào. Chúng là thứ gần nhất với việc có được cả tốc độ lẫn sự an toàn cùng lúc, và bật chúng lên là một trong những việc mang lại hiệu quả cao nhất khi bạn làm việc nhanh.
Không thói quen nào trong số này biến vibe coding thành engineering, và chúng cũng không nhằm mục đích đó. Chúng là những cơ chế bảo vệ cho phép bạn giữ phần lớn tốc độ trong khi cắt bỏ phần đuôi của những kết cục biến một buổi chiều vui vẻ thành một quý đầy đau đớn. Tinh thần chung của tất cả là như nhau: nhanh ở nơi an toàn để nhanh, và dành chút ít sự cẩn thận của bạn đúng vào nơi mà sai sẽ thực sự gây tổn hại.
Làm tốt các chế độ ở giữa
Phần lớn công việc thực tế không nằm ở thái cực nào. Nó nằm ở hai chế độ giữa trên dải liên tục, có AI hỗ trợ và dựa trên đặc tả, và cả hai đều đáng được áp dụng chút kỹ thuật. Dưới đây là cách khai thác mỗi chế độ hiệu quả hơn.
Review những gì mô hình viết mà không mất cả ngày:
- Đọc diff như một người review, không phải một người đọc. Hãy hỏi điều gì có thể sai ở đây, chứ không chỉ hỏi trông thế này có hợp lý không.
- Tập trung sự chú ý vào những phần rủi ro. Bạn không cần soi xét boilerplate kỹ như phần logic chạm vào dữ liệu hay tiền bạc.
- Hãy nghi ngờ sự tự tin. Kết quả nguy hiểm nhất của mô hình không phải là code trông có vẻ sai, mà là code sai nhưng trông hoàn toàn bình thường.
- Yêu cầu mô hình giải thích code của chính nó, rồi đối chiếu lời giải thích với những gì code thực sự làm. Những chỗ vênh nhau là nơi lỗi và sự hiểu lầm của chính bạn ẩn nấp.
- Giữ mỗi thay đổi đủ nhỏ để bạn thực sự review được. Một diff khổng lồ được tạo tự động là thứ bạn sẽ duyệt cho qua theo quán tính, mà như vậy thì chỉ là vibe coding thêm vài bước.
Nói cho mô hình biết bạn muốn gì, để nó xây đúng thứ cần xây:
- Nói thật chính xác trước khi yêu cầu code. Đầu vào, đầu ra, các trường hợp biên, các ràng buộc. Yêu cầu mơ hồ sẽ nhận về code nghe hợp lý nhưng sai một cách tinh vi.
- Đưa ra ví dụ về hành vi đúng. Vài trường hợp cụ thể thể hiện ý định của bạn tốt hơn một đoạn mô tả dài.
- Nói rõ những yêu cầu không hiển nhiên, yêu cầu về hiệu năng, quy tắc bảo mật, điều tuyệt đối không được xảy ra. Mô hình sẽ không tự suy ra điều bạn không nói.
- Kiểm chứng kết quả so với những gì bạn yêu cầu, tốt nhất là bằng test, thay vì tin rằng nó đã khớp.
- Coi đặc tả là sản phẩm lâu dài. Nó tồn tại lâu hơn bất kỳ lần tạo code nào và cho phép bạn tạo lại hoặc refactor sau này mà không phải bắt đầu từ phỏng đoán.
Hai thói quen này thực chất là cùng một thói quen dưới hai vai trò. Hãy ở đủ gần công việc để giữ phán đoán của mình trong vòng lặp, dù bạn đang kiểm tra kết quả sau hay định hình nó từ trước. Sự gần gũi đó chính là toàn bộ khác biệt giữa sử dụng mô hình và bị mô hình sử dụng.
Kỹ năng đang thực sự thay đổi
Lùi lại khỏi những lời khuyên cụ thể, có một sự dịch chuyển lớn hơn nằm bên dưới tất cả, đáng được gọi tên vì nó thay đổi ý nghĩa của việc giỏi xây dựng phần mềm.
Trong phần lớn lịch sử của nghề, kỹ năng khan hiếm và giá trị là viết code, tạo ra các chỉ dẫn chính xác bằng một ngôn ngữ hình thức. Kỹ năng đó đang lặng lẽ trở nên dồi dào. Mô hình có thể tạo ra các chỉ dẫn, thường nhanh hơn và đôi khi tốt hơn con người. Điều không trở nên dồi dào, mà thực tế còn giá trị hơn, là mọi thứ xung quanh việc viết: biết nên xây gì, đánh giá thứ đã xây có tốt hay không, hiểu các mảnh ghép khớp với nhau thế nào, và quyết định nên tin vào điều gì.
Đó là lý do người kỹ sư biết review và định hướng không bị mô hình thay thế mà được nó khuếch đại. Điểm nghẽn dịch chuyển từ khâu sản xuất sang khâu phán đoán. Những câu hỏi quan trọng không còn là bạn có viết được hàm này không, mà là thứ này có nên tồn tại không, phần triển khai này có vững chắc không, nó sẽ làm gì với đầu vào mà bạn chưa nghĩ tới, và đây là nơi một sai lầm rẻ mạt hay thảm khốc. Đó là những câu hỏi về gu thẩm mỹ, tư duy hệ thống và kiểm chứng, và chúng chính là những câu hỏi mà vibe coding cám dỗ bạn bỏ qua.
Có một rủi ro thực sự ẩn trong sự dịch chuyển này, nhất là với những người đang học nghề lúc này. Nếu bạn chỉ vibe coding, bạn sẽ không bao giờ xây dựng được sự thấu hiểu cho phép bạn đánh giá kết quả, mà phán đoán lại chính là kỹ năng đang trở thành toàn bộ công việc. Bạn có thể rơi vào tình trạng tạo ra được chương trình chạy được nhưng không thể phân biệt cái vững chắc với cái mong manh, một vị thế yếu khi vững chắc hay mong manh chính là toàn bộ cuộc chơi. Lối thoát không phải là từ chối công cụ. Mà là dùng chúng trong khi vẫn giữ mình trong vòng lặp đủ để tiếp tục học hỏi, thỉnh thoảng đọc code ngay cả khi có thể bỏ qua, hỏi mô hình tại sao chứ không chỉ cái gì, để sự hiểu biết mà mô hình có không trở thành sự hiểu biết chẳng hề tồn tại trong bạn.
Những người xây dựng thành công sẽ là những người để mô hình viết nhưng không để nó thấu hiểu thay mình. Họ sẽ nhanh vì công cụ nhanh, và đáng tin cậy vì họ chưa bao giờ thuê ngoài phần vốn thực sự là của mình phải giữ.
Mô hình tốt hơn có khiến điều này trở nên vô nghĩa?
Có một phản biện hợp lý xuyên suốt tất cả những điều trên. Các mô hình ngày càng tốt hơn. Nếu chúng đủ tốt, liệu toàn bộ sự phân biệt có sụp đổ, để vibe coding đơn giản trở thành cách mọi người xây dựng mọi thứ?
Đó là câu hỏi đúng, và câu trả lời thành thật là mô hình tốt hơn sẽ dịch chuyển lằn ranh chứ không xóa bỏ nó. Khi mô hình cải thiện, nhiều thứ hơn trở nên an toàn để vibe coding, vì kết quả đúng thường xuyên hơn và phần đuôi của những thảm họa mỏng dần. Ranh giới trong biểu đồ bốn góc trượt ra ngoài, và công việc năm ngoái cần engineering cẩn thận thì năm nay có thể vibe coding. Điều đó là thật, sẽ tiếp tục diễn ra, và thực sự là điều tốt.
Nhưng bản thân sự phân biệt không phụ thuộc vào việc mô hình giỏi đến đâu. Nó phụ thuộc vào cái giá của việc sai, và cái giá đó do thế giới thực quyết định, không phải do mô hình. Dù mô hình có năng lực đến đâu, vẫn sẽ có những hệ thống mà một sự cố hiếm hoi là thảm họa, nơi cần có người chịu trách nhiệm hiểu những gì đã được triển khai, nơi câu hỏi không phải là khả năng thứ này đúng cao đến mức nào mà là chúng ta có chấp nhận được trường hợp nó sai hay không. Trong những bối cảnh đó, bạn vẫn sẽ cần kiểm chứng và thấu hiểu, không phải vì bạn không tin mức trung bình của mô hình, mà vì mức trung bình không phải là điều quan trọng khi trường hợp xấu nhất đủ nghiêm trọng. Một mô hình đúng chín mươi chín phần trăm thời gian là tuyệt vời nhưng vẫn không phải thứ bạn chấp nhận mà không đọc khi một phần trăm còn lại xóa sạch hồ sơ của một bệnh viện.
Còn có vấn đề của chính sự thấu hiểu, điều không hề bớt cần thiết chỉ vì code trở nên dễ tạo ra hơn. Phải có người có khả năng suy luận về một hệ thống, giải thích nó, phát triển nó và chịu trách nhiệm về nó, và một cỗ máy tạo code hoàn hảo không cung cấp điều đó. Nó cung cấp code. Trách nhiệm của con người trong việc thấu hiểu những gì mình đã xây dựng và phát hành không phải là hạn chế của các mô hình hiện tại mà mô hình tốt hơn sẽ gỡ bỏ. Đó là bản chất của việc nhận lấy trách nhiệm.
Vì vậy lằn ranh sẽ tiếp tục dịch chuyển, và phản ứng khôn ngoan là dịch chuyển theo nó, vibe coding tập hợp ngày càng lớn những thứ giờ đã an toàn để vibe coding, và dành engineering thực thụ cho tập hợp đang thu hẹp nhưng không bao giờ trống rỗng những thứ mà sai lầm là không thể gánh nổi. Điều sẽ không thay đổi là nhu cầu biết mình đang ở trong tập hợp nào.
Tổng hợp
Những người xây dựng giỏi nhất hiện nay không phải là những người đã chọn phe. Họ là những người nắm vững cả hai chế độ và chuyển đổi giữa chúng tự nhiên đến mức gần như không nhận ra mình đang làm vậy. Họ vibe coding thử nghiệm buổi sáng mà không chút áy náy, và engineering thay đổi production buổi chiều mà không hề đi tắt, và họ không nhầm lẫn giữa hai việc. Sự thành thạo nằm ở việc chuyển đổi, không phải ở lòng trung thành với bên nào.
Điều làm nên sự thành thạo đó là bỏ hẳn lăng kính đạo đức. Vibe coding không phải là liều lĩnh và engineering không phải là đức hạnh. Chúng là một công cụ nhanh, thoải mái và một công cụ chậm, cẩn thận, và một người xây dựng chỉ sở hữu một trong hai sẽ bị giới hạn y như một người thợ mộc chỉ có mỗi cây búa. Sai lầm không bao giờ là việc dùng một trong hai. Sai lầm là dùng sai công cụ cho thời điểm, rồi bảo vệ lựa chọn đó như thể nó là nguyên tắc chứ không phải một thói quen bạn chưa từng xem xét.
Rốt cuộc, lằn ranh phân chia chưa bao giờ là vibe coding đối đầu engineering. Mà là thiếu suy nghĩ đối đầu có chủ đích. Bạn có thể vibe coding một cách chín chắn, biết chính xác vì sao tốc độ là lựa chọn đúng ở đây, bạn đang chọn không biết điều gì, và bạn đã giữ phạm vi ảnh hưởng đủ nhỏ ở đâu để việc không biết là an toàn. Bạn cũng có thể engineering một cách thiếu suy nghĩ, chất chồng test, quy trình và thủ tục không ai cần vì sự chặt chẽ đã trở thành phản xạ thay vì một sự phán đoán. Cả tốc độ lẫn sự chặt chẽ đều không phải là đức tính. Sự phán đoán mới là đức tính.
Vì vậy, điều đáng để giỏi không phải là vibe coding, cũng không phải là engineering. Đó là hành động thành thật, không hào nhoáng, nhìn vào nhiệm vụ trước mặt và tự hỏi thứ này phải tồn tại bao lâu, ai phụ thuộc vào nó, và nếu hỏng thì tổn thất bao nhiêu, rồi chọn chế độ làm việc từ câu trả lời thay vì từ tâm trạng. Làm điều đó một cách nhất quán, cuộc tranh luận cũ sẽ tự tan biến. Chưa bao giờ có phe đúng. Chỉ có công cụ đúng cho công việc, và sự sáng suốt để phân biệt đâu là đâu.




