37 điểm bởi GN⁺ 2026-03-20 | 6 bình luận | Chia sẻ qua WhatsApp
  • Về tuyên bố rằng với agentic coding thì "có thể thay thế mã bằng tài liệu đặc tả", bài viết chỉ ra một giới hạn mang tính nền tảng: nếu đặc tả trở nên đủ chính xác, cuối cùng nó buộc phải hội tụ về cùng một hình thức với mã
  • Nhìn vào dự án Symphony của OpenAI, có thể thấy SPEC.md đó không phải là đặc tả mà trên thực tế là mã giả ở định dạng Markdown
  • Thực tế, khi thử triển khai bằng Haskell dựa trên đặc tả của Symphony, đã phát sinh nhiều lỗi và các vấn đề về độ tin cậy như agent chờ vô hạn
  • Công việc viết đặc tả vốn đòi hỏi tư duy sâu hơn cả lập trình, nhưng trong xu hướng tối ưu hóa tốc độ hiện nay của ngành, đang hình thành một cơ chế sản sinh hàng loạt các bản đặc tả chất lượng thấp do AI tạo ra
  • Nguyên tắc "garbage in, garbage out" cũng áp dụng nguyên vẹn cho coding agent; với những tài liệu thiếu rõ ràng và chi tiết thì không thể tạo ra mã đáng tin cậy

Hai ngộ nhận về agentic coding

  • Những người ủng hộ agentic coding đang dựa vào hai ngộ nhận cốt lõi
    • Ngộ nhận 1: Tài liệu đặc tả đơn giản hơn mã tương ứng — một góc nhìn kiểu thuê ngoài, cho rằng có thể biến kỹ sư thành người quản lý viết tài liệu đặc tả rồi giao việc cho một nhóm agent
    • Ngộ nhận 2: Viết đặc tả nhất định sâu sắc hơn viết mã — cho rằng đi qua bước tài liệu đặc tả sẽ cải thiện chất lượng và thúc đẩy các thực hành kỹ thuật tốt hơn

Mã giả làm đặc tả: phân tích trường hợp Symphony

  • Dự án Symphony của OpenAI được giới thiệu là một bộ điều phối agent được tạo từ tài liệu đặc tả (SPEC.md), nhưng nội dung thực tế của SPEC.md lại gần với mã giả ở định dạng Markdown hơn là đặc tả
  • Các loại nội dung có trong SPEC.md:
    • Bản dump văn xuôi của lược đồ cơ sở dữ liệu — liệt kê các trường như session_id, thread_id, codex_input_tokens
    • Chuyển mã sang văn xuôi — các biểu thức như available_slots = max(max_concurrent_agents - running_count, 0) cho điều khiển đồng thời, công thức backoff khi retry (delay = min(10000 * 2^(attempt-1), agent.max_retry_backoff_ms)) v.v.
    • Các mục trùng lặp như "Config Fields Summary (Cheat Sheet)" được thêm vào một cách tường minh để hỗ trợ mô hình sinh mã
    • Mục "Reference Algorithms" về thực chất chính là mã nguồn như hàm start_service()
  • Vừa khẳng định tài liệu đặc tả là thứ thay thế mã, nhưng bản thân tài liệu đó lại đọc như mã là điều đánh tráo khái niệm
  • Muốn làm tài liệu đặc tả đủ chính xác thì không thể tránh khỏi việc biến nó thành hình thức mã, hoặc viết nó bằng thứ tiếng Anh hình thức có cấu trúc rất cao

Lập luận về "giao diện hẹp" của Dijkstra

  • Trích dẫn Dijkstra để nhấn mạnh rằng việc chọn giao diện không chỉ là phân chia lao động đơn thuần; nó còn kéo theo chi phí cộng tác và giao tiếp khi phải vượt qua giao diện đó
  • Bài viết nêu các ví dụ lịch sử: toán học Hy Lạp từng trì trệ khi chỉ dừng ở hoạt động ngôn ngữ và thị giác; đại số Hồi giáo suy tàn khi quay lại phong cách tu từ; còn Tây Âu đã thoát khỏi "nỗ lực đạt độ chính xác ngôn ngữ viển vông" của kinh viện trung cổ và phát triển nhờ các hệ ký hiệu hình thức của Vieta, Descartes, Leibniz, Boole
  • Các agentic coder không thể né tránh "giao diện hẹp" (= mã) mà lao động kỹ thuật đòi hỏi; họ chỉ có thể chuyển hóa lao động đó sang một hình thức bề ngoài có vẻ khác nhưng vẫn đòi hỏi cùng mức độ chính xác

