Một task đi qua PM, SWE, QA ra sao, và cách chạy nhiều task song song mà không phải ngồi canh.
Bài 2 trong 3. Series: dựng một team agent AI để làm phần mềm.
Ở bài 1 tôi kể vì sao tôi coi session chính là orchestrator, và chia việc cho bốn vai: PM, SWE, QA, On-Call. Vai trò mới là khung xương. Bài này nói về phần làm cho khung đó sống: một task chạy qua team thế nào, làm sao chạy nhiều task cùng lúc mà không phải ngồi canh, và ghi trạng thái ở đâu.
Mọi task đi qua cùng một dãy bước. Tôi không cho ngoại lệ, kể cả với việc nhỏ, vì ngoại lệ là chỗ quy trình bắt đầu rạn.
Tôi nói với orchestrator để tạo task và đẩy vào backlog. PM nhặt lên, gọt thành spec rõ ràng. SWE code và viết test. QA chạy test, soi từng tiêu chí, rồi phán đậu hay rớt. Nếu rớt, task quay về SWE sửa. Nếu đậu, PM bước vào lần cuối để nghiệm thu. Chỉ sau khi PM gật, orchestrator mới commit code và đóng task.
Vòng lặp gọn lại trong đầu thế này: PM, SWE, QA, rồi về PM trước khi commit.
Cái loop "QA rớt thì quay lại SWE" nghe hiển nhiên, nhưng nó là chỗ tôi thấy giá trị thật của việc tách vai. Vì QA là một vai riêng, nó không ngại trả task về. Một agent ôm hết sẽ có xu hướng tự tặc lưỡi cho qua, vì rớt nghĩa là tự nhận mình làm sai. QA tách rời thì không có cái sĩ diện đó. Nó rớt là rớt, kèm bằng chứng.
Trong cả dãy bước, bước dễ bị bỏ nhất lại là bước tôi giữ chặt nhất: PM nghiệm thu lần cuối, sau khi QA đã đậu.
Nhiều người sẽ hỏi, QA đậu rồi thì còn duyệt gì nữa?
Vì qua hết test không có nghĩa là giải đúng bài.
Một tính năng có thể "xong" hoàn hảo dưới mắt kỹ thuật mà vẫn hỏng khi vào tay người dùng thật. Test xanh hết, nhưng luồng thao tác vô lý. Hoặc nó làm đúng cái đề bài viết ra, trong khi đề bài lại không khớp với cái người ta thật sự cần. Test chỉ kiểm được "code có làm đúng điều ta bảo nó làm không". Nó không kiểm được "điều ta bảo nó làm có đúng là điều cần làm không".
Bước PM cuối soi đúng khoảng cách đó. PM quay lại user story ban đầu và hỏi: kết quả này có thật sự phục vụ cái người dùng cần không? Đây là lớp bảo vệ cuối, và nó bắt được đúng loại lỗi mà không cái test nào bắt được.
Để cả team đi đúng dãy bước này một cách nhất quán, tôi không lặp lại nó mỗi phiên làm việc. Tôi viết nó ra file, ngay trong repo. Agent đọc và bám theo:
PROCESS.md mô tả luồng phát triển từ đầu tới cuối.CLAUDE.md chứa chỉ dẫn cấp dự án.Viết quy trình ra file là điểm khiến cả cách làm này lặp lại được, đúng kiểu tôi thích. Lần sau mở dự án mới, tôi bê nguyên bộ này sang. Agent biết luôn nó là vai gì, đi qua bước nào, và "xong" nghĩa là gì. Tôi không phải dạy lại từ đầu.
Có một điểm tinh tế ở đây mà tôi sẽ quay lại ở bài 3: khi quy trình chỉ nằm trong file chữ, agent vẫn có thể lờ đi vài chỗ. File là chỉ dẫn, không phải hàng rào cứng. Nhưng ngay cả ở dạng file, viết ra vẫn tốt hơn nhiều so với nhắc miệng từng lần.
Một task một lần thì phí thời gian. Tôi thường chạy hai task song song. Khi xong một đợt hai task, orchestrator kéo tiếp hai task nữa từ backlog. Cứ thế cuốn chiếu.
Nghe đơn giản, nhưng có một chỗ kẹt mà ai chạy agent kiểu này cũng gặp: vòng lặp tự chết.
Xong một đợt, orchestrator dừng lại, hỏi "tiếp đi chứ?" rồi ngồi chờ tôi gõ. Nửa đêm tôi ngủ thì nó đứng yên tới sáng. Cả đêm trôi qua mà backlog vẫn còn nguyên một nửa. Đây là một trong những thứ làm tôi bực nhất khi mới làm.
Cách tôi vá nó nhỏ mà hiệu quả: cài một chỉ dẫn lặp ngay trong task list.
Chỉ dẫn đó nói orchestrator làm hai việc. Một, kéo đợt task tiếp theo. Hai, tự thêm lại đúng chỉ dẫn này vào cuối danh sách. Thế là sau mỗi đợt, nó tự nhắc mình kéo đợt sau, rồi lại tự nhắc tiếp. Vòng lặp chạy tới khi backlog cạn, thay vì khựng lại sau mỗi đợt chờ tôi đẩy.
Cái mẹo này biến cả đêm thành thời gian làm việc thật. Tôi đi ngủ với backlog đầy, sáng dậy phần lớn đã được gọt, code, test, nghiệm thu xong.
Nhưng tôi muốn nói thẳng một điều kiện đi kèm, vì nó dễ bị bỏ qua trong cơn phấn khích "để agent chạy qua đêm". Vòng lặp tự chạy chỉ an toàn khi quy trình ở trên đã chặt. Nếu bạn cho agent tự cuốn chiếu mà không có ai gác từng bước, nó sẽ cuốn luôn cả lỗi đi thật xa, và sáng ra bạn dọn còn mệt hơn. Tự động và kiểm chứng phải đi cùng nhau. Tự động mà thiếu kiểm chứng chỉ là tạo rác nhanh hơn.
Vòng lặp tự chạy chỉ có ích khi tôi nhìn được nó đang làm gì. Tôi dùng một trong hai cách ghi trạng thái.
Cách thứ nhất là GitHub Issues. Hợp khi tôi muốn phối hợp công khai và muốn báo cáo của từng agent dính kèm vào từng task. Mỗi issue thành một hồ sơ đầy đủ: PM ghi yêu cầu, tiêu chí nghiệm thu, kịch bản test; SWE báo đã code xong; QA xác nhận kèm ảnh chụp kết quả. Mở một issue ra là đọc được cả lịch sử việc đó đi qua những tay nào, ai làm gì, vì sao đậu hay rớt.
Cách thứ hai là tracker bằng file. Nhẹ hơn nhiều. Trạng thái nằm luôn trong tên file.
Một task đi từ .todo.md sang .groomed.md sang .in-progress.md, rồi cuối cùng vào thư mục done/. Không cần dịch vụ ngoài, không cần mạng, chỉ là file trong repo. Nhìn tên file là biết task đang ở đâu trong vòng lặp.
Tôi chọn cách nào tùy mức công khai tôi cần. Dự án nhiều người nhìn vào thì GitHub Issues. Dự án tôi làm một mình, hoặc chưa chắc sống lâu, thì file cho nhanh gọn.
Nhưng đây là điểm quan trọng hơn cả hai lựa chọn: cái tracker chỉ là chỗ ghi trạng thái.
Cùng một vòng lặp PM, SWE, QA, về PM chạy y hệt dù tôi ghi trạng thái ở đâu. Công cụ theo dõi là cái sổ, còn cái tạo ra chất lượng là quy trình quanh nó, là việc tách vai và bắt mọi task đi đủ bước. Đổi tracker không đổi kết quả. Bỏ quy trình thì tracker xịn tới đâu cũng vô dụng.
Tới đây tôi đã kể xong cách làm: vai trò ở bài 1, quy trình ở bài 2. Bài 3 tôi đem nó ra thực chiến, qua các loại dự án khác nhau, kể cả một dự án tôi làm hỏng, rồi rút ra cái gì còn lại sau tất cả.
1 đến 2 email mỗi tháng. Hủy đăng ký dễ.
1 đến 2 email mỗi tháng. Hủy đăng ký dễ.
Bình luận