Đây là phần hai của Tại Sao Các Nhà Máy Phần Mềm Thất Bại
Phiên bản nói chuyện của bài viết này có trên youtube: https://www.youtube.com/watch?v=Ib5GBkD555M
Bật đèn trở lại
Trong phần 1, tôi đã đi sâu vào lý do tại sao không thể tin tưởng các mô hình để duy trì chất lượng codebase theo thời gian. Tại sao không có một lượng kỹ thuật harness hay tokenmaxxing nào có thể giải quyết được vấn đề huấn luyện mô hình và benchmarks. Tại sao "mô hình làm người phán xét" cho chất lượng code không hiệu quả như một số người muốn bạn tin.
Hiện tại, người phán xét là bạn -- vì vậy chúng ta sẽ đưa code review trở lại.

Chúng ta sẽ đón nhận điều tương tự mà chúng ta đã làm từ trước thời AI, đó là lên kế hoạch một chút từ đầu, để giảm khả năng xảy ra một quy trình review dài và khó khăn.
Chúng ta sẽ tìm kiếm đòn bẩy, và chúng ta sẽ sử dụng AI để hỗ trợ việc này, qua 4 giai đoạn:
- Yêu cầu Sản phẩm
- Kiến trúc Hệ thống
- Thiết kế Chương trình
- Các lát cắt Dọc
Product review (Đánh giá sản phẩm)
Mọi thứ bắt đầu bằng một product review: một tài liệu ngắn xác định rõ chúng ta đang xây dựng cái gì và tại sao. Mục tiêu là có thể lấy hai câu hoặc một đoạn ghi chú thoại dài và biến nó thành một thứ có cấu trúc.
Đầu tiên, chúng ta thống nhất về vấn đề cần giải quyết -- nỗi đau thực sự của người dùng, theo cách diễn đạt của người dùng. Thứ hai, thành công trông như thế nào -- chúng ta có thể đọc được điều gì sau khi phát hành để quyết định rằng thứ đó đáng để xây dựng. Lý tưởng nhất là một kết quả cho người dùng như "có thể thực hiện quy trình XYZ trong thời gian ngắn hơn" hoặc "đạt được cột mốc onboarding ABC sớm hơn". Đôi khi nó ở cấp độ thấp hơn như tỷ lệ lỗi hoặc con số độ trễ, đôi khi chỉ là "các ticket hỗ trợ về X dừng lại."
Chúng tôi cố gắng giữ cho điều này khá thực tế trong không gian sản phẩm, không phải kỹ thuật. Là một người sống với một chân trong thế giới sản phẩm và một chân trong công nghệ, tôi thường thấy mình lạc sang các chi tiết kỹ thuật ở đây. Khi điều đó xảy ra, tôi cố gắng chỉ ghi chú lại cho các giai đoạn sau và quay lại những gì người dùng thực sự trải nghiệm. Nếu các quyết định kỹ thuật đang cản trở các quyết định sản phẩm, thì chúng tôi cam kết những gì đã có và chuyển sang kiến trúc hoặc thực hiện nghiên cứu nguyên mẫu thêm về những gì khả thi
Và vì hầu hết những điều này là về những gì người dùng thấy, tôi không mô tả nó -- tôi tạo mockup. Một mockup HTML thô của màn hình thực tế sẽ giải quyết một cuộc tranh luận mà ba đoạn văn chỉ kéo dài thêm.
Đây là một ví dụ thực tế đang được thực hiện -- tài liệu xác định tính năng với một dàn ý JSON, sau đó là hai mockup HTML thô của các màn hình thực tế:
https://x.com/dexhorthy/status/2078592010852982977
Tất nhiên, không phải mọi thứ đều cần product review. Một chỉnh sửa sao chép, một script dùng một lần, một lỗi với cách tái tạo rõ ràng -- chúng tôi vẫn gửi thẳng những thứ đó cho agent. Điều này dành cho những thay đổi mà việc agent hiểu sai ý định của chúng tôi sẽ rất tốn kém.
Đối với tài liệu này và tất cả các tài liệu trong loạt bài, chúng tôi thực hiện reviews theo hình thức tác giả tự chọn tham gia. Nếu bạn muốn tiết kiệm thời gian trong quá trình review, bạn chọn người sẽ review PR, và xem qua các thông số kỹ thuật sản phẩm/công nghệ với họ, không đồng bộ qua các bình luận trong tài liệu (chúng tôi dogfood humanlayer cho việc này, nhưng bạn cũng có thể dễ dàng thực hiện điều này trong github/notion/plannotator/v.v.).
Kiến trúc Hệ thống
Khi product review đã được giải quyết, chúng tôi thực hiện kiến trúc hệ thống. Điều này không đặc biệt mới lạ và là thứ mà ngay cả những người code theo vibe cũng bắt đầu thề thốt.
Nếu bạn muốn tiết kiệm thời gian trong quá trình review, bạn chọn người sẽ review PR, và xem qua các thông số kỹ thuật sản phẩm/công nghệ với họ trước khi bạn bắt đầu phần code.
Trong giai đoạn này, chúng tôi thống nhất về cách các dịch vụ, endpoints, schemas, hàng đợi và kho dữ liệu giao tiếp với nhau, mà không đi vào chi tiết của thiết kế chương trình. Để tối đa hóa băng thông giao tiếp giữa con người và agent, chúng tôi sử dụng nhiều hình ảnh trực quan ở đây - ví dụ như sơ đồ tuần tự:

