Tự động hóa sự nghi ngờ: Quy trình phát triển phần mềm tin cậy với AI

Phần mềm07 tháng 6, 2026·12 phút đọc

Bài viết chia sẻ quy trình phát triển phần mềm sử dụng AI, nơi tác giả áp dụng "sự nghi ngờ tự động hóa" thông qua các tác nhân phụ (subagents) để kiểm tra và đánh giá mã nguồn. Bằng cách đa dạng hóa các góc nhìn kiểm tra trong giai đoạn thiết kế, phát triển và đóng gói, quy trình này giúp khôi phục niềm tin vào chất lượng code do AI tạo ra. Đây là phương pháp nhằm đảm bảo tính nhất quán, khả năng bảo trì và an toàn cho dự án.

Quy trình này bắt nguồn từ sự thiếu tin tưởng. Tôi đã mất niềm tin vào giai đoạn đầu phát triển hỗ trợ bởi AI vì đã cho phép các đối tác Mô hình Ngôn ngữ Lớn (LLM) làm quá nhiều việc, quá nhanh mà thiếu các kỹ thuật kỹ thuật tiêu chuẩn mà tôi đã từng nội hóa. Niềm tin được khôi phục bằng cách tự động hóa càng nhiều sự nghi ngờ càng tốt. Việc thực hiện sự nghi ngờ trông như thế nào? Đó là phê bình thực thi của một sản phẩm và làm việc đó lặp đi lặp lại. Nếu bạn đang sử dụng AI để viết code, thông số kỹ thuật (specs), tài liệu hoặc bất kỳ sản phẩm nào, bạn có thể thấy bài viết này hữu ích.

Tôi sử dụng các tác nhân phụ (subagents) rất nhiều. Chúng đóng vai trò là điểm tựa của toàn bộ quy trình. Chúng được chuyên biệt hóa theo cách kiểm tra các bề mặt quan điểm mà một phiên bản Claude tiêu chuẩn không nhất thiết bao quát được. Ý tưởng cốt lõi ở đây là sự nghi ngờ tự động hóa từ nhiều góc độ khác nhau và việc đưa việc kiểm tra lên ngay từ đầu. Độ phủ thị sai càng nhiều trong phát triển AI càng tốt; nơi các điểm quan sát khác nhau bắt được các khiếm khuyết khác nhau, giống như cách hai mắt cho bạn độ sâu của thị giác.

Quy trình phát triển diễn ra như sau:

Giai đoạn 1 — Thiết kế

Nó bắt đầu với một ý tưởng hoặc tính năng tôi muốn xây dựng và một bản thông số kỹ thuật. Giống như bất kỳ thực hành phát triển tốt nào, việc bắt đầu với một bản spec, PRD, kế hoạch hay bất kỳ hình thức thiết kế nào được ưu tiên là điều khôn ngoan. Tôi yêu Claude viết bản spec và dành 2–5 phút để lướt qua file, xác minh các khía cạnh thực thi cốt lõi của ý tưởng đã được nắm bắt chưa. Đây là nơi quá trình lặp lại bắt đầu.

Tôi bắt đầu với quy trình Trước khi thực thi (Pre-implementation workflow - một lệnh gạch chéo trong Claude Code), bao gồm ba tác nhân thực hiện vòng đầu tiên của sự nghi ngờ: Kiến trúc sư Trước khi thực thi (Pre-Implementation Architect), Trình xác thực Tài liệu (Documentation Validator) và Người khai thác Giả định (Assumption Excavator). Các tác nhân này làm vài việc: xác minh chất lượng thiết kế, đánh giá phạm vi, tính đầy đủ, các khoảng trống tài liệu và tất cả các giả định ẩn tồn tại trong bản spec. Tất cả các phát hiện liên quan được lồng vào bản spec bởi tác nhân terminal chính — thường là 10–25 phát hiện tùy thuộc vào phạm vi của ý tưởng.

