Mở đầu — ảo tưởng về đặc tả bằng tiếng Anh
- Bài viết này bắt đầu từ cảm hứng của một bài có ý rằng “một bản đặc tả đủ chi tiết chính là code”. Đặc tả bằng tiếng Anh thoạt nhìn có vẻ chính xác, nhưng khi thật sự bắt tay vào triển khai thì sự mơ hồ mới lộ ra
- “Mọi thứ đều mơ hồ cho đến khi ta cố làm cho nó chính xác” — Bertrand Russell
- Lập trình, giống như viết lách, là một hoạt động lặp đi lặp lại trong đó ta liên tục gọt giũa để nó ngày càng sắc nét hơn (bài luận này cũng đã trải qua vô số bản nháp)
Vibe coding — vì sao nó hiệu quả, và vì sao nó nguy hiểm
- Vì AI ngày càng chuyển từ tiếng Anh → code chạy được nhanh hơn và tốt hơn, nên giờ có thể tạo code chỉ từ mức “cảm giác (vibe)” của tiếng Anh
- Phản ứng với những gì AI tạo ra — “chuyển cái nút sang bên kia đi, xanh hơn nữa” — rồi dần dần làm nó chính xác hơn
- Cụm từ “vibe coding” hoàn hảo ở chỗ này: giữ nguyên mức vibe của tiếng Anh nhưng dùng đầu ra của AI để làm tư duy sắc bén hơn
- Vấn đề cốt lõi: vibe tạo ra ảo giác rằng đó là một abstraction chính xác. Khi tính năng tăng lên hoặc quy mô lớn hơn, abstraction bắt đầu rò rỉ (
leaky abstraction), và những lỗi không ngờ tới có thể phá hỏng cả ngày
Trường hợp thực tế — ứng dụng vibe coding của Dan Shipper
- Ứng dụng trình soạn thảo văn bản do Dan Shipper tạo bằng vibe coding trở nên viral → máy chủ sập
- Nguyên nhân: “cộng tác thời gian thực (
live collaboration)” trực giác thì có vẻ đơn giản, nhưng trên thực tế lại phức tạp đến mức ác mộng
- Vì ai cũng từng dùng Google Docs và Notion nên “cộng tác thời gian thực” tạo cảm giác như thể đã được đặc tả rất chính xác. Nhưng gần như không thể nhận ra trước vì sao thực tế lại không phải vậy
- Chính tác giả cũng từng làm một trình soạn thảo cộng tác cách đây 10 năm và đã trải qua cơn ác mộng của độ phức tạp ngoài dự tính. Khó ở chỗ nào ư? Thậm chí còn không nhớ nổi! Đó cũng là một phần vấn đề — độ phức tạp thì tẻ nhạt, chẳng ai muốn nghĩ về nó, và rất khó nhớ hết chi tiết lẫn edge case
- Ví dụ: sơ đồ luồng kinh điển để Slack quyết định có gửi thông báo hay không — mức độ phức tạp như thế này đang ẩn sau những cụm từ tưởng chừng đơn giản như “gửi thông báo”
Abstraction — công cụ duy nhất để xử lý độ phức tạp
- Giới hạn căn bản của bộ não con người: chỉ xử lý được 7±2 thứ cùng lúc
- Cách duy nhất để xử lý nhiều hơn 7 thứ: nén (
compress) nhiều thứ thành một. Vì ta có thể lặp lại việc này một cách đệ quy vô hạn, con người mới có thể xử lý độ phức tạp vô hạn. Bước nén đó chính là abstraction
- “Mục đích của abstraction không phải là trở nên mơ hồ, mà là tạo ra một tầng ý nghĩa mới trong đó người ta có thể tuyệt đối chính xác” — Dijkstra
- Ví dụ Sophie Alpert đã refactor sơ đồ luồng thông báo khét tiếng của Slack thành một cấu trúc đơn giản hơn rất nhiều nhờ abstraction khéo léo
- Phần tuyệt vời nhất của lập trình: tạo ra những abstraction ngày càng tốt hơn để chinh phục độ phức tạp, giống như ReactJS hay TailwindCSS đã làm trong lĩnh vực của chúng
- Việc trình soạn thảo văn bản cộng tác vốn phức tạp từ gốc chỉ có nghĩa là ta phải tiếp tục tìm abstraction tốt hơn
AGI — nhưng code tốt vẫn không biến mất
- Hãy hình dung 1 năm, 2 năm, 5 năm, 10 năm, 100 năm tới: AI ngày càng tốt hơn / nhanh hơn / rẻ hơn, và rồi đến lúc trí tuệ máy móc không thể phân biệt với con người nữa (AGI)
- Thế giới AGI có thể trông giống thế giới vibe. Nếu bạn có thể thuê 100 thiên tài cỡ Kaparthy với giá $1000/tháng, thì cần gì phải bận tâm đến những chi tiết phiền phức?
- “Đây thật sự là một ý nghĩ buồn cười.” Kiểu suy nghĩ đó chỉ có vẻ hợp lý khi công nghệ còn chưa đến nơi và mới chỉ tồn tại như một khả năng trừu tượng
- Nếu có thể tiếp cận mức trí tuệ như thế, sẽ có 0% người dùng nó để tạo thêm slop. Dĩ nhiên là không
- Lý do ta nhầm lẫn: vì ta (sai lầm) cho rằng code chỉ dùng để sản xuất phần mềm. Bản thân code cũng là một sản phẩm cốt lõi. Nếu được làm tốt, nó là thơ
- “Đâu có ai nói về ‘vibe writing’?” — trong viết lách, chẳng ai tin ChatGPT sẽ thay thế các tiểu thuyết gia hay nhà báo vĩ đại. Với code cũng vậy, chỉ là tính “kỳ bí” của việc code có thể chạy được khiến ta ngộ nhận
- AI tạo ra code dở (dù ngày càng bớt dở hơn). Ai cũng biết điều này. Ta dùng AI là bất chấp code xấu, chứ không phải vì code xấu
- Trích Simon Willison: “AI nên giúp tạo ra code tốt hơn”
- Việc đầu tiên phải làm khi AGI đến: giải các bài toán abstraction khó nhất. Tạo ra abstraction tốt hơn để hiểu và chinh phục độ phức tạp tốt hơn
- AI càng thông minh thì nhu cầu về code tốt càng biến mất ư? Nói vậy chẳng khác nào bảo ChatGPT nên được dùng để sản xuất thêm slop
- Ví dụ thực tế: Opus 4.6 đã giải quyết gọn trong một lần một vấn đề chưa có lời giải khi xây dựng framework React full-stack của Val Town (
vtrr). Bản demo ứng dụng full-stack một file, 50 dòng, là kết quả của việc đó
Kết luận — code mới chỉ bắt đầu
- Có vẻ như 99% xã hội đã đồng ý với câu “code đã chết”. Hôm qua thôi còn nghe podcaster Sam Harris tự tin nói rằng “mọi người đều đồng ý coding đã chết, không ai cần học code nữa”
- “Điều đó thật đáng buồn. Nó giống như nói ‘kể chuyện đã chết’ sau khi máy in được phát minh. Đồ ngốc, code mới chỉ bắt đầu thôi. AI sẽ là một phước lành khổng lồ cho lập trình.”
- Những trích dẫn kết thúc:
- “Thay vì xem nghĩa vụ dùng ký hiệu hình thức là gánh nặng, ta nên xem khả năng được dùng nó là một đặc quyền. Nhờ đó sinh viên có thể làm được những điều mà trước kia chỉ thiên tài mới làm nổi” — Dijkstra
- “Việc có thể dùng tiếng mẹ đẻ một cách ‘tự nhiên’ chẳng qua chỉ có nghĩa là bạn có thể dễ dàng tạo ra những câu mà sự vô nghĩa của chúng không hiển nhiên” — Dijkstra, “On the foolishness of natural language programming”
- “Có hai cách để thiết kế phần mềm: một là làm nó đơn giản đến mức khuyết điểm hiển nhiên là không có, hai là làm nó phức tạp đến mức cũng không có khuyết điểm nào hiển nhiên” — Tony Hoare
- “Lượng ý nghĩa được nén trong một không gian nhỏ bằng ký hiệu đại số giúp cho việc suy luận thông qua nó trở nên dễ dàng hơn” — Charles Babbage
7 bình luận
Ngay cả trước khi bàn đến chuyện chỉnh sửa cộng tác, chỉ riêng việc triển khai cho ra hồn một trình soạn thảo dùng một mình thôi cũng đã đầy rẫy những độ phức tạp khó lường như xử lý con trỏ, ngăn xếp hoàn tác/làm lại, nhập liệu IME. Như bài viết đã chỉ ra, hiếm có phần mềm nào phơi bày rõ cái bẫy của một "đặc tả tạo cảm giác trực quan nhưng lại chính xác" như trình soạn thảo. Rốt cuộc, thứ trông có vẻ dễ không phải là dễ thật, mà là vì người ta đã trừu tượng hóa tốt và che đi sự phức tạp đó.
Thực ra, lý do Anthropic làm một trình biên dịch C để demo có lẽ cũng là vì trình biên dịch có đặc tả rõ ràng và các test case cũng được chuẩn bị rất tốt. Đồng thời, nó cũng trông cực kỳ khó nhằn.
Tôi đã thử làm vài trình biên dịch và hiện cũng đang làm một cái, còn khi nhìn từ góc độ vibe coding thì tôi cũng đã thử với editor, nhưng cảm giác trình biên dịch lại dễ hơn. Đúng như bạn viết, tôi thấy đặc tả kém chính xác hơn và có nhiều biến số do người dùng tạo ra hơn. Việc kiểm thử cũng khó hơn.
Đặc tả chắc chắn sẽ trở nên quan trọng hơn, nhưng từ trước đến nay tôi vẫn nghĩ rằng không thể viết đặc tả thật chi tiết và bao quát mọi tình huống. Tôi vẫn cho rằng hướng tốt hơn hiện tại là cũng như code, đặc tả nên được mài giũa dần trong quá trình làm việc; tuy vậy, tôi cũng nghĩ có lẽ có thể để nhiều agent tự làm việc đó với nhau. Nhưng rốt cuộc, nếu không có sự can thiệp của con người thì sẽ khó vượt ra ngoài những tình huống và kiến thức đã được học, nên tôi nghĩ những tình huống và tính năng hoàn toàn mới sẽ không dễ.
Nó cho tôi cảm giác giống như khi robot hút bụi mới ra mắt, người ta nói phải làm một việc "dọn dẹp đơn giản" là cất bớt đồ trên sàn đi để phục vụ robot. Việc viết đặc tả chi tiết cho AI cũng đã là một công việc đáng kể, cứ như là đang làm việc vì AI vậy.
IDE, PR đều chết cả rồi mà code lại hồi sinh à?
Code là đặc tả chính xác nhất về mặt logic trong một hệ đơn giản.
Nhưng cái bẫy là thế giới thực lại là một hệ phức tạp.. rốt cuộc chỉ có dữ liệu mới là đặc tả chính xác nhất, dù chỉ là tương đối
Có lẽ cần xem liệu nó có thể được thay thế bằng các phương pháp kiểm chứng khác hay không. Càng gần phía frontend, chỉ với E2E thông qua hành vi của trình duyệt cũng có thể xác minh rằng nó hoạt động tốt. Nhưng với code ở phía backend, và càng gần hạ tầng hơn, thì có lẽ code review là điều bắt buộc. Nếu không, sẽ khó kiểm chứng các side effect như transaction vô hình được mở rồi đóng, hay các lệnh gọi API được gửi đi.
Trong trình duyệt có rất nhiều vấn đề mà ngay cả E2E cũng không thể bắt được.