Lời biên tập: Trong bối cảnh AI generative đang gia nhập nhanh chóng vào lĩnh vực kỹ thuật phần mềm, tâm lý ngành đang chuyển từ "kinh ngạc về năng lực" sang "lo lắng về hiệu suất". Viết không đủ nhanh, sử dụng không đủ nhiều, tự động hóa không triệt để, dường như đều khiến người ta cảm thấy áp lực bị đào thải. Nhưng khi Agent mã hóa thực sự bước vào môi trường sản xuất, một số vấn đề thực tế hơn bắt đầu lộ diện: lỗi bị phóng đại, độ phức tạp mất kiểm soát, hệ thống dần trở nên khó hiểu, sự cải thiện hiệu suất không chuyển hóa tỷ lệ thuận thành sự nâng cao chất lượng.
Bài viết dựa trên thực tiễn tuyến đầu, đưa ra suy ngẫm điềm tĩnh về cơn sốt "agentic coding" này. Tác giả chỉ ra, Agent sẽ không học hỏi từ sai lầm như con người, trong tình trạng thiếu nút thắt cổ chai và cơ chế phản hồi, vấn đề nhỏ sẽ nhanh chóng bị phóng đại; trong khi ở kho mã phức tạp, góc nhìn cục bộ và khả năng truy hồi hạn chế của nó lại càng làm trầm trọng thêm sự hỗn loạn trong cấu trúc hệ thống. Bản chất của những vấn đề này không nằm ở bản thân công nghệ, mà ở chỗ con người trong sự thúc đẩy của lo lắng, đã trao đi sự phán đoán và kiểm soát quá sớm.
Vì vậy, thay vì chìm đắm trong nỗi lo "liệu có phải hoàn toàn ôm lấy AI", hãy hiệu chỉnh lại mối quan hệ giữa người và công cụ: để Agent đảm nhận các nhiệm vụ cục bộ, có thể kiểm soát, trong khi nắm chặt việc thiết kế hệ thống, kiểm soát chất lượng và quyết định then chốt trong tay mình. Trong quá trình này, "chậm lại" ngược lại trở thành một năng lực, nó có nghĩa là bạn vẫn hiểu hệ thống, có thể đưa ra sự lựa chọn, và vẫn giữ được cảm giác làm chủ công việc.
Trong thời đại công cụ không ngừng tiến hóa, thứ thực sự khan hiếm, có lẽ không phải là khả năng tạo nhanh hơn, mà là khả năng phán đoán tính phức tạp, và sự kiên định trong việc lựa chọn giữa hiệu suất và chất lượng.
Dưới đây là nguyên văn:
Khoảng một năm trước, những Agent mã hóa thực sự có thể giúp bạn "làm dự án hoàn chỉnh từ đầu đến cuối" bắt đầu xuất hiện. Trước đó cũng đã có những công cụ như Aider, Cursor thời kỳ đầu, nhưng chúng giống trợ lý hơn là "đại lý" (agent). Công cụ thế hệ mới cực kỳ hấp dẫn, nhiều người cũng dành rất nhiều thời gian ngoài giờ để làm tất cả những dự án mà họ luôn muốn làm nhưng không có thời gian.
Tôi nghĩ bản thân điều đó không có vấn đề gì. Dùng thời gian ngoài giờ để làm gì đó vốn đã rất vui, và hầu hết thời gian bạn cũng không cần quá quan tâm đến chất lượng mã và khả năng bảo trì. Điều này cũng cho bạn một con đường học tập công nghệ mới.
Vào kỳ nghỉ Giáng sinh, Anthropic và OpenAI còn phát một số "hạn mức miễn phí", hút mọi người vào như máy đánh bạc. Đối với nhiều người, đây là lần đầu tiên thực sự trải nghiệm phép thuật "Agent viết mã". Người tham gia ngày càng đông.
Ngày nay, Agent mã hóa cũng bắt đầu đi vào kho mã sản xuất. 12 tháng trôi qua, chúng ta bắt đầu thấy hậu quả của sự "tiến bộ" này. Dưới đây là quan điểm của tôi hiện tại.
Mọi thứ đều hỏng hết rồi
Mặc dù phần lớn chỉ là kinh nghiệm, nhưng phần mềm hiện nay thực sự mang lại cảm giác "có thể vỡ tan bất cứ lúc nào". Khả năng sử dụng 98% đang từ ngoại lệ trở thành trạng thái bình thường, ngay cả đối với các dịch vụ lớn. Giao diện người dùng tràn ngập đủ loại bug kỳ lạ, đáng lẽ ra đội ngũ QA phải phát hiện ngay.
Tôi thừa nhận, tình trạng này đã tồn tại trước khi Agent xuất hiện. Nhưng bây giờ, vấn đề rõ ràng đang tăng tốc.
Chúng ta không thấy tình hình thực tế bên trong công ty, nhưng thỉnh thoảng vẫn có một số thông tin rò rỉ, như vụ "AWS ngừng hoạt động do AI" được đồn đại. Amazon Web Services sau đó ngay lập tức "sửa lại" thông tin, nhưng ngay sau đó lại khởi động một kế hoạch tái cấu trúc 90 ngày nội bộ.
Satya Nadella (CEO Microsoft) gần đây cũng luôn nhấn mạnh, ngày càng có nhiều mã trong công ty được viết bởi AI. Mặc dù không có bằng chứng trực tiếp, nhưng thực sự có cảm giác: chất lượng Windows đang đi xuống. Thậm chí từ một số blog do chính Microsoft phát hành, dường như họ cũng mặc định điều này.
Những công ty tuyên bố "100% mã sản phẩm được tạo bởi AI", hầu như luôn xuất ra những sản phẩm tồi tệ nhất mà bạn có thể tưởng tượng. Không nhắm vào ai cả, nhưng rò rỉ bộ nhớ tính bằng GB, giao diện người dùng hỗn loạn, chức năng thiếu sót, sập thường xuyên... Tất cả những điều này tuyệt đối không phải là "bảo chứng chất lượng" như họ nghĩ, càng không phải là minh chứng tích cực cho việc "để Agent làm hết mọi thứ cho bạn".
Riêng tư, bạn sẽ ngày càng nghe thấy, dù là công ty lớn hay nhóm nhỏ, đều nói một điều: họ đã bị "Agent viết mã" dồn vào đường cùng. Không có đánh giá mã, giao quyết định thiết kế cho Agent, rồi chất đống lên một đống tính năng không ai cần - kết cục tự nhiên không tốt.
Tại sao chúng ta không nên sử dụng Agent như vậy
Chúng ta gần như đã từ bỏ mọi kỷ luật kỹ thuật và phán đoán chủ quan, chuyển sang một phương thức làm việc "gây nghiện": mục tiêu duy nhất - tạo ra nhiều mã nhất trong thời gian ngắn nhất, hậu quả thế nào hoàn toàn không nằm trong cân nhắc.
Bạn đang xây một lớp điều phối, để chỉ huy một đội quân Agent tự động. Bạn cài Beads, nhưng hoàn toàn không biết bản chất nó gần như là một "phần mềm độc hại" không thể gỡ bỏ. Chỉ vì trên mạng nói "mọi người đều làm vậy". Không làm vậy bạn "sẽ tiêu tan" (ngmi).
Bạn đang tự hao mòn trong vòng lặp "búp bê Nga".
Xem này - Anthropic dùng một nhóm Agent làm một trình biên dịch C, mặc dù hiện còn vấn đề, nhưng thế hệ mô hình tiếp theo chắc chắn sẽ sửa được, phải không?
Lại xem - Cursor dùng một đám lớn Agent làm một trình duyệt, mặc dù hiện cơ bản không dùng được, còn cần người thỉnh thoảng can thiệp thủ công, nhưng thế hệ mô hình tiếp theo chắc chắn sẽ giải quyết được, phải không?
"Phân tán", "chia để trị", "hệ thống tự trị", "nhà máy không đèn", "giải quyết vấn đề phần mềm trong sáu tháng", "SaaS đã chết, bà tôi vừa dùng Claw dựng một Shopify"...
Những câu chuyện kể nghe rất đã.
Tất nhiên, cách này đối với dự án phụ (side project) hầu như không ai dùng (kể cả bạn) của bạn, có lẽ thực sự "vẫn chạy được". Có lẽ, thực sự tồn tại một thiên tài nào đó, có thể dùng cách này tạo ra một sản phẩm phần mềm không rác rưởi, thực sự được người dùng sử dụng. Nếu bạn là người đó, thì tôi thực lòng khâm phục.
Nhưng ít nhất trong vòng kết nối các nhà phát triển xung quanh tôi, tôi chưa thấy phương pháp này thực sự hiệu quả. Tất nhiên, có lẽ chỉ là chúng tôi đều quá kém.
Lỗi liên tục chồng chất trong tình trạng không học hỏi, không nút thắt, bùng phát trễ
Vấn đề của Agent là: chúng sẽ mắc lỗi. Bản thân điều đó không có gì, con người cũng mắc lỗi. Có thể chỉ là một số lỗi tính đúng đắn, dễ nhận biết, dễ sửa, bổ sung thêm một bài kiểm tra hồi quy thì càng ổn định. Cũng có thể là một số mùi mã mà linter không bắt được: ở đây một phương thức vô dụng, ở kia một kiểu không hợp lý, còn có mã trùng lặp... Những thứ này xét riêng lẻ đều không ảnh hưởng gì lớn, nhà phát triển con người cũng mắc những lỗi nhỏ như vậy.
Nhưng "máy móc" không phải người. Con người lặp lại cùng một lỗi vài lần sau, thường sẽ học được cách không mắc lại - hoặc bị mắng cho tỉnh, hoặc trong quá trình học thực sự đã sửa được.
Mà Agent không có khả năng học hỏi đó, ít nhất mặc định là không. Nó sẽ lặp đi lặp lại cùng một lỗi, thậm chí còn có thể "sáng tạo" ra sự kết hợp kỳ diệu của các lỗi khác nhau dựa trên dữ liệu huấn luyện.
Bạn tất nhiên có thể cố "huấn luyện" nó: viết quy tắc trong AGENTS.md, để nó đừng mắc lỗi này nữa; thiết kế một hệ thống bộ nhớ phức tạp, để nó truy vấn lỗi lịch sử và thực tiễn tốt nhất. Điều này trong một số loại vấn đề cụ thể thực sự hiệu quả. Nhưng điều kiện tiên quyết là - bạn phải quan sát thấy nó mắc lỗi này trước.
Khác biệt then chốt hơn nằm ở: con người là nút thắt cổ chai, còn Agent thì không.
Con người không thể nhổ ra hai vạn dòng mã trong vài giờ. Dù tần suất mắc lỗi không thấp, một ngày cũng chỉ có thể đưa vào số lượng lỗi hạn chế, sự tích lũy của những lỗi này là chậm. Thông thường, khi "nỗi đau do lỗi" tích lũy đến một mức độ nhất định, con người (theo bản năng ghét đau đớn) sẽ dừng lại để sửa. Hoặc người bị thay thế, để người khác sửa. Tóm lại, vấn đề sẽ được xử lý.
Nhưng khi bạn dùng cả một đội quân Agent được điều phối chỉn chu, thì không có nút thắt cổ chai, cũng không có "cảm giác đau". Những lỗi nhỏ vốn không đáng kể này, sẽ chồng chất lên với tốc độ không bền vững. Bạn đã bị loại khỏi vòng lặp, thậm chí không biết những vấn đề nhỏ tưởng chừng vô hại này, đã phát triển thành một thứ to lớn. Đến khi bạn thực sự cảm nhận được nỗi đau, thường đã quá muộn.
Cho đến một ngày, bạn muốn thêm một tính năng mới, lại phát hiện kiến trúc hệ thống hiện tại (về bản chất đã là sự chồng chất của sai lầm) hoàn toàn không hỗ trợ sửa đổi; hoặc người dùng bắt đầu phàn nàn điên cuồng, vì bản phát hành mới nhất gặp vấn đề, thậm chí mất dữ liệu.
Lúc này bạn mới nhận ra: Bạn đã không thể tin tưởng vào đống mã này nữa.
Tệ hơn nữa, hàng nghìn bài kiểm tra đơn vị, kiểm tra nhanh, kiểm tra end-to-end do Agent tạo ra, cũng không còn đáng tin. Cách duy nhất còn có thể đánh giá "hệ thống có hoạt động bình thường không", chỉ còn là kiểm tra thủ công.
Chúc mừng, bạn đã tự hại mình (và công ty) rồi.
Kẻ buôn bán sự phức tạp
Bạn đã hoàn toàn không biết hệ thống đang xảy ra chuyện gì, vì bạn đã trao quyền kiểm soát cho Agent. Mà Agent, về bản chất là đang "buôn bán sự phức tạp". Chúng đã thấy rất nhiều quyết định kiến trúc tồi tệ trong dữ liệu huấn luyện, trong quá trình học tăng cường cũng không ngừng củng cố những mẫu hình đó. Bạn để nó thiết kế hệ thống, kết quả có thể đoán được.
Cuối cùng bạn nhận được là: cả một hệ thống cực kỳ phức tạp, hỗn tạp đủ loại bắt chước vụng về về "thực tiễn tốt nhất ngành", mà bạn trước khi vấn đề mất kiểm soát, đã không hề hạn chế.
Nhưng vấn đề không dừng lại ở đó. Các Agent của bạn không chia sẻ quá trình thực thi với nhau, cũng không nhìn thấy toàn bộ kho mã, càng không hiểu quyết định mà bạn hoặc Agent khác đã đưa ra trước đó. Vì vậy, quyết định của chúng luôn là "cục bộ".
Điều này trực tiếp dẫn đến những vấn đề đã đề cập phía trên: lượng lớn mã trùng lặp, cấu trúc trừu tượng vì trừu tượng, đủ loại không nhất quán. Những vấn đề này không ngừng chồng chất, cuối cùng hình thành một hệ thống phức tạp không thể cứu vãn.
Điều này thực ra rất giống kho mã cấp doanh nghiệp do con người viết. Chỉ có điều sự phức tạp đó thường là kết quả tích lũy qua nhiều năm: nỗi đau được phân tán trên số đông người, mỗi người đều chưa đến điểm tới hạn "phải sửa", bản thân tổ chức lại có khả năng chịu đựng cao, thế là tính phức tạp cùng tổ chức "cùng nhau tiến hóa".
Nhưng trong sự kết hợp giữa con người + Agent, quá trình này sẽ được đẩy nhanh cực độ. Hai người, cộng với một đống Agent, vài tuần là đạt đến mức độ phức tạp này.
Tỷ lệ truy hồi của tìm kiếm Agentic rất thấp
Bạn có thể kỳ vọng vào Agent để "dọn dẹp đống hỗn độn", giúp bạn tái cấu trúc, tối ưu hóa, làm cho hệ thống sạch sẽ. Nhưng vấn đề là: chúng đã không làm được nữa rồi.
Bởi vì kho mã quá lớn, độ phức tạp quá cao, mà chúng luôn chỉ nhìn thấy cục bộ. Đây không chỉ đơn giản là cửa sổ ngữ cảnh không đủ lớn, hoặc cơ chế ngữ cảnh dài thất bại trước hàng triệu dòng mã. Vấn đề còn ẩn giấu hơn.
Trước khi Agent cố gắng sửa chữa hệ thống, nó phải tìm tất cả mã cần sửa đổi, và các triển khai đã có thể tái sử dụng. Bước này, chúng ta gọi là agentic search (tìm kiếm Agentic).
Agent làm việc này như thế nào, phụ thuộc vào công cụ bạn cung cấp cho nó: có thể là Bash + ripgrep, có thể là chỉ mục mã có thể truy vấn, dịch vụ LSP, cơ sở dữ liệu vector...
Nhưng dùng công cụ gì, bản chất đều giống nhau: kho mã càng lớn, tỷ lệ truy hồi càng thấp. Mà tỷ lệ truy hồi thấp đồng nghĩa: Agent không thể tìm thấy tất cả mã liên quan, tự nhiên cũng không thể thực hiện sửa đổi chính xác.
Đây cũng là lý do tại sao ngay từ đầu những lỗi nhỏ "mùi mã" đó xuất hiện, nó không tìm thấy triển khai đã có, thế là tạo lại bánh xe, đưa vào sự không nhất quán. Cuối cùng, những vấn đề này sẽ không ngừng lan rộng, chồng chất, nở ra một bông hoa "thối" cực kỳ phức tạp.
Vậy chúng ta nên tránh tất cả những điều này như thế nào?
Chúng ta nên cộng tác với Agent như thế nào (ít nhất hiện tại)
Agent mã hóa giống như nàng tiên cá, dùng tốc độ tạo mã cực nhanh và thứ trí thông minh "ngắt quãng nhưng thỉnh thoảng lại gây ấn tượng" đó để thu hút bạn. Chúng thường có thể hoàn thành một số nhiệm vụ đơn giản với tốc độ đáng kinh ngạc, chất lượng cao. Vấn đề thực sự bắt đầu, là khi bạn nảy ra ý nghĩ như vậy - "Thứ này mạnh quá, máy tính, thay ta làm việc đi!"
Giao nhiệm vụ cho Agent bản thân không có vấn đề gì. Nhiệm vụ Agent tốt thường có vài đặc điểm: phạm vi có thể được giới hạn tốt, không cần hiểu toàn bộ hệ thống; nhiệm vụ là vòng kín, nghĩa là Agent có thể tự đánh giá kết quả; đầu ra không phải đường dẫn then chốt, chỉ là một số công cụ tạm thời hoặc phần mềm sử dụng nội bộ, không ảnh hưởng người dùng thực hoặc doanh thu; hoặc bạn chỉ cần một "vịt cao su" để hỗ trợ suy nghĩ - về bản chất là đem ý tưởng của bạn đi va chạm một vòng với kiến thức nén của internet và dữ liệu tổng hợp.
Nếu thỏa mãn những điều kiện này, thì đó là nhiệm vụ thích hợp để giao cho Agent, với điều kiện, bạn với tư cách con người, vẫn là người kiểm soát chất lượng cuối cùng.
Ví dụ, dùng phương pháp auto-research do Andrej Karpathy đề xuất để tối ưu hóa thời gian khởi động ứng dụng? Tốt. Nhưng điều kiện tiên quyết là bạn biết rõ, mã nó nhổ ra tuyệt đối không có tính khả dụng sản xuất. Auto-research hiệu quả, là vì bạn đã cho nó một hàm đánh giá, để nó có thể tối ưu hóa xung quanh một chỉ số (ví dụ thời gian khởi động hoặc loss). Nhưng hàm đánh giá này chỉ bao phủ một phạm vi rất hẹp. Agent sẽ bỏ qua tất cả các chỉ số không nằm trong hàm đánh giá một cách đường hoàng, ví dụ chất lượng mã, độ phức tạp hệ thống, thậm chí trong một số trường hợp ngay cả tính đúng đắn cũng có thể bỏ qua - nếu bản thân hàm đánh giá của bạn có vấn đề.
Tư tưởng cốt lõi thực ra rất đơn giản: để Agent làm những việc nhàm chán, không khiến bạn học được điều gì mới, hoặc những công việc thăm dò mà bạn vốn không có thời gian thử. Sau đó do bạn đánh giá kết quả, chọn ra phần thực sự hợp lý, chính xác, rồi hoàn thành triển khai cuối cùng. Tất nhiên, bước cuối này bạn cũng có thể nhờ Agent hoàn thành.
Nhưng tôi muốn nhấn mạnh hơn: Thực sự, nên chậm lại một chút.
Cho bản thân thời gian để suy nghĩ, bạn thực sự đang làm gì, tại sao làm. Cho bản thân một cơ hội để nói "không", "không, cái này chúng ta không cần." Đặt cho Agent một giới hạn rõ ràng: mỗi ngày cho phép nó tạo bao nhiêu mã, lượng này nên phù hợp với khả năng bạn thực sự có thể xem xét. Tất cả phần quyết định "hình thái tổng thể" của hệ thống, như kiến trúc, API... đều nên tự viết. Bạn có thể dùng tự động hoàn thành để tìm cảm giác "viết mã thủ công", cũng có thể lập trình cặp với Agent, nhưng điểm then chốt là: bạn phải ở trong mã.
Bởi vì, tự viết mã, hoặc nhìn nó từng bước được xây dựng, bản thân quá trình này mang lại một cảm giác "ma sát". Chính ma sát này, khiến bạn rõ hơn mình thực sự muốn làm gì, hệ thống vận hành ra sao, cảm giác tổng thể thế nào. Đây chính là nơi kinh nghiệm và "gu" phát huy tác dụng, và đây chính xác là thứ mà mô hình tiên tiến nhất hiện nay vẫn chưa thể thay thế. Chậm lại, chịu một chút ma sát, chính là cách bạn học hỏi và trưởng thành.
Cuối cùng, bạn nhận được sẽ là một hệ thống vẫn có thể bảo trì - ít nhất sẽ không tệ hơn trước khi Agent xuất hiện. Đúng vậy, hệ thống trước đây cũng không hoàn hảo. Nhưng người dùng của bạn sẽ cảm ơn bạn, vì sản phẩm của bạn là "dùng được", chứ không phải một đống rác được hồ lại.
Bạn sẽ làm ít tính năng hơn, nhưng chính xác hơn. Học cách nói "không", bản thân đã là một năng lực. Bạn cũng có thể yên tâm ngủ, vì ít nhất bạn còn biết hệ thống đang xảy ra chuyện gì, bạn vẫn nắm quyền chủ động. Chính sự hiểu biết này, cho phép bạn bù đắp vấn đề truy hồi của tìm kiếm agentic, khiến đầu ra của Agent đáng tin cậy hơn, cần ít sửa chữa hơn.
Khi hệ thống gặp vấn đề, bạn có thể tự xuống sửa; khi thiết kế ngay từ đầu đã không hợp lý, bạn cũng có thể hiểu vấn đề nằm ở đâu, và tái cấu trúc nó thành hình thái tốt hơn. Còn có Agent hay không, thực ra không quan trọng lắm.
Tất cả những điều này, đều cần kỷ luật. Tất cả những điều này, đều không thể thiếu con người.