Ví dụ về các phát hiện:

  • Người khai thác Giả định: "executionStatsSchema trong registry-sdk trả về {totalCount, recentCount, windowMinutes}. Spec giả định {avgScore, medianDurationMs, passRate, lastRunDate, lastRunScore}. Toàn bộ phần lịch sử không thể xây dựng mà không có endpoint API mới."
  • Kiến trúc sư Trước khi thực thi: "HarnessProfile nhúng các phương thức mcp.read/merge/remove/write cùng với cấu hình đường dẫn. Hãy cân nhắc tách biệt McpConfigStrategy để tách biệt mối quan tâm. Mỗi file harness sẽ phát triển đến 80–120 dòng nếu không làm vậy."

Phạm vi quyết định số lượng lần lặp lại tôi thực hiện. Nếu phạm vi yêu cầu, quá trình lặp lại tiếp tục với tập hợp tác nhân tiếp theo: Trình phân tích Khoảng trống (Gap Analyzer), Trình phát hiện Hoàn thành Ẩn (Implied Completeness Detector), Trình ánh xạ Mơ hồ (Ambiguity Mapper). Các tác nhân này đặc biệt xuất sắc trong việc tìm ra tất cả các khía cạnh bị bỏ sót của hệ thống sẽ bị lỡ nếu không được giải quyết. Khi các khoảng trống được phát hiện, chúng được thêm vào bản spec.

Ví dụ về các phát hiện:

  • Trình phân tích Khoảng trống: "McpConfigStrategy định nghĩa read/merge/write nhưng không chỉ định hành vi cho đầu vào sai định dạng, từ chối quyền, lỗi ghi một phần, hoặc khóa file. Hoạt động phá hủy trên các file cấu hình người dùng trên 4 harness trong 3 định dạng."
  • Trình phát hiện Hoàn thành Ẩn: "Manifest ghi lại phiên bản ở gốc nhưng trạng thái cài đặt theo từng harness. Khi người dùng v0.3.0 (Claude Code) chạy v0.4.0 với --harness opencode, hành vi không được định nghĩa. Việc lập phiên bản theo từng harness hoặc hòa giải nâng cấp không được giải quyết."

Để sử dụng thực tế:

  • Phạm vi nhỏ: Chỉ Trước khi thực thi.
  • Phạm vi trung bình: Trước khi thực thi kết hợp với Gap, Implied, Ambiguity.
  • Phạm vi lớn: Quét toàn bộ với nhiều lần chạy mỗi loại, thỉnh thoảng lấn sang các tác nhân chuyên biệt khác.

Bây giờ tôi dừng lại và dành thời gian đọc bản spec, khoảng 15–60 phút. Nếu mọi thứ kiểm tra tốt và bản spec đã sẵn sàng để phát triển, tôi yêu cầu Claude tạo một danh sách kiểm tra đi kèm để chúng ta có thể cập nhật và theo dõi. Danh sách kiểm tra được tạo thành một file riêng biệt và rất hữu ích nếu bạn cần rời đi và đóng phiên giữa chừng phát triển.

Giai đoạn 2 — Phát triển

Claude mở bản spec và danh sách kiểm tra và bắt đầu phát triển. Nếu tôi tiếp tục bản spec khi phát triển đã hoàn thành một phần trong một phiên mới, tôi thường yêu cầu Claude khám phá, hoặc gửi một tác nhân phụ Chain Tracer hoặc Deep Explore để có bức tranh toàn cảnh trước khi khởi động lại.

Một khía cạnh của quy trình phát triển của tôi có thể nổi bật và tôi muốn nhấn mạnh: Tôi không sử dụng tác nhân phụ để ghi (write). Điều này quay lại vấn đề niềm tin. Kinh nghiệm của tôi về việc tạo ra các tác nhân phụ để ghi đã đi sai hướng, thường gây hại nhiều hơn lợi, dẫn đến việc vạch ra một ranh giới tạm thời. Tôi cũng nói là tạm thời, vì điều này chắc chắn sẽ thay đổi. Theo tôi hiểu, có các phương pháp để điều phối đàn (swarm) đúng cách, worktrees, phát triển dẫn động bởi tác nhân-to-spec, nhưng điều đó hơi vượt quá mức độ tin tưởng của tôi hiện tại. Đôi khi tác nhân terminal Claude sẽ tạo ra chúng để cập nhật hàng loạt, nhưng tôi ưu tiên một phiên bản terminal Claude Code duy nhất xây dựng dự án.

