1 điểm bởi GN⁺ 4 giờ trước | 1 bình luận | Chia sẻ qua WhatsApp
  • Vòng lặp ở mức harness quản lý hàng đợi công việc và harness bên ngoài coding agent đang nổi lên như một mẫu trung tâm mới của kỹ nghệ agent
  • Càng để mô hình tự vận hành lâu, nó càng dễ chồng thêm phòng thủ cục bộ và fallback hơn là dựng các bất biến mạnh, khiến việc hiểu thiết kế và kiểm soát trong mã được duy trì dài hạn có thể bị lung lay
  • Ngược lại, ở các lĩnh vực như porting mã, thử nghiệm hiệu năng, quét bảo mật và nghiên cứu, nơi kết quả dễ kiểm chứng hoặc dễ loại bỏ, lặp cơ học đã hoạt động rất hiệu quả
  • Khi kẻ tấn công và người gửi báo cáo chạy vòng lặp, bên bảo trì cũng chịu áp lực phải dùng máy cho triage, tái hiện và ứng phó; trường hợp của curl cho thấy gánh nặng do các báo cáo do AI tạo ra
  • Thách thức sắp tới không phải là có dùng vòng lặp hay không, mà là làm sao vẫn giữ được phán đoán của con người, các nguyên tắc kỹ thuật, giám sát có trách nhiệm và kiến trúc dễ hiểu bên trong chúng

Những vòng lặp chạy bên ngoài coding agent

  • Bên trong coding agent đã có vòng lặp agent: mô hình gọi công cụ, phản ánh kết quả, đọc và sửa tệp, chạy test rồi đưa ra câu trả lời
  • Mẫu mới nổi bật là vòng lặp ở mức harness bên ngoài nó
    • Công việc được đưa vào hàng đợi
    • Máy lấy việc và thử thực hiện
    • Sau khi dừng lại, harness phán đoán xem công việc đã thật sự xong chưa
    • Nếu chưa xong, nó tiêm thêm thông điệp vào cùng phiên, hoặc bắt đầu phiên mới với ngữ cảnh đã chỉnh sửa, hoặc chuyển việc sang máy khác
  • Vòng lặp bên ngoài này giữ cho công việc tiếp tục sống ngay cả sau thời điểm mà mô hình thường sẽ nói là “xong rồi”
  • Bản thân vòng lặp không phải điều mới, nhưng gần đây nó xuất hiện thường xuyên hơn trong kỹ nghệ agent và các thảo luận trên Twitter
  • Một phần dòng chảy như vậy cũng xuất hiện trên Pi, và vì Pi là một harness nên nó nằm ở trung tâm của các thử nghiệm này

Sự khó chịu với mã cần duy trì lâu dài

  • Cách này hiện vẫn chưa thật sự hợp với loại mã mà người ta rất quan tâm sâu sắc
  • Cốt lõi là gu và khả năng kiểm soát
    • Muốn hiểu mã mình triển khai
    • Trong tình huống áp lực hoặc khi thảo luận với người khác, phải có khả năng giải thích hệ thống hoạt động thế nào mà không cần bắt máy giải thích trước
    • Ở thời điểm hiện tại, hiểu mã vẫn rất quan trọng
  • Mã được tạo ra khi buông tay, đặc biệt là mã sinh ra từ vòng lặp, có những vấn đề lặp đi lặp lại
    • Quá phòng thủ
    • Quá phức tạp
    • Mắc kẹt trong suy luận cục bộ
    • Né tránh các bất biến mạnh
    • Thêm fallback thay vì làm cho trạng thái sai trở nên bất khả thi
    • Tạo mã trùng lặp và trừu tượng hóa tệ, rồi che phủ thiết kế mơ hồ bằng nhiều lớp cơ chế hơn
  • Các tổ hợp như Claude Code và Fable có thể làm liên tục hơn 30 phút trên một vấn đề, nên mức độ human in the loop đã giảm so với trước
  • Chất lượng mã từ kiểu harness buông tay hiện tại thậm chí còn có cảm giác tệ hơn mùa thu năm ngoái, ít nhất là với gu này thì gần như không thấy cải thiện

Vòng lặp khuếch đại thói quen của mô hình

  • Khi thấy một thất bại cục bộ, mô hình có xu hướng thêm một lớp phòng thủ cục bộ
  • Andrej Karpathy từng nói rằng các mô hình “sợ ngoại lệ một cách bệnh lý”
  • Với các hệ thống có bất biến quan trọng, đặc biệt là định dạng dữ liệu bền vững hoặc hạ tầng cốt lõi, cách sửa bằng việc “xử lý mọi trường hợp malformed” có thể không phải là hướng đúng
    • Hướng tốt hơn là khiến các trường hợp malformed không thể được biểu diễn hoặc không thể được ghi ra ngay từ đầu
    • Ngay cả khi được điều khiển thủ công khá nhiều, LLM vẫn khó tự nhiên sinh ra kiểu mã như vậy, và có thể còn cố xử lý cả những lỗi đã bị làm cho không thể xảy ra
  • Khi đặt thói quen này sau một vòng lặp, vấn đề sẽ bị khuếch đại
    • Mỗi vòng lặp lại thêm từng lớp phòng thủ nhỏ
    • Hệ thống trông có vẻ vững hơn nhưng ngày càng khó hiểu hơn
    • Càng buông tay, xu hướng này càng mạnh
  • Nếu đưa công cụ kiểu này cho người mới mà không có hướng dẫn rõ ràng, nó có thể dạy họ những thực hành tệ
    • Khi bị hỏi lý do, họ vẫn có thể biện hộ lựa chọn của mình một cách khá thuyết phục