Tính bất ổn: vấn đề độ tin cậy của việc sinh mã từ đặc tả

  • Làm theo khuyến nghị trong README của Symphony và yêu cầu Claude Code triển khai bằng Haskell, kết quả là không chạy được
    • Xuất hiện nhiều lỗi, cần sửa thông qua prompt (có thể thấy trong lịch sử commit)
    • Ngay cả khi có vẻ "chạy" mà không báo lỗi, agent codex vẫn đứng chờ vô hạn mà không có tiến triển nào với một ticket Linear đơn giản ("tạo một git repository trống")
  • Mượn cách diễn đạt của Dijkstra, có thể thấy "nỗ lực đạt độ chính xác ngôn ngữ viển vông" của Symphony rốt cuộc vẫn không tạo ra được triển khai đáng tin cậy
  • Vấn đề này không chỉ riêng Symphony — ngay cả các đặc tả như YAML, vốn cực kỳ chi tiết, được dùng rộng rãi và còn có cả bộ kiểm thử tính tương thích, thì đa số các triển khai YAML vẫn không tuân thủ đầy đủ spec
  • Đặc tả của Symphony đã dài bằng 1/6 bản triển khai Elixir đi kèm; nếu còn mở rộng thêm nữa thì sẽ chạm tới tình huống như truyện ngụ ngôn "On Exactitude in Science" của Borges — tấm bản đồ có kích thước bằng cả đế chế và vì vậy trở nên vô dụng
  • Trước phản biện rằng "nếu sinh bằng ngôn ngữ mainstream hơn thì kết quả sẽ tốt hơn", bài viết cho rằng nếu agent gặp khó khi sinh mã Haskell thì điều đó cho thấy khả năng khái quát hóa vượt ra ngoài dữ liệu huấn luyện còn yếu

Slop: vấn đề chất lượng của đặc tả do AI tạo ra

  • Công việc viết đặc tả vốn dĩ phải khó hơn viết mã; mục đích của nó là buộc người ta nhìn dự án bằng góc nhìn suy xét và phê phán trước khi bắt đầu lập trình
  • Nhưng trong xu hướng ngành công nghệ muốn cắt giảm và hạ thấp giá trị lao động, nếu xuất phát từ tiền đề rằng "viết đặc tả dễ hơn viết mã" thì thất bại đã được định sẵn
  • Không thể vừa theo đuổi tối ưu hóa tốc độ giao hàng vừa thực hiện được công việc khó khăn và khó chịu mà việc viết đặc tả đòi hỏi
  • Section 10.5 của SPEC.md trong Symphony (linear_graphql extension contract) là một ví dụ điển hình của slop — kiểu đầu ra của agent gồm những câu trông giống đặc tả nhưng thiếu nhất quán, thiếu mục đích và thiếu hiểu biết về bức tranh tổng thể
    • Ví dụ, các quy tắc rời rạc như query phải là chuỗi không rỗng, phải chứa đúng một thao tác GraphQL, v.v. được liệt kê ra nhưng không có ngữ cảnh tổng thể
  • Ngay cả khi do con người viết, loại tài liệu đặc tả này cũng tất yếu trở thành slop — vì nó được tối ưu cho thời gian giao hàng chứ không phải cho tính nhất quán hay độ rõ ràng
  • Việc các đoạn mã bị chú thích là text mà không có syntax highlighting cũng là dấu hiệu của tài liệu do AI tạo ra — nhiều khả năng là hệ quả của việc mô hình làm theo câu chữ bề mặt thay vì hiểu đúng ý định của yêu cầu