Tôi giải quyết tất cả các giai đoạn của thông số kỹ thuật cho đến khi hoàn thành. Xác minh bản build hoạt động, và sau đó đến quy trình phát triển sau khi thực thi. Tôi đã đề cập đến sự nghi ngờ tự động hóa và đây là nơi nó tỏa sáng. Vài lần lặp lại tiếp theo của quy trình phát triển liên quan đến việc chạy quy trình Sau khi thực thi (Post-implementation workflow) bao gồm các tác nhân phụ sau: Trình xác thực Mã (Code Validator), Trình xác thực An toàn Kiểu (Type Safety Validator), Kiến trúc sư Kiểm thử (Test Architect), Trình tối ưu Mã (Code Optimizer), Trình xác thực Giao diện Công khai (Public Interface Validator) và Chuyên gia An ninh (Security Analyst). Các tác nhân này kiểm tra codebase và cung cấp các phát hiện: chất lượng code & kiểm thử, tư thế an ninh, trùng lặp, cân nhắc hiệu suất, tính toàn vẹn ngữ nghĩa hoặc cấu trúc, tài liệu, giao diện công khai, v.v. Lần chạy đầu tiên thường tạo ra (tùy thuộc vào phạm vi) 15–35 phát hiện, thường với 15–20 phát hiện đầu tiên được gắn cờ là quan trọng hoặc mức độ nghiêm trọng cao. Các phát hiện này được giải quyết và tôi chạy lại quy trình Sau khi thực thi. Sau đó giải quyết tập hợp vấn đề tiếp theo, rồi tiếp theo cho đến khi tôi đạt được ý tưởng của mình về chất lượng nên trông như thế nào.

Ví dụ về các phát hiện:

  • Trình xác thực Mã: "Mọi phương thức thực thi khác đều gọi trackIfEnabled() sau khi hoàn thành. startPipeline() trả về PipelineHandle trực tiếp mà không có theo dõi. Người dùng pipeline bất đồng bộ không nhận được dữ liệu theo dõi."
  • Chuyên gia An ninh: "PreflightError bao gồm đường dẫn mục tiêu đã mở rộng shellQuote nguyên văn. Các thông báo lỗi chứa đường dẫn hệ thống tệp đã giải quyết có thể lan truyền đến API theo dõi và bảng điều khiển."

Giai đoạn 3 — Tổng kết và Phát hành (Wrap-up and Ship)

Một khi tôi đã thỏa mãn sở thích của mình về những gì tôi sẵn sàng phát hành và mọi thứ kiểm tra tốt cả về mặt thực tế lẫn chất lượng, tôi chạy quy trình cuối cùng: Ship. Quy trình này bao gồm các tác nhân sau: Trình xác thực Mã, Trình xác thực An toàn Kiểu, Kiến trúc sư Kiểm thử, Trình kiểm toán Mã (Code Auditor), Trình xác thực Giao diện Công khai, Chuyên gia An ninh, Người đọc Lo âu (Anxiety Reader), Trình xác thực Hợp đồng API (nếu có API), Trình xác thực Sẵn sàng Phát hành (Release Readiness Validator). Quy trình này hoàn tất quá trình lặp lại được giải quyết trong giai đoạn trước. 5/9 tác nhân đều nằm trong quy trình sau khi thực thi, vì vậy chúng nên tìm thấy rất ít hoặc đi vào vùng sở thích, những người khác đang kiểm tra hợp đồng API (nếu liên quan), tính nhất quán thời gian chạy, những gì có thể bị hỏng và tư thế phát hành của hệ thống. Khi điều này chạy, câu hỏi là: liệu cái này đã sẵn sàng để phát hành chưa? Tùy thuộc vào độ phức tạp, điều này có thể yêu cầu 2+ lần lặp lại của Ship.