Hình dạng Contract / Endpoint:

Mô hình dữ liệu và các phép biến đổi:

Mermaid cũng ổn ở đây nhưng đôi khi nó có thể thừa thãi và đôi khi dụ bạn vào một cảm giác sai lầm rằng bạn đã thống nhất với nhau. Kiến trúc có tính đòn bẩy khá cao và có rất nhiều tật xấu tiềm ẩn của mô hình mà bạn có thể ngăn chặn trong giai đoạn này. Nhưng nó không đủ để tạo ra code chất lượng cao. Để làm được điều đó, chúng ta cần thiết kế chương trình.
Thiết kế Chương trình
Sau kiến trúc, chúng tôi thực hiện một điều mà tôi nghĩ là bị đánh giá thấp một cách nghiêm trọng trong coding agent: thiết kế chương trình.
Hầu hết mọi người cho rằng một khi kiến trúc đã đúng, mô hình có thể tự nấu ăn. Bạn có thể tiếp tục làm điều này, nhưng bạn có thể không thích những gì bạn nhận lại.
Nhưng điều tôi thấy hoạt động hiệu quả là trước khi bất kỳ ai (con người hay agent) viết phần triển khai, chúng ta đi xuống một cấp độ từ kiến trúc vào hình dạng của code: các kiểu dữ liệu (types), chữ ký phương thức (method signatures), bố cục chương trình và các call stacks.
Phiên bản đầu tiên của kỹ năng thiết kế chương trình của chúng tôi rất tệ. Nó khó đọc, nó kiệt sức. Chúng tôi đã thử mermaid, nó có chỗ đứng của nó, nhưng thứ chúng tôi thực sự yêu thích là các hình ảnh trực quan nhẹ nhàng trong pseudocode:
Call-stack trees, cho bất kỳ thay đổi điều phối hoặc luồng điều khiển nào. Sử dụng cú pháp diff khi phần thú vị là những gì đang thay đổi:

Dillon Mulroy nói về việc sử dụng đồ thị cuộc gọi (call graphs) như một phần trong quy trình lập kế hoạch của anh ấy, và tôi nghĩ điều đó hoàn toàn đúng.
File-tree diffs - để bạn có thể nắm được bố cục của codebase và nơi mọi thứ nằm ở đâu

Các kiểu dữ liệu và chữ ký phương thức cho các hàm mới chính -- những thứ quá nội bộ đối với tài liệu kiến trúc nhưng agent vẫn có thể làm sai

Không có thứ nào trong số này mất nhiều thời gian để tạo ra (mô hình phác thảo chúng, bạn tranh luận với nó), và mỗi thứ trong số chúng đều là một quyết định mà bạn sẽ phải đưa ra một cách ngầm định trong quá trình code review -- vào thời điểm đắt đỏ nhất để thay đổi quyết định của bạn.
Các lát cắt Dọc
Tiếp theo, chúng tôi thích làm điều mà tôi gọi là "các lát cắt dọc" - Matt Pocock và tôi đã có một
cuộc trò chuyện về các lát cắt dọc hoặc "đạn đánh dấu" (tracer bullets) trên một buổi livestream vào tháng 1 năm 2026 - điều này còn được gọi là - đạn đánh dấu
Các mô hình thích thứ tôi gọi là "kế hoạch ngang" - làm mọi thứ theo thứ tự ngăn xếp:
- Database Migrations
- Service Layer
- API
- Frontend