Kết luận

  • Đặc tả vốn không được thiết kế như một công cụ tiết kiệm thời gian
  • Nếu mục tiêu là tối ưu thời gian giao hàng, thì viết mã trực tiếp sẽ có lợi hơn so với đi qua một tài liệu đặc tả trung gian
  • Nguyên tắc "garbage in, garbage out" vẫn áp dụng nguyên vẹn — nếu đầu vào là những tài liệu thiếu rõ ràng và chi tiết, thì không tồn tại một thế giới nào mà coding agent có thể lấp đầy những thiếu hụt đó một cách đáng tin cậy
  • Coding agent không phải thực thể biết đọc suy nghĩ; mà kể cả có thế đi nữa, nếu bản thân tư duy đã hỗn loạn thì chúng cũng chẳng thể làm gì

6 bình luận

 
gracefullight 2026-03-20

Có vẻ giống hệt như khi phát triển hướng mô hình vậy.

 
wedding 2026-03-20

Chẳng phải phát triển dựa trên đặc tả SDD vốn dĩ đã có từ trước rồi sao.

 
koreacglee 2026-03-20

Có vẻ như với các giải pháp dựa trên Python hoặc JavaScript, chỉ cần tài liệu đặc tả chi tiết thôi cũng có thể hiện thực được khá như ý. Tôi làm ở mảng game/y tế dựa trên C/C++, mà dạo này càng thấy rằng không chỉ chuyện giao phó cho FULL AI AGENT là còn xa, mà ngay cả việc tự động hóa chỉ bằng tài liệu đặc tả chi tiết thôi cũng là một canh bạc quá mạo hiểm.

 
GN⁺ 2026-03-20
Ý kiến trên Hacker News
  • Tôi không đồng ý với ý rằng nếu đưa vào tài liệu không rõ ràng thì tác nhân lập trình cũng không thể tự điền phần chi tiết
    LLM về bản chất là một cỗ máy nội suy/ngoại suy ngôn ngữ, nên rất giỏi trong việc lấp đầy những chi tiết còn thiếu
    Có nhiều trường hợp chỉ với mô tả ngắn gọn, súc tích mà vẫn tạo ra được mã chạy được
    Tuy nhiên, kiểu bổ sung chi tiết này không phải lúc nào cũng đúng, và để đảm bảo độ tin cậy thì cần ràng buộc tường minh những phần quan trọng
    Hiện nay có văn hóa viết code, nhưng văn hóa viết đặc tả siêu chính xác thì gần như không tồn tại ngoài những nơi như NASA

    • LLM có thể tạo code từ mô tả ngắn, nhưng không có nghĩa là tạo ra một cách đáng tin cậy
      Code càng ngắn và càng phổ biến thì càng hoạt động tốt, nhưng với mô tả phức tạp thì rất dễ sụp đổ
      Rốt cuộc, việc thừa nhận rằng “phần chi tiết bổ sung có thể sai” cũng có nghĩa là việc sinh ra kết quả đáng tin cậy là khó
    • Thực ra chúng ta đã có những ngôn ngữ đặc tả chính xác như vậy rồi
      Ví dụ có các ngôn ngữ tổng hợp chương trình như Synquid
      Chúng cho thấy những giới hạn của việc sinh chương trình từ đặc tả chính xác về mặt toán học
      Vấn đề được gọi là specification gap, tức là việc chứng minh chương trình có thực sự triển khai đúng đặc tả hay không mới là nhiệm vụ cốt lõi
      Ngôn ngữ tự nhiên quá mơ hồ nên không phù hợp để định nghĩa chương trình
      Việc LLM điền vào các chi tiết có vẻ hợp lý không có nghĩa là khoảng cách đó được giải quyết
      Ngôn ngữ đặc tả toán học thì chính xác, nhưng đường cong học tập cao và khó, tốn công hơn rất nhiều so với chỉ viết prompt bằng Markdown
    • Nói rằng “phần chi tiết bổ sung có thể sai” thực chất là tự phủ nhận chính lập luận của mình
    • Nếu dùng ChatGPT 5.4 Pro, khi chỉ hỏi “cái này có khả thi không?” thì nó thực sự có thể tạo ra ví dụ hoạt động được
      Mô hình có thể nhớ mối quan tâm của tôi, hoặc tự dùng tri thức của nó để lấp chỗ trống và tạo ra một ứng dụng, trò chơi hay whitepaper hoàn chỉnh
      Có lúc đó là “đúng chính xác thứ tôi muốn”, có lúc lại là “đúng cái cảm giác tôi đang muốn nói đến”
      Khả năng xử lý ý nghĩa, ngữ cảnh và sắc thái có những mặt còn vượt cả con người
      AI đang ngày càng thông minh và có năng lực hơn
    • Những gì LLM tạo ra phần lớn là boilerplate hoặc phần mở rộng của các thuật toán đã biết
      Tức là nó gần với việc kéo từ dữ liệu huấn luyện ra hơn là sáng tạo nên những chi tiết hoàn toàn mới
  • Tôi đồng cảm với câu “đặc tả đủ chi tiết thì chính là code”
    Điều này giống với lập luận trong No Silver Bullet của Brooks
    Nhưng đa số mọi người không muốn đi tới mức chi tiết như vậy
    Khi bảo “hãy làm cho tôi một ứng dụng to-do bằng AI”, thực chất ý là “hãy làm một ứng dụng tốt hơn thứ tôi tưởng tượng”

    • Đó là vì trong dữ liệu huấn luyện đã có vô số ứng dụng to-do
      Nhưng cách tiếp cận này không dễ mở rộng sang các loại phần mềm khác
    • Nếu thật sự muốn làm một ứng dụng, bạn phải giải thích nó khác gì so với ứng dụng hiện có
      Cuối cùng, bạn vẫn phải biểu diễn điểm khác biệt đó dưới dạng đặc tả
    • Những lĩnh vực trực quan, cụ thể như web frontend thì đặc tả gần như đã là code
      Nhưng ở các lĩnh vực như cơ sở dữ liệu, hệ thống tệp, tính toán song song, nơi độ chính xác và hiệu năng là tối quan trọng, thì việc triển khai khó hơn đặc tả rất nhiều
      Việc AI tạo ra code vượt qua được kiểm chứng hình thức trong các lĩnh vực này là một thách thức lớn
    • Để định nghĩa “ứng dụng tốt hơn” là gì thì cuối cùng vẫn cần đặc tả (spec)
    • Nếu là ứng dụng đem bán thương mại thì đặc tả là bắt buộc
      Muốn kiếm tiền hoặc cạnh tranh thì phải có yêu cầu cụ thể
  • Nếu nhìn vibe coding dưới góc độ lý thuyết thông tin, thì đó là giả định rằng tồn tại một bộ giải mã có thể phục hồi không gian chương trình hữu ích từ một không gian prompt nhỏ
    Lúc này, tỷ lệ nén chính là lợi ích của vibe coding
    Một prompt như “ứng dụng giao tiếp nhóm dựa trên kênh IRC” là không thể giải mã nếu không biết Slack
    Vì vậy, điều quan trọng là nhận ra cái gì đang bị thiếu
    Muốn code với AI hiệu quả thì nên chia prompt thành các đơn vị ngắn, đồng thời cung cấp kèm tài liệu hiện có hoặc đoạn code đã thử

    • Điều này thực chất gần như trùng với lý thuyết thông tin thuật toán
      Theo Algorithmic Information Theory, lượng thông tin của một chuỗi bằng độ dài của biểu diễn tự hoàn chỉnh được nén nhất của nó
      Tuy nhiên, điều kiện “tự hoàn chỉnh” chỉ đúng khi trọng số của mô hình đóng vai trò như một codebook
    • Tôi rất thích khái niệm “phục hồi chương trình từ một prompt nhỏ”
      Con người giả định ngữ cảnh chia sẻ nhiều hơn LLM rất nhiều, nên thường đánh giá quá cao giới hạn của bộ giải mã
      Nhưng với một hệ thống có ràng buộc mạnh và trọng tâm rõ ràng, có vẻ tỷ lệ nén của vibe coding có thể tăng bùng nổ
    • Đây không chỉ là vấn đề của tính ngắn gọn
      Ngôn ngữ tự nhiên mang lại một giao diện mới cho những người cảm thấy ngôn ngữ lập trình khó tiếp cận hơn
      LLM không suy nghĩ thay bạn, nhưng nó mở ra một con đường mới để biến ý tưởng thành hệ thống hoạt động được
  • Có lẽ sắp tới con người sẽ tạo ra một phương ngữ tiếng Anh kỹ thuật kiểu LLMSpeak để tối ưu hiệu năng mô hình và hiệu quả token
    Kiểu như giảm mơ hồ, tiết kiệm token, và nén các khái niệm phức tạp vào một từ
    Về mặt ngữ pháp, có lẽ cũng sẽ xuất hiện các quy tắc như Oxford comma để tăng độ rõ ràng

    • Rốt cuộc điều đó cũng chẳng khác gì phát minh lại ngôn ngữ lập trình
      Nếu đã đặc tả chi li như vậy thì chẳng còn lý do gì để dùng prompt nữa
    • Nhưng nếu mô hình không được huấn luyện bằng phương ngữ đó, thì mỗi lần vẫn phải gửi kèm định nghĩa của nó
      Cuối cùng vẫn phải định nghĩa lại bằng ngôn ngữ con người, nên hiệu quả tiết kiệm token là có hạn
    • Thậm chí còn có đề xuất dùng ngôn ngữ phi mơ hồ như Lojban
      Xem wiki Lojban, video người nói Lojban
    • Ngôn ngữ của con người vốn đã đủ hiệu quả để truyền đạt hầu hết ý tưởng
      Những nỗ lực tạo phương ngữ nhân tạo có khả năng thất bại giống Esperanto
    • Nếu LLM không được huấn luyện bằng những phương ngữ này, thì cuối cùng khả năng diễn giải ngôn ngữ con người mơ hồ vẫn quan trọng hơn
      Những ngôn ngữ như vậy có khi lại hữu ích hơn khi dùng giữa các LLM với nhau
      Và ngôn ngữ lập trình từ lâu đã đóng vai trò đó rồi
  • Spec là một kiểu phong bì (envelope) bao trùm mọi chương trình thỏa điều kiện đó
    Việc tạo ra phong bì này còn khó hơn viết ra một chương trình đơn lẻ
    Cũng như việc LLM sinh ra code khác nhau mỗi lần, đặc tả cho phép cả triển khai tốt lẫn triển khai kém
    Trên thực tế, khi một triển khai được chấp nhận thì nó sẽ trở thành đặc tả trên thực tế cho phiên bản kế tiếp
    Trong môi trường có code sẵn từ trước (brownfield), đặc tả không còn sạch sẽ nên LLM khó ứng phó tốt

    • Sau 20 năm kinh nghiệm rồi mới bắt đầu viết đặc tả, tôi mới hiểu vì sao nó khó hơn code
      Có một bùng nổ tổ hợp khi phải cân nhắc một dòng đặc tả sẽ tương tác thế nào với các dòng khác
      Nhưng từ góc nhìn của compiler thì code cũng chỉ là đặc tả mà thôi
      Cuối cùng, chuyện “code dễ hơn đặc tả” chỉ là tương đối
    • Hai chương trình cùng thỏa một đặc tả nhưng đặc tính bảo mật có thể hoàn toàn khác nhau
      Một đặc tả như “lưu thông tin xác thực người dùng” có thể bao gồm từ bcrypt cho tới cookie lưu plaintext
      Con người có trực giác rằng “cái đó thì không được làm”, nhưng tác nhân thì sẽ không biết nếu không ghi rõ
      Vì vậy, muốn đảm bảo bảo mật thì phải đặc tả cả những điều không được làm
    • Đặc tả tốt chỉ định nghĩa “làm gì”, không định nghĩa “làm như thế nào”
      Nếu hiệu năng hay bảo mật là quan trọng thì phải nêu rõ các thuộc tính đó
      Ví dụ, câu “chương trình này phải là O(n)” đơn giản hơn triển khai rất nhiều
  • Có vẻ mỗi người đang dùng từ spec với nghĩa khác nhau
    Với tôi, spec là thứ định nghĩa “làm gì (what)”, plan là “làm như thế nào (how)”, còn build packet là “các bước chi tiết”
    Trong đa số trường hợp, phần quan trọng là “làm gì”
    Việc viết thành đặc tả rằng dữ liệu đi từ A sang B, qua C, được bảo toàn ở D và được biểu diễn dưới dạng F tại E, dễ hơn nhiều so với triển khai nó bằng code Rust

  • Khi làm agentic engineering, nhiều khi tài liệu đặc tả dài hơn cả code
    Ngôn ngữ tự nhiên thì không hoàn chỉnh, nhưng code thì chính xác
    Mục đích của đặc tả là giữ nguyên chức năng qua nhiều vòng lặp phát triển
    Với tôi, tài liệu thiết kế kiểu waterfall hiệu quả hơn test hay comment
    Theo cách này, tôi cũng đã refactor trơn tru các dự án vibe coding hoàn chỉnh hoặc đổi ngôn ngữ cho chúng
    Bây giờ có cảm giác như đang quay lại quy trình phát triển của thập niên 70–80

    • Có thể cũng làm được bằng test, nhưng nếu giao cho tác nhân sửa test thì có nguy cơ nó sửa luôn cả test
    • Đặc tả bằng ngôn ngữ tự nhiên không phải lúc nào cũng cần dài hơn code
      Những câu như “hãy triển khai giao diện TCP” ngắn hơn code thực tế rất nhiều
      Cuối cùng, nếu có thể ánh xạ sang một schema rõ ràng, thì ngôn ngữ tự nhiên cũng có thể rất cô đọng
  • Hướng Spec → LLM là không hiệu quả và lãng phí
    Ngược lại, LLM → Spec thực tế hơn
    Nếu đặc tả tồn tại ở dạng có thể biên dịch, thì LLM có thể nhận phản hồi đó để sinh ra code tốt hơn
    Những nỗ lực tạo ra “tiếng Anh được kiểm chứng (validated English)” chỉ làm tăng thêm độ phức tạp
    Cuối cùng, thứ quan trọng vẫn là code thực sự chạy được

  • Code chứa nhiều thứ hơn đặc tả rất nhiều
    Phần lớn dự án có 90% là code framework hoặc hạ tầng, chỉ 10% là logic nghiệp vụ
    Đặc tả không xử lý chi tiết ngôn ngữ hay framework nên ngắn gọn hơn nhiều

    • Nhưng code thực sự giải quyết vấn đề phải trừu tượng hóa mọi thứ ngoài logic nghiệp vụ
      Làm như vậy sẽ tạo ra code gần như ở cùng mức với đặc tả
      Chuyên gia miền nghiệp vụ cũng đọc được và việc kiểm thử cũng dễ hơn
    • Ví dụ, dù đổi MySQL sang Postgres thì đặc tả vẫn giữ nguyên
      Nhưng code thực tế sẽ thay đổi khá nhiều
  • Sự xung đột giữa cách nhìn đặc tả như công cụ quản lý và như công cụ kỹ thuật tạo ra cảm giác bất hòa nhận thức
    Nhà quản lý xem đặc tả như một ticket để giao việc, còn lập trình viên dùng nó như công cụ tư duy để tinh luyện suy nghĩ
    Một số lập trình viên ban đầu thuận tiện nên cũng tiếp cận theo kiểu của quản lý, nhưng rồi sớm nhận ra

    • Dù quản lý giỏi đến đâu thì cuối cùng vẫn phải tự tay xây dựng
      Có thể sống nhờ hype hay các buổi gặp nhà đầu tư trong một thời gian, nhưng rốt cuộc người dùng vẫn muốn sản phẩm thật
 
savvykang 2026-03-21

Tiếp theo chắc lại tái phát minh cả Waterfall với Agile nữa nhỉ

 
jjw9512151 2026-03-20

Là một lập trình viên embedded C, tôi tạo đặc tả sao cho gần như mọi luồng của Feature/Subfeature đều có thể được kiểm tra bằng biểu đồ.

Sau khi xem xét đặc tả kỹ lưỡng trong thời gian dài và chốt bản cuối cùng,
tôi tạo ra đoạn mã tương ứng hoàn toàn 1:1 với đặc tả để sử dụng.
Khi rà soát bằng đặc tả thì khả năng đọc hiểu vượt trội hơn hẳn so với rà soát mã.