Ví dụ về các phát hiện:

  • Người đọc Lo âu: "Promise.allSettled kích hoạt tất cả tác nhân đồng thời mà không có giới hạn đồng thời, gây nguy cơ cạn kiệt tài nguyên và giới hạn tốc độ API."
  • Trình kiểm toán Mã: "Lỗi I/O tệp trong writeReportFiles bị bắt bởi handleCoreError cung cấp gợi ý cụ thể của SDK thay vì nhắn tin cụ thể của hệ thống tệp."

Kết luận

Về mặt triết học, đây là sự đàm phán giữa các sản phẩm, các tác nhân và người vận hành và nơi ý tưởng về chất lượng hội tụ. Chúng ta đều có một ý nghĩa về chất lượng đối với mình, ngay cả các tác nhân cũng có ý tưởng về những gì định lượng và đủ điều kiện là chất lượng. Đây là thỏa thuận chúng ta thực hiện với bản thân và các tác nhân: những gì cấu thành sự sẵn sàng. Nền tảng của tất cả là ý tưởng rằng chúng ta đang nhắm đến một dạng sự nhất quán, khả năng sử dụng, khả năng đọc, khả năng bảo trì — và bên dưới những thứ đó, là điều gì đó chúng ta có thể tự tin hơn. Chất lượng có thể là một trạng thái chủ quan, với các mục tiêu khách quan. Tôi lặp lại cho đến khi những ý tưởng đó hội tụ. Làm sao bạn biết khi nào nên dừng vòng lặp? Tôi muốn nghĩ rằng nó trực giác: sự kết hợp của kiên nhẫn, thực hành, phán đoán và chuyên môn của bạn trong việc đặt đúng câu hỏi. Liệu công sức có đáng giá cho bản sửa lỗi hoặc tính năng tiếp theo này không? Nó quay lại ngưỡng cá nhân cho bất kỳ trạng thái dự án nào bạn sẵn sàng phát hành. Nghệ sĩ không bao giờ hoàn thành, còn kỹ sư thì sao? Cuối cùng, nó phụ thuộc vào người vận hành. Điều tốt về việc lập phiên bản là bạn luôn có thể thêm, bớt hoặc sửa đổi theo một cách nào đó và cách chất lượng đó biểu hiện bắt nguồn từ sở thích và quỹ đạo của sản phẩm.

Một cân nhắc của phương pháp, và một điều tôi có thể nêu với sự tự tin: quy trình này không nhất thiết rẻ về token. Đối với những người trong chúng ta đã dành vô số giờ đốt token và đạt đến giới hạn sử dụng, điều này có thể đóng một vai trò lớn trong cách chúng ta phát triển với AI. Đối với một số dự án, quy trình này là quá mức cần thiết (overkill), và đối với những dự án khác, nó đơn giản là chưa đủ và yêu cầu thêm một tập hợp hoàn toàn các tác nhân khác để kiểm toán. Xu hướng cá nhân của tôi là chạy quy trình này và chạy nó lặp đi lặp lại. Tôi muốn đảm bảo code tôi đang phát triển với Claude hoặc bất kỳ hệ thống AI nào khác có thể được xác minh, xác nhận và lý tưởng là đáp ứng một tiêu chuẩn cao hơn. Một số dự án có thể không cần gì hơn ngoài Trình xác thực Mã và Kiến trúc sư Kiểm thử để xem xét, những dự án khác liên quan đến 40+ tác nhân từ nhiều quan điểm. Nếu có ít nhất một tác nhân nên được thử trên bất kỳ sản phẩm nào — codebase, spec, tài liệu, v.v — đó là Người khai thác Giả định, vì nó gần như áp dụng phổ quát.

Quy trình này bắt nguồn từ sự thiếu tin tưởng và đã phát triển thành một tín hiệu tin tưởng.

Các tác nhân, lệnh và đường ống được tham chiếu trong bài viết này có sẵn tại github.com/aself101/agents-and-pipelines.

Chia sẻ:FacebookX
Nội dung tổng hợp bằng AI, mang tính tham khảo. Xem bài gốc ↗