Những lĩnh vực mà vòng lặp rất hợp

  • Mẫu vòng lặp đã hoạt động rất tốt ở một số lĩnh vực
  • Porting mã là ví dụ tiêu biểu
  • Nó cũng rất hợp với việc khám phá hiệu năng
    • Máy thử các thí nghiệm
    • Chạy benchmark
    • Loại bỏ các thất bại
    • Tiếp tục khám phá
  • Nó cũng phù hợp tự nhiên với quét bảo mật và gần như mọi dạng nghiên cứu
    • Có thể cho máy khám phá một không gian vấn đề phức tạp rồi báo cáo kết quả
    • Không nhất thiết phải commit mã sẽ tồn tại lâu dài
  • Điểm chung của các ca thành công là đầu ra либо không cần được duy trì lâu dài, либо là biến đổi mã sẵn có, hoặc gần với proof of concept, ý tưởng, phát hiện, hay chuyển đổi cơ học hơn
  • Điều harness cần không phải là tín hiệu hoàn toàn khách quan hay nhị phân, mà là một tín hiệu đủ hữu ích để đẩy sang vòng lặp tiếp theo
    • Nhiều trường hợp thành công dùng một LLM khác làm judge hoặc orchestrator
    • Dịch cơ học có thể được kiểm chứng bằng test case nhị phân, hoặc cũng có thể do LLM phán đoán
  • Claude Code ngày càng thành thạo trong việc tạo và chạy toàn bộ workflow thí nghiệm
    • Dù mã sinh ra có bừa bộn, đó vẫn gần với vấn đề của mô hình hơn là năng lực phán đoán của harness

Sự thay đổi khi đối xử với phần mềm như sinh vật hơn là cỗ máy

  • Viết mã sẽ tồn tại lâu dài theo cùng kiểu vòng lặp này hiện vẫn chưa thấy thoải mái
  • Lý tưởng cũ gần hơn với việc hiểu phần mềm như một cỗ máy mang tính quyết định
    • Bóc một lớp thì có thể hiểu sâu hơn
    • Một cỗ máy được quan sát theo cách phi quyết định khó được xem là tối ưu
    • Kiến trúc nên tiến về phía nhiều tính quyết định hơn
    • Thiết kế tốt là thứ cho phép kỹ sư mới cũng có thể lần theo một codebase phức tạp
  • Trong một hệ thống được thiết kế tốt, sẽ có kỹ sư biết bất biến nằm ở đâu, phần nào là load-bearing, và thay đổi nào là an toàn
  • Phần mềm lớn vốn đã không còn nằm trọn trong đầu người, và hệ thống phân tán đôi khi được chẩn đoán giống như bác sĩ nhìn triệu chứng, đưa ra giả thuyết rồi chỉ định thêm xét nghiệm
  • LLM đẩy xu hướng này nhanh hơn nữa
    • Khi có sự cố production, máy đọc log
    • Đề xuất root cause
    • Đưa lên patch
    • Máy khác review, đôi khi đưa thẳng vào main mà không cần giám sát của con người
  • Cách này rất mạnh và rất hấp dẫn, nhưng con người có thể không còn hiểu toàn bộ hệ thống theo cách cũ nữa
    • Họ vận hành, giám sát và ổn định nó, nhưng không nhất thiết là hiểu nó
  • Không phải mọi đoạn mã đều cần do con người viết, và trong quá khứ có thể cũng từng có nhiều mã còn tệ hơn thế

Áp lực khó lòng hoàn toàn đứng ngoài

  • Có thể sẽ rất khó opt out khỏi một tương lai hoàn toàn do máy dẫn dắt
  • Bảo mật là ví dụ rõ nhất
    • Dù bản thân không dùng vòng lặp để tạo phần mềm, người khác vẫn có thể chạy vòng lặp nhắm vào phần mềm đó
    • Kẻ tấn công tiếp tục chạy máy
    • Ngay cả khi không phải kẻ tấn công, nhà nghiên cứu bảo mật vẫn thực hiện công việc tự động hóa
    • Kết quả là issue thật và nhiễu cùng đổ vào
  • Bài summer of bliss của Daniel Stenberg về curl cho thấy áp lực mà maintainer đã phải gánh
    • Có vẻ AI không đóng vai trò lớn trong phát triển lõi của curl
    • Dù vậy, maintainer vẫn đang bị ngập trong báo cáo, và phần lớn trong số đó là báo cáo do AI tạo ra
  • Khi kẻ tấn công và người gửi báo cáo chạy vòng lặp, bên phòng thủ cũng phải chạy theo
    • Không nhất thiết là để tự tay viết patch
    • Nhưng áp lực triage, tái hiện và ứng phó có thể buộc họ phải dùng máy
  • Áp lực cạnh tranh cũng tương tự
    • Có đội có thể tạo ra nhiều thứ hơn đội khác chỉ nhờ tốc độ thuần túy
    • Một nhóm nhỏ điều phối máy tốt có thể khiến dự án bỗng tăng tốc mạnh
    • Có startup có thể làm với 5 người những việc trước đây cần 50 người
    • Ai đó cũng có thể chạy vòng lặp lên sản phẩm và bảo nó “hãy làm cái gì đó giống thế này”
  • Không phải mọi phần mềm đều bị ảnh hưởng như nhau
    • Có những lĩnh vực trừng phạt sự cẩu thả và đòi hỏi niềm tin cùng trách nhiệm
    • Nhưng với nhiều phần mềm, tốc độ, thử nghiệm nhanh và độ bao phủ rộng lại cực kỳ quan trọng