Trên thực tế, điều này có nghĩa là không có cách thực sự nào để "chạm" vào giải pháp khi bạn đang tiến hành. Bạn có thể kiểm tra mọi thứ bằng code, nhưng đối với hầu hết mọi tính năng tôi từng xây dựng, đọc các bài kiểm tra là một khởi đầu nhưng kéo một thứ gì đó lên trong trình duyệt, hoặc dùng curl để gọi nó trong khi tôi đang làm việc luôn là một phần thường xuyên của quy trình làm việc.
Trước AI, hiếm khi ai đó viết hơn 2000 dòng code hoặc thậm chí 500 dòng code mà không kiểm tra một thứ gì đó trên đường đi.
Tôi đã mất một thời gian để nhận thấy sự khác biệt so với những gì tôi đã quen - khi tôi viết code trước AI, tôi luôn bắt đầu ở giữa và làm việc ra bên ngoài. Một cách mơ hồ:
- Tạo API contract và phục vụ dữ liệu giả (mock data), kiểm tra bằng curl
- Tạo frontend để tiêu thụ dữ liệu giả, lặp lại và đánh bóng trong trình duyệt
- Kết nối API với lớp dịch vụ (services phục vụ dữ liệu/hành vi giả)
- Thêm database migrations, kết nối các dịch vụ với cơ sở dữ liệu
- Thêm một loạt logic nghiệp vụ
- Thêm một loạt xử lý lỗi
Và tôi sẽ kiểm tra/lặp lại/đánh bóng ở mỗi bước.