Sự phụ thuộc mới do vòng lặp tạo ra

  • Công cụ do vòng lặp tạo ra có thể không chỉ là chi phí một lần, mà còn tạo nên sự phụ thuộc nhận thức kéo dài
  • Trước đây phát triển phần mềm phụ thuộc vào các công cụ tốn kém như compiler, nhưng công cụ hiện tại giống những hệ thống phải được truy cập liên tục hơn
  • Nếu codebase được tạo bằng vòng lặp, được review bằng vòng lặp, được vá bằng vòng lặp và được bảo trì bằng vòng lặp, thì sẽ phát sinh vấn đề khi quyền truy cập vào cùng cấp độ hệ thống đó bị gián đoạn
    • Hạn chế thương mại có thể khiến mất quyền truy cập vào các mô hình mạnh nhất
    • Chi phí có thể trở nên không thể gánh nổi
    • Đội ngũ có thể đánh mất năng lực cuối cùng để hiểu mã mà không cần máy
  • Có thể sẽ xuất hiện những codebase không chỉ khó để con người bảo trì, mà còn mặc định việc máy tham gia là một phần của chính mô hình bảo trì
  • Một số thay đổi đã bắt đầu lộ rõ
    • Ngày càng nhiều người merge những đoạn mã mà họ không thể giải thích hoàn toàn
    • Báo cáo issue hoặc thảo luận chat được máy bổ sung hay viết lại bằng ngữ cảnh do nó cung cấp
    • Tóm tắt và ngữ cảnh hóa được giao cho máy
    • Ngày càng hay thấy con người trò chuyện thông qua LLM
  • Không thể khẳng định điều đó nhất thiết là sai, nhưng đó là một thay đổi lớn so với trước đây

Harness và công cụ cần có trong thời gian tới

  • Chỉ điều phối nhiều vòng lặp hơn thôi là chưa đủ
  • Ngay cả khi trực quan hóa tốt hơn các thay đổi, orchestration và agent, sự hiểu biết cũng không tự động quay trở lại
  • Hướng cần thiết là một trong hai điều sau
    • Kéo con người trở lại vòng lặp một cách đủ mạnh, và làm cho các thay đổi trong vòng lặp có thể đọc hiểu được về lâu dài
    • Hoặc tìm cách kết hợp tốt hơn những hệ thống ngày càng phức tạp
  • Cách nhìn về Pi cũng đang thay đổi
    • Pi đã thận trọng, và sự thận trọng đó là tốt
    • Không muốn một tương lai nơi mọi tương tác đều biến thành thay đổi do cả đàn máy tạo ra mà rất khó theo dõi
    • Cũng không muốn Pi trở thành một mớ hỗn loạn không thể bảo trì chỉ để thắng cuộc đua phần mềm tự viết
    • Cũng không muốn Pi khuyến khích kiểu kỹ nghệ này
  • Dù vậy Pi vẫn là một harness, và harness đang ở trung tâm của các thí nghiệm mới
  • Hàng đợi tác vụ coding, orchestration agent, subagent và durable session sẽ ngày càng quan trọng hơn
  • Ngay cả những người không muốn mù quáng chấp nhận vòng lặp cũng nên bắt đầu thử nghiệm
    • Vì cần hiểu cách làm cho tương lai này nằm trong ranh giới và có thể chịu đựng được

Vấn đề kiểm soát vòng lặp

  • Khi chấp nhận vòng lặp harness, chính harness sẽ quyết định khi nào công việc thật sự kết thúc
  • Trong vòng lặp agent, cuối cùng mô hình sẽ nói “done” và con người review
    • Ngay trước đó, con người thường cũng điều hướng giữa chừng
    • Con người có tham gia, và trong quá trình đó họ học hỏi
  • Trong vòng lặp do harness vận hành, vai trò của con người trở nên mơ hồ
    • Tín hiệu “done” cũng mất ý nghĩa và trở thành một thông điệp để máy khác phán đoán
    • Vai trò của con người có thể trở nên gần giống người chuyển tin
  • Hiện tại, phần lớn mã được tạo ra theo kiểu này đều không gây thiện cảm, và việc tương tác với phần mềm được tạo bằng hỗ trợ AI cũng không mấy dễ chịu
  • Vòng lặp rất mạnh, nhưng nó dần gỡ bỏ trách nhiệm, và ở thời điểm hiện tại có phần khuyến khích việc đầu hàng trước máy móc
  • Dù vậy, tương lai của vòng lặp có vẻ vẫn sẽ đến
    • Đã có những ví dụ về các nhóm rất nhỏ xây dựng với tốc độ tưởng như không thể
    • Codebase đang biến thành những sinh vật mơ hồ và rối rắm hơn
    • Những codebase như vậy vừa hữu ích vừa lộn xộn
  • Câu hỏi sắp tới sẽ không còn là “có chạy vòng lặp hay không”, mà gần hơn với những điều sau
    • Làm sao không từ bỏ phán đoán bên trong vòng lặp
    • Làm sao giữ được các nguyên tắc kỹ thuật tốt
    • Làm sao để con người có trách nhiệm vẫn tiếp tục giám sát được
    • Làm sao nghĩ lại kiến trúc mã để vẫn giữ được tỉnh táo