Nếu tôi quan tâm nhiều đến code hoặc hoài nghi về khả năng của mô hình để làm việc tốt trong phần này của codebase, tôi cũng sẽ review code ở mỗi bước. Kiểm tra 100-200 dòng và định hướng lại sẽ rẻ hơn nhiều
Ở đây, tôi sẽ làm vậy. Hầu hết các mô hình tiên tiến sẽ không thiết kế một kế hoạch như thế này nếu không có sự định hướng của con người, và thật khó để khái quát hóa cho từng codebase hoặc thậm chí từng tác vụ, vì vậy tôi thích ở lại trong vòng lặp ở đây. Hãy tin tôi. Nếu tôi có thể outsource việc suy nghĩ
30 phút lập kế hoạch tiết kiệm hàng giờ review
Và vì vậy chúng tôi có một số bước mà tôi cho rằng con người cần phải tham gia vào vòng lặp, nếu bạn muốn duy trì chất lượng gần như con người mà không phải vật lộn với núi code tệ hại để cố gắng dọn dẹp nó sau đó. (tức là bạn thực sự muốn đi nhanh)
- Thiết kế Sản phẩm
- Kiến trúc Hệ thống
- Thiết kế Chương trình
- Các lát cắt Dọc
Rõ ràng là chúng tôi không làm toàn bộ quy trình này cho mọi thứ chúng tôi phát hành (xem mục phụ bên dưới). Tôi đoán sự phân bổ sẽ gần như:
- Khoảng 40% các tác vụ được gửi thẳng một phát hoặc một phát kèm 1-2 vòng phản hồi nhẹ
- Đối với các tác vụ vừa, chúng tôi thực hiện thiết kế sản phẩm/hệ thống tất cả trong một tài liệu kế hoạch duy nhất và không bận tâm chia nhỏ công việc thành các giai đoạn
- Đối với những thứ lớn, chúng tôi thực hiện tất cả các bước. Chúng tôi sẽ bỏ qua phần sản phẩm cho những thứ mà nó không phù hợp như các bản refactor lớn.
Và trong hầu hết các trường hợp, tôi sẽ gửi một mô hình để thực hiện 1-3 lát cắt cùng một lúc và review code khi tôi tiến hành. Việc định hướng lại sớm sẽ dễ dàng hơn nhiều, cho dù đó là nội bộ hay chức năng thực tế, hơn là kết thúc ở phía bên kia của hơn 2k dòng code mà không biết cái gì bị hỏng.
Bạn có thể cảm thấy mình có quá nhiều pull requests
Bạn không có quá nhiều PR. Bạn có quá nhiều PR tệ.
Tất cả chúng ta đều đã review rất nhiều PR cần làm lại, từ rất lâu trước AI.
Nhưng một PR tuyệt vời là một niềm vui để review. Bạn đang cuộn qua từng file, code sạch sẽ, nó tuân theo tất cả các quyết định/cuộc thảo luận/ý kiến khó giành được của bạn về cách phần mềm nên được xây dựng.
Mặt khác, nếu một Pull Request cần thậm chí 20% làm lại (và đó là một sự hào phóng, tôi sẽ nói hầu hết các PR một phát từ AI có xu hướng gần 50% hơn), đó vừa là gánh nặng trí tuệ vừa là gánh nặng cảm xúc cho cả người gửi và người review. (Ngay cả khi người gửi là AI, ai đó có thể đã bắt đầu công việc này hoặc trau chuốt kết quả AI hoặc ít nhất là quan tâm đến kết quả).
Để tiết kiệm thời gian cho bạn (chúng ta sắp kết thúc rồi), tôi đã nói lan man thêm về điều này trong một mục phụ:
một lý thuyết về các ràng buộc (phiên bản 2026)
Thật dễ dàng để hơi thất vọng với luận điểm chính ở đây: "hiện tại chúng ta bị mắc kẹt với việc đọc code."
Tôi đã khá hào hứng với một thế giới nơi chúng ta có thể chỉ cần yêu cầu mọi thứ và để các mô hình tự nấu ăn và không đọc code và nhận được phần mềm sản xuất đẹp đẽ phát triển theo thời gian và không trở nên tồi tệ.
Nhưng những gì tôi đã cố gắng hết sức để trình bày ở đây không gì khác ngoài những ràng buộc. Các mô hình giỏi một số thứ, không giỏi một số thứ khác. Làm thế nào để bạn tối ưu hóa quy trình của mình dựa trên những ràng buộc đó?
Các mô hình giỏi một số thứ, không giỏi một số thứ khác. Làm thế nào để bạn tối ưu hóa quy trình của mình dựa trên những ràng buộc đó?
Có thể bạn đang quá bận rộn cố gắng di chuyển nhanh hơn 10-100 lần và cố gắng thuyết phục bản thân rằng chất lượng code không còn quan trọng nữa, trong khi bạn có thể chấp nhận các ràng buộc và di chuyển nhanh hơn 2-3 lần, một cách an toàn.
Lời khuyên kết thúc kiểu của tôi về cơ bản là:
- Học các ràng buộc thật kỹ, phát triển trực giác bằng cách làm việc nhiều với các mô hình
- Tối ưu hóa các hệ thống trong phạm vi của các ràng buộc này
- Tìm kiếm đòn bẩy
- Đọc cái code chết tiệt đó
Đó là tất cả. Nếu bạn muốn ở lại để nghe phần chào hàng, hãy tiếp tục cuộn, tôi đoán vậy. Tôi hy vọng điều này giúp bạn tránh được thảm họa hoặc ít nhất là bạn đã vui vẻ khi xem một số hoạt ảnh dễ thương.
Cảm ơn vì đã đọc
-dex
PS Chúng tôi bị ám ảnh bởi điều này
Chúng tôi đang xây dựng humanlayer.com, một IDE agentic và nền tảng cộng tác để giúp bạn di chuyển nhanh hơn 2-3 lần trong khi vẫn duy trì chất lượng code ở mức con người (hoặc khá gần với con người).
Chúng tôi đang xây dựng hướng tới hai ý tưởng: "các khối xây dựng cho nhà máy phần mềm của bạn" và "bộ xác minh tốt hơn cho khả năng bảo trì phần mềm" (có lẽ là các mô hình tốt hơn nữa).
HumanLayer miễn phí cho các nhóm nhỏ lên đến 3 người và nếu bạn muốn được giúp đỡ bắt đầu, bạn có thể đến tham gia discord của chúng tôi hoặc gửi email cho chúng tôi theo địa chỉ founders@humanlayer.dev
Một lời cảm ơn nhanh tới @calvinfo vì nguồn cảm hứng, tới đồng sáng lập của tôi @0xBlacklight, tới @swyx và nhóm tại @aiDotEngineer vì đã cho tôi một đấu trường để khám phá những ý tưởng này, và tới tất cả các khách hàng, nhà đầu tư, bạn bè và gia đình tuyệt vời của chúng tôi đã cổ vũ chúng tôi.
Nếu bạn muốn tìm hiểu thêm, về cơ bản tôi sẽ không ngừng nói về điều này, vì vậy bạn có thể tìm thấy tất cả các liên kết từ bài viết này cũng như một số hình thức trình bày khác của tài liệu dưới dạng podcast, bảng trắng dạng dài, v.v., bên dưới.
PPS Các tài nguyên khác
Podcasts và Bài viết:
- Dex và Gergely nói về kỹ thuật ngữ cảnh và nhà máy phần mềm trên The Pragmatic Engineer - Tháng 7 năm 2026
- Dex và Matt Pocock nói về lời khuyên coding AI lâu dài (và vòng lặp ralph) - Tháng 1 năm 2026
Các tập AI That Works:
- Benchmarks chẳng chứng minh được gì
- Thông số Kỹ thuật Sản phẩm cho AI Coding
- Các bài kiểm tra Học tập để có backpressure tốt hơn
- Áp dụng các nguyên tắc 12-factor agents vào AI coding
Các liên kết từ bài viết này:
- Tại Sao Các Nhà Máy Phần Mềm Thất Bại bài phát biểu chính — AI Engineer World's Fair 2026
- Nhà máy phần mềm tắt đèn của StrongDM
- OpenAI: Kỹ thuật Harness (Tháng 2 năm 2026)
- Ryan Lopopolo trên Symphony (bài nói, Tháng 4 năm 2026)
- Mario tại AI Engineer Europe: "Xây dựng pi trong một thế giới đầy rác"
- FT: Sự cố mất điện của Amazon do sai sót của coding-agent
- Matt Pocock: các codebase đang sụp đổ
- Faros AI: báo cáo về cú sốc tăng tốc AI
- Kỹ thuật Ngữ cảnh Nâng cao cho Coding Agents (bài nói 8/25)
- Không Có Vibe Nào Được Phép (bài nói 11/25)
- Tất Cả Những Gì Chúng Ta Đã Sai Về RPI (bài nói 3/26)
- Awesome-RLVR - Tài nguyên Học Tăng cường
- Kỹ thuật Ngữ cảnh Nâng cao cho Coding Agents (bài viết)
- 12-Factor Agents
- Addy Osmani về vibe-coding và bảo trì
- Hội nghị Kỹ thuật Phần mềm NATO, 1968
- Tài liệu Tham khảo Thiết kế DevSecOps của DoD (PDF)
- Nền tảng coding-agent của Ramp
- Stripe: Minions, coding agents một phát từ đầu đến cuối
- WorkOS: Project Horizon
- Brex (Latent Space)
- Dan Shapiro: năm cấp độ dẫn đến nhà máy phần mềm
- Simon Willison về nhà máy phần mềm của StrongDM
- "Đun sôi đại dương"
- Phẫu thuật bằng súng ngắn (shotgun surgery) (refactoring.guru)
- John Ousterhout — Một Triết lý về Thiết kế Phần mềm
- Robert C. Martin — Clean Code
- Martin Fowler — Refactoring
- aider
- cline
- codebuff
- Bài báo SWE-Agent (2024)
- Bài nói OpenAI Codex (Tháng 11)
- Bài nói Calvin French-Owen — AI Council
- SWE-bench Đa ngôn ngữ (bộ dữ liệu)
- AIE Worlds Fair 2026 - Cuộc tranh luận về các Vòng lặp Lớn ("sự cường điệu đang vượt quá kỷ luật")
- SWE-Marathon (Abundant AI)
- DeepSWE (Datacurve)
- Frontier Code (Cognition)
- Kiểm thử đột biến (Wikipedia)
- Dillon Mulroy về đồ thị cuộc gọi trong lập kế hoạch
- Dex × Matt Pocock: các lát cắt dọc / đạn đánh dấu (livestream, Tháng 1 năm 2026)
- "Công việc khó khăn của suy nghĩ không thể được outsource" (Jake Nations)