1 bình luận

 
Ý kiến trên Hacker News
  • Vòng lặp chỉ hoạt động khi đã dành đủ thời gian để hiểu rõ trước điều mình muốn. Tiền đề là sự rõ ràng, đến mức bạn có thể viết một bản đặc tả cẩn thận đủ để giao cho một đồng nghiệp junior
    Thường thì để hiểu đến mức đó phải đi qua 5–6 phiên bản hỏng hóc, vụng về. 5–6 lần thử sai này không thể tăng tốc, và không có công nghệ agent nào giúp né được thời gian bộ não con người cần để suy nghĩ. Vì vậy phần lớn thời gian là qua lại giữa “mình chưa biết mình muốn gì, phải đọc, viết và nghịch mã đã” và “giờ thì có lẽ đã đủ lâu để biết mình muốn gì rồi”. Rất dễ tự lừa mình, nhưng chỉ khi thực sự biết mình muốn gì thì mới dùng được vòng lặp. Nhiều người nghĩ có thể vượt lên nhờ agent, nhưng sự hiểu biết và độ rõ ràng thì không thể giả lập, và ai bỏ qua bước đó sẽ lộ ra một cách đau đớn

    • Tôi đã cho Codex làm một công cụ trích xuất toàn bộ các phiên pi của mình. Tôi phải lọc prompt và các cuộc trò chuyện của sub-agent, rồi cho nó phân tích các mẫu mà tôi tạo ra và biến chúng thành một lưu đồ cho prompt sinh hướng dẫn ở lớp ngoài
      Tôi không cần phải suy nghĩ quá lâu về điều mình muốn, tôi chỉ đơn giản là muốn nó làm việc đó. Kết quả vẫn còn lẫn lộn và tôi chưa tin tưởng đến mức giao cho nó một codebase tinh vi, nhạy cảm, nhưng với trò chơi tôi đang làm thì thời gian dành cho việc kiểm tra đã giảm xuống còn 1/5 so với trước. Đây không hẳn hoàn toàn là điều tốt. Rất có thể tôi đang bỏ lỡ những ý tưởng hay vì dành ít thời gian hơn. Nhưng trước đây prompt chỉ mang tính cơ học kiểu #now-do-this, #now-review-that và bị kẹt ở mức 90% đề xuất là đúng. Giờ thì tôi chỉ cần tự động nhắc nó “làm phần khó trước, rồi vừa làm vừa dọn dẹp và refactor”, và sau lần trả về đầu tiên thì “hãy nhìn lại công việc”, để nó bộc lộ các vấn đề còn sót lại; sau đó đưa những thứ đó vào prompt sinh hướng dẫn và tung ra loạt tác vụ mới
    • Tôi hoàn toàn đồng ý chuyện phải đi qua 5–6 phiên bản hỏng hóc. Chỉ là sau khi tìm được một bộ khung (prompt + skill + model) mà tôi tin sẽ xử lý phần lớn theo cách mình thích, thì phần coding và khám phá trong quá trình đó đã nhanh hơn
      Vòng lặp nhanh hơn, nhưng công sức để đi qua các phiên bản thô sơ đó gần như vẫn như cũ. Tôi vẫn phải hiểu ý tưởng, nguyên tắc hay thiết kế nào phù hợp với lời giải, phải biết tiếp theo nên thử gì, và phải điều chỉnh mô hình tinh thần của mình. Cuối cùng cảm giác là dồn nhiều nỗ lực trí óc hơn vào một khoảng thời gian ngắn hơn, còn phần tiết kiệm từ việc viết code thì chỉ một chút. Khi đã thành thạo thì việc gõ code vốn dĩ chưa bao giờ chiếm tỷ trọng lớn. Dù có vẻ chỉ là “đơn giản” viết prompt và đọc code, tôi vẫn mệt y như cũ, thậm chí đôi khi còn mệt hơn vì chu kỳ lặp bị nén lại
  • Dạo này ngày nào tôi cũng gặp chuyện này, và nó vừa làm tôi nản vừa lo lắng. Tôi cho rằng lý do chúng ta đang merge ngày càng nhiều đoạn code không thể giải thích trọn vẹn là vì mô hình tinh thần mà trước đây được xây từ việc viết code và cùng nhau lập kế hoạch kỹ thuật, giờ lại bị đẩy sang cho code review
    Code review không phù hợp cho mục đích đó. Tuy vậy, tôi nghĩ có thể gắn các bài tập có cấu trúc dựa trên giáo dục học vào code review để cân bằng tốt hơn giữa ma sát và sự hiểu. Tôi đang tìm người giúp thử nghiệm các bài tập như vậy

    • Khả năng code review hiệu quả khó hơn rất nhiều so với viết code. Nếu không có một bản đồ tốt về việc thay đổi này sẽ ảnh hưởng đến những phần khác của hệ thống ra sao, thì nó gần như chỉ là một nghi thức đóng dấu cho qua chuyện
      Giao diện PR nghèo nàn của GitHub cũng chẳng giúp ích gì. Có quá ít công cụ để khám phá phần codebase xung quanh không trực tiếp bị thay đổi nhưng vẫn chịu tác động, nhằm tìm và làm nổi bật vấn đề
    • https://pages.cs.wisc.edu/~remzi/Naur.pdf
    • Tôi tò mò sản phẩm của bạn là gì. Tôi rất muốn xem một sản phẩm được phát triển bởi cả một bầy agent với năng suất gấp 100 lần con người trông sẽ ra sao. Chắc hẳn sẽ rất ghê gớm
    • Loại code này thường đầy rẫy lỗ hổng bảo mật. Nó giống như chồng hack lên trên hack, và kết thúc bằng 100 nghìn dòng code đầy các nhánh thay thế kỳ quặc cho một việc vốn có thể làm ổn định hơn chỉ với 1 nghìn dòng
      Ý trong bài gốc rằng nên ưu tiên những hệ thống khiến điều kiện biên sai trở nên bất khả thi, thay vì xử lý chúng bằng các nhánh thay thế, là cực kỳ quan trọng. Cách tiếp cận bằng nhánh thay thế khiến người ta lại phải viết thêm nhánh thay thế cho chính nhánh thay thế đó, và mỗi nhánh như vậy làm lượng code tăng theo cấp số nhân, đồng thời bằng cách nào đó luôn tạo ra vấn đề mới. Gần như có thể gọi đây là “định luật phổ quát của thiết kế hệ thống”. Nhánh thay thế làm giảm rủi ro thất bại, nhưng khi thất bại thực sự xảy ra thì nó khiến mọi thứ phức tạp hơn và gây hại hơn. Với tư cách là một kỹ sư phần mềm, tôi thích môi trường lập trình mới mà AI tạo ra. Vì Big Tech đã tạo ra vô hạn việc làm cho tôi. Các lập trình viên con người đã trở thành một thành phần cốt lõi trong việc thực thi code, luôn phải túc trực để xử lý gần như vô hạn các ngoại lệ khó, chưa được xử lý, mà thỉnh thoảng chắc chắn sẽ xảy ra. Giờ đây kỹ sư phần mềm ít giống người lao động hơn, mà giống nhân viên an ninh hơn: phần lớn thời gian ngồi ở bàn uống cà phê, thỉnh thoảng có sự cố thì nhảy vào can thiệp
  • Điều này nối tiếp những gì tôi đã nói suốt mấy tháng qua. LLM rất giỏi trong hoàn thành công việc, nhưng yếu về cảm quan thẩm mỹ và gu
    Có hai loại công việc. Một là công việc định hướng mục tiêu: có một mục tiêu cần đạt được, còn cách đi tới đó thì không quá quan trọng. Bảo mật là ví dụ hoàn hảo. Nếu bạn muốn khai thác một hệ thống, bạn hầu như không quan tâm exploit đó có đẹp hay không, bạn chỉ muốn truy cập vào kế hoạch hạt nhân tuyệt mật. Nghiên cứu cũng tương tự: code “chất lượng nghiên cứu” đã nổi tiếng là lộn xộn từ rất lâu trước thời AI. Loại còn lại là công việc định hướng gu. Khi thêm tính năng vào một codebase lớn, ta nghĩ mục tiêu là thêm được tính năng đó, nhưng nhiều khi không phải vậy. Việc giữ cho codebase tiếp tục đón nhận tốt các thay đổi sau này còn quan trọng hơn rất nhiều so với chính tính năng cụ thể đó, và điều này đòi hỏi gu. Tính dễ bảo trì và chất lượng code không phải là từ đồng nghĩa; chất lượng code chỉ là phương tiện, còn mục đích của nó là tính dễ bảo trì

    • Nhiều tổ chức đang nhanh chóng tiến vào một thế giới nơi chất lượng code và tính dễ bảo trì hoàn toàn không còn là ưu tiên. Nếu Claude sẽ là bên viết code, thì liệu việc code đó “dễ bảo trì” hay “chất lượng tốt” có còn quan trọng không? Theo góc nhìn này thì là không. Chỉ cần chạy được và nhanh là đủ
  • Vấn đề LLM cố xử lý cả những trường hợp sai một cách “tự nhiên” là điều tôi đã phải đấu tranh trong rất nhiều lần review PR. Đặc biệt là sau khi đã viết xong rồi thì cực kỳ khó thuyết phục rằng việc kiểm tra null quá mức là có hại
    Nếu không có mô hình hóa tốt hơn, và không dùng ngôn ngữ cho phép union type, thì tôi vẫn chưa tìm ra phản biện nào đủ hiệu quả trước kiểu “parsing bằng súng hoa cải” này. Có lẽ nó cũng không phải vấn đề quá lớn. Nhưng khi thực sự đọc và refactor codebase, việc phải quản lý những lần kiểm tra không cần thiết như vậy lúc nào cũng rất bực bội. Một khi chúng đã được thêm vào rồi thì đôi khi gần như không thể xóa an toàn nếu chưa bổ sung logging hoặc điều tra trên diện rộng trước

    • Một lập luận thường có tác dụng là: giá trị tùy chọn về bản chất sẽ phân nhánh không gian trạng thái khả dĩ của chương trình. Không gian trạng thái càng lớn thì càng khó suy luận và bảo trì code
      Đây cũng chính là cốt lõi của câu nói rằng hãy làm cho các trạng thái không mong muốn trở nên không thể biểu diễn
    • Review code bằng AI khuyến khích kiểu hoang tưởng phòng thủ quá mức và mang tính ảo giác. Việc kiểm tra null ba lớp sâu trong một hàm về mặt kỹ thuật có thể là rủi ro thật, nhưng trên thực tế thường là trường hợp lẽ ra không bao giờ tới được, vì ở hàm gọi hoặc mọi hàm có thể gọi tới đó đã kiểm tra null hết rồi, nên chưa chắc đáng để phòng thủ đến vậy
    • Điều quan trọng là bạn đang nói đến mức độ “bất khả thi” nào. Tôi vốn cũng lập trình theo kiểu phòng thủ khá nhiều
      Dù bây giờ chưa có gì gửi số âm vào hàm này, nhưng sẽ khó đến mức nào để một thay đổi code trong tương lai làm giả định đó không còn đúng? Tôi vẫn luôn nghĩ lỗi rõ ràng là tốt nhất. Người không quen code này cũng có thể biết có giả định nào về miền giá trị hợp lệ của đầu vào, và không cần phải cân nhắc những ngoại lệ bất khả thi
  • Nút thắt của tôi nằm ở đặc tả. Vòng lặp agent giờ đã là vấn đề ít quan trọng hơn với tôi
    Nếu tôi truyền đạt mục tiêu là phải có được sự hiểu biết rõ ràng về thứ mình muốn xây, rồi viết một đặc tả có thể thực thi trong chế độ lập kế hoạch của Claude Code, thì khi agent bắt tay vào triển khai, kết quả nhìn chung là rất tốt. Nhưng chiến lược hiệu quả này lại đẩy phần gánh nặng viết đặc tả sang cho tôi. Agent thường xử lý rất tốt từng đặc tả, và các bước theo sau dựa trên review code cũng thường chỉ cần 2–3 lượt, nhưng rồi chẳng mấy chốc lại quay về giai đoạn cần đặc tả mới. Ngoài ra, khi tôi rời máy, ngay cả khi agent đã hoàn thành việc đang làm và có thể bắt đầu một đặc tả sẵn có khác không bị xung đột vì không đụng file, nó cũng không biết rằng có thể tạo branch mới rồi bắt đầu. Trước khi đi ngủ tôi thường bảo “hãy làm việc X, hoàn thành và push xong thì bắt đầu việc Y”, nhưng quá thế là không ổn. Nhiều khi nó bắt đầu Y rồi phát sinh câu hỏi, và sau đó agent đứng im hết phần thời gian còn lại. Vấn đề cuối cùng là tính phụ thuộc, kết hợp với tất cả những điều trên. Ví dụ hôm nay tôi viết một worker xử lý tác vụ nền, và dĩ nhiên các job của những việc sau đó sẽ cần hệ thống đó. Chuyện này xảy ra khá thường xuyên. Bản thân đặc tả cũng cần được cập nhật sau khi triển khai để phản ánh các chi tiết đã được quyết định trong quá trình thực hiện. Dù vậy, giờ tôi đã gần tới điểm cần một vòng lặp bên ngoài. Điểm nghẽn gần như hoàn toàn nằm ở việc viết đặc tả và review PR. Ở những chỗ mà nút thắt đó không quan trọng, tôi muốn agent cứ tiếp tục chạy. Ngoài ra, tôi tin rất mạnh rằng chúng ta cần bắt đầu dùng những công cụ tốt hơn cho LLM, dù có thể tệ hơn cho con người. Ví dụ, Rust làm tôi khó chịu vì compiler quá khắt khe, nhưng lại rất tuyệt với LLM

    • Đó chính xác là cách mọi thứ nên vận hành. Tuyệt vời. Đây là phần quan trọng nhất của kỹ nghệ hệ thống, thứ đã bị thu hẹp suốt 20 năm qua trong làn sóng chỉ chăm chăm làm cho nhanh
      Giờ đây việc tạo ra thứ gì đó đã được tự động hóa hơn, nên đặc tả và thiết kế hệ thống có thể một lần nữa quay lại vị trí dẫn đầu quan trọng. Có khi kỹ nghệ và chất lượng sẽ trở lại
    • Điều này cũng khớp với trải nghiệm lập trình của tôi, và với kỳ vọng mà tôi đã nói suốt nhiều năm rằng AI vẫn còn rất xa mới “giải được” việc coding. Phần khó của lập trình không phải là gõ phím để đưa code vào file, mà là hiểu vấn đề và nghĩ ra một lời giải tốt, sạch sẽ, có khả năng mở rộng
      AI rất giỏi trong việc tạo ra một lời giải tạm ổn và chạy được về mặt kỹ thuật, nhưng lại khá yếu trong việc có một tầm nhìn tốt cho lời giải. Nó vẫn rất hữu ích trong việc trao đổi ý tưởng và khám phá để tăng mức độ hiểu biết, nhưng viết một đặc tả tốt để LLM triển khai không hẳn dễ hơn nhiều so với tự viết code
    • Cái bên dưới có thể giải quyết vấn đề đó
      https://www.aihero.dev/skills-handoff
      /handoff là skill mới tôi thích nhất
      https://www.youtube.com/watch?v=dtAJ2dOd3ko
    • Tôi tò mò không biết bạn định nghĩa “kết quả rất tốt” như thế nào. Định nghĩa thành công có bao gồm code sạch và dễ bảo trì không? Tôi phải luôn ở trong vòng lặp. Code của tôi được triển khai cho hàng nghìn người dùng, nên vấn đề gì cũng bị khuếch đại
    • “Viết đặc tả” chính là độ phức tạp nội tại của lập trình. Cuối cùng thì vẫn là không có viên đạn bạc
      Có agent hay không, dùng thẻ đục lỗ hay interpreter, thì rốt cuộc lập trình vẫn là lập trình
  • Mùi code lớn nhất của LLM là nó cố “xử lý mọi trường hợp sai”, giờ thì còn cố xử lý cả những lỗi không thể xảy ra. Tôi không hiểu vì sao nó lại ám ảnh chuyện đó đến vậy
    Trong Python, điều này thường xuất hiện trong codebase được kiểm tra kiểu đầy đủ, theo kiểu gắn thêm kiểm tra hasattr cho một kiểu đã được định nghĩa là có thuộc tính đó. Tại sao lại làm vậy? Tôi tự hỏi là do tiền huấn luyện hay do học tăng cường. Nếu là vế sau thì mong các phòng nghiên cứu sửa giúp

    • Có lẽ vì nó chọn mắc lỗi theo hướng xử lý lỗi không cần thiết thay vì bỏ sót xử lý lỗi. Khả năng cao là trong huấn luyện, lỗi runtime bị phạt rất nặng
    • Tôi nghĩ phần lớn là do dữ liệu huấn luyện. Tôi cũng thuộc phe “hãy làm cho trạng thái sai không thể được biểu diễn”
      Trên HN người ta nói nhiều về chuyện này, nhưng tôi vẫn thấy ngạc nhiên mỗi khi thấy một codebase không phải do mình viết — dù là mã nguồn mở hay ở chỗ làm — thực sự làm tốt điều đó. Đa số lập trình viên nghĩ theo kiểu vá chỗ lỗi bật ra thông báo, thay vì thiết kế sao cho lỗi không thể xảy ra và để dữ liệu phản ánh thực tế đó. Tôi nói “đa số” vì tôi cho rằng AI hiện tại cũng có đúng vấn đề về tư duy này. Hiện rất khó để trao cho AI mức độ hiểu codebase như con người ở giai đoạn cuối, tức là hiểu toàn bộ dòng chảy của các bảo đảm. Ở cấp độ mã nguồn thô, những bảo đảm đó thường trải dài qua lượng mã đủ lớn để dễ dàng làm tràn cửa sổ ngữ cảnh. Ngay cả khi cố tóm tắt bằng các file kiểu bộ nhớ thì vẫn có vấn đề. Việc có văn bản mô tả các bảo đảm không có nghĩa là AI sẽ lấy ra đúng thông tin, và con người chỉ đọc code cũng vậy thôi. Tôi không nói việc trao cho AI kiểu hiểu biết này là “bất khả thi”, nhưng ngay cả nếu làm được thì cách AI làm việc cũng thường đi ngược lại chính sự hiểu đó. Giải pháp của tôi phần lớn là từ bỏ việc mong AI tự hiểu chuyện này. Tôi biến cách giải quyết vấn đề thành prompt như cách người bình thường vẫn làm, và nếu muốn làm cho các trạng thái sai tệ hại trở nên không thể biểu diễn thì tôi bảo AI thực hiện quá trình refactor cần thiết theo từng bước. Nếu việc rất nhỏ thì tôi tự làm. Nếu bảo nó từng bước tăng mức độ type hóa cho những đoạn code đầy map/dictionary, mảng, chuỗi và số nguyên thì thực ra nó làm khá tốt. Dù có viết chi tiết đến đâu, tôi hiếm khi nhận được thiết kế tốt chỉ với một prompt duy nhất. Tách thành hai nhiệm vụ riêng thì hợp hơn. Và phải nhìn rất kỹ sự khác biệt trong các kiểu. AI rất thích lén nhét vào các phương thức kiểu .JustSetItAndIgnoreAllThePreAndPostConditions(string). Có lẽ trong dữ liệu ngoài đời có rất nhiều trường hợp “một kiểu được cấu trúc tốt để khiến trạng thái lỗi không thể biểu diễn, rồi sau này một người bảo trì đến và thêm vào phương thức JustEffingDoIt phá hỏng tất cả”. Một trong những cách phòng thủ tốt nhất là đặt các kiểu đó trong file riêng, để dễ rà soát mọi phương thức mới được thêm vào và sửa ngay nếu có kiểu làm bậy đó. Tôi đã thử viết đầy cảnh báo trong tài liệu rằng đừng làm vậy, kèm theo hàng đống điều kiện tiên quyết và hậu điều kiện cần được giữ, nhưng thay đổi rất ít
    • Vì phần lớn áp đảo các codebase trong tập huấn luyện hoặc là không được kiểm tra kiểu đầy đủ, hoặc đơn giản là chẳng sạch sẽ gì cả. Hoặc cũng có thể vì đó là các mẩu từ Stack Overflow, nơi không có ngữ cảnh sẵn có nên không thể giả định rằng kiểm tra null là vô nghĩa
    • Thật sự rất đồng cảm. Việc dùng getattr cho mọi dataclass là một lựa chọn kỳ quặc
    • Vì nó khớp với các mẫu đã được học. AI không hiểu code. Nó không thể suy luận được luồng logic thực sự, chỉ có thể xử lý mẫu
  • Code là một phần của sự hiểu biết được chia sẻ và tích lũy về các hệ thống thông tin
    Nếu các vòng lặp này khiến tất cả chúng ta tiếp tục chuyển động giữa làn sóng phần mềm không ngừng dồn tới, thì ở cấp độ cao nhất của thiết kế hệ thống thông tin logic, rốt cuộc mọi thứ sẽ xoay quanh phán đoán của con người và sự cân bằng với yêu cầu kinh doanh. Để khớp với một ngách cụ thể của công ty hay thị trường, mọi lập trình viên sẽ phải trở thành nhà phân tích kinh doanh, nhà nghiên cứu thị trường và doanh nhân. Ngoại lệ là những ngách nhất định mà công cụ AI không thể “lạch cạch” làm tốt, hoặc khi thời đại token AI được trợ giá kết thúc và tất cả các vòng lặp này trở nên quá đắt đỏ. Cảm giác này giống như sự lặp lại của các hệ chuyên gia và máy Lisp của Symbolics. Trong chốc lát, điều chúng ta đối mặt là: không phải bản thân code không làm được gì đó, mà là cấu trúc tổ chức của công ty cuối cùng cũng in nguyên vào phần mềm; nếu không thể thay đổi tổ chức công ty thì tính linh hoạt của phần mềm cũng sẽ có giới hạn. Sơ đồ luồng dữ liệu, tri thức miền, mô hình hóa miền và ngôn ngữ phổ quát có thể trở thành siêu ngôn ngữ để chúng ta xác định chất lượng, tính năng và các tiêu chuẩn, quy ước phi chức năng. Phải khiến các “clanker chạy vòng lặp” đáp ứng được các hợp đồng về dữ liệu, hành vi và hiệu năng trước khi chúng nói là “xong”. Giờ đây “xong” không chỉ có nghĩa là code biên dịch được, build được, deploy được, thậm chí chạy được trên production. Nó phải là code đáp ứng được yêu cầu của người dùng, người vận hành và người bảo trì. Vì vậy, ngôn ngữ được dùng có thể khiến tất cả chúng ta trở nên gần với nhà phân tích kinh doanh và kiến trúc sư phần mềm hơn là chỉ là người biết cú pháp. Đây có phải là sự báo thù của UML và sự trở lại của thiết kế khai báo, logic và BDD không?
    Tôi đã dùng gemma4-12b để kiểm tra chính tả, nhưng không để nó thay đổi thông điệp

  • Tôi cứ nghĩ mãi không biết từ khi nào mình không còn phải bị ép ở trong vòng lặp nữa. Với tư cách một lập trình viên, tôi thực sự thích việc gọt giũa cấu trúc code, làm nó rõ ràng hơn, nghĩ ra các abstraction tốt và chia thành module
    Tôi tìm thấy niềm vui ở đó, nhưng đến một lúc nào đó tôi cũng hiểu rằng chính mình lại trở thành yếu tố giới hạn. Nếu mục đích của phần mềm là mang lại lợi ích cho con người, thì liệu tôi còn nên quan tâm code trông như thế nào không? Hiện tại tôi nghĩ câu trả lời là “có”, nhưng 3 năm nữa thì sao? 10 năm nữa thì sao?

    • Nếu bạn muốn phần mềm tiếp tục mang lại lợi ích cho con người, thì câu trả lời là
    • Nếu bạn đang ở một nơi ngoài kỹ thuật ra thì chẳng thấy nhiều ý nghĩa, điều đó có thể rất khó khăn. Có cảm giác một bước ngoặt hiện sinh sang công việc đem lại nhiều thỏa mãn hơn sẽ sớm đến. Có thể đó là suy nghĩ ngây thơ, hoặc đơn giản chỉ là điều tôi cảm thấy mình cần nói với chính mình
    • Refactor lúc nào cũng có thể giao cho agent làm. Nó thậm chí có thể xử lý cả những cuộc đại tu lớn đến mức chỉ nghĩ thôi cũng thấy mệt
  • Nếu điều gì đó đòi hỏi rất nhiều phán đoán và là “đoạn mã tôi thực sự quan tâm sâu sắc”, thì khó mà đồng ý với hướng tiếp cận đang được nói đến ở đây. Không nên cố ủy quyền những quyết định mà mình quan tâm sâu sắc
    Tôi thích sự phân biệt giữa vòng lặp tác nhân và vòng lặp harness, nhưng chỉ nên ủy quyền những gì có thể được đặc tả chính xác từ trước. Với tôi, đó thường là các tác vụ có thể lặp lại, ví dụ như “xem X đã được làm như thế nào rồi làm Y theo cách đó”, và về bản chất đây là những việc có thể dự đoán được. Nếu khi thiếu đi phán đoán của tôi thì cuối cùng đó vẫn là việc tôi sẽ nói “không”, thì nên hạ xuống hợp tác trong vòng lặp tác nhân mà Armin nói tới. Điều đó hoàn toàn ổn. Vừa nhanh vừa an toàn. Ngay cả trước thời AI coding assistant, thỉnh thoảng cũng có những kỹ sư cực kỳ năng suất gia nhập đội ngũ. Đồng nghiệp sẽ ghen tị và nói “Các cậu làm được hết chỗ đó chẳng phải vì trong đội có X sao!”, nhưng họ chưa từng trải qua lời nguyền của việc có một người như vậy ở bên cạnh. Nếu không hoàn toàn đồng bộ, họ sẽ lao rất nhanh theo hướng sai

    • Không nên ủy quyền những quyết định mà mình thực sự quan tâm sâu sắc. Hoặc phải tìm ra một phương pháp mang tính quyết định để đưa quyết định đó vào
    • Chính xác. Nếu đó không phải việc bạn sẽ thuê ngoài cho một người mà bạn cho là có tay nghề rất cao, thì tại sao lại thuê ngoài cho máy?
  • Tôi không hiểu rốt cuộc điều này thực sự có nghĩa là gì. Nó chỉ là một bài viết dài dòng liệt kê các khái niệm trừu tượng có vẻ như được thiết kế để gợi ra một bức tranh lớn hơn, nhưng cuối cùng vẫn chỉ là nói về việc để AI viết code
    Tương lai sẽ là thế này sao? Thực ra chúng ta không còn là người dẫn dắt tư duy nữa, mà đang trở thành kiểu giáo viên giả hiệu cố lùa một bầy AI ngốc về phía đáp án đúng, nhưng vẫn phải thần bí hóa vai trò của mình để trông như thể vẫn là người dẫn dắt tư duy? Miễn là không bị phát hiện tất cả chỉ là ra vẻ công nghệ?

    • Đây không phải bài viết dài dòng, cũng không hề trừu tượng. Nội dung ở đây nói về hiệu ứng bậc hai của việc “để AI viết code” theo cách ít bị giám sát hơn
      Tác giả có thể biên tập ngắn gọn hơn, nhưng chỉ vì độc giả hiện tại không hiểu nội dung không có nghĩa là ở đây đang có sự thần bí hóa
    • Cứ hấp thụ cơn sốt thổi phồng AI thì sẽ nói năng như thế đấy. Yegge còn là ví dụ nặng hơn
    • Tôi tin chắc ngành kỹ thuật phần mềm đang tách làm hai. Đây là những mối lo thực sự, và là một logic nhất quán, có ý nghĩa đối với các lập trình viên đã dùng vòng lặp tác nhân và quy trình làm việc có hỗ trợ AI mạnh
      Tôi đang thấy chính xác điều bài gốc nói đến trong công việc và các dự án cá nhân của mình, nên việc có người xem đây là “một bài viết dài dòng liệt kê các khái niệm trừu tượng” làm tôi thấy đáng sợ. Tôi có cảm giác phần lớn mọi người hoàn toàn không nhận ra chuyện gì đang diễn ra lúc này
    • Các blog kỹ thuật ngày xưa đọc như hướng dẫn README có thể làm theo ngay. Khi đọc bài này tôi cứ nghĩ “Rốt cuộc mình phải làm gì với thông tin này?” nên không đọc hết
      Trong lĩnh vực AI, thời hạn sử dụng của kỹ thuật tối tân mới nhất chỉ khoảng 2 tuần. Tôi còn chưa theo kịp vòng lặp Ralph Wiggum, nên giờ lại thấy may vì mình đã không cố thử
      https://news.ycombinator.com/item?id=46682325
    • “Thực sự có nghĩa là gì” à, nghĩa là hãy dùng nhiều token hơn