Ba lần chạy thật với team agent, kể cả lần làm hỏng, và thứ giữ nó khỏi đi lệch.
Bài 3 trong 3. Series: dựng một team agent AI để làm phần mềm.
Hai bài trước là lý thuyết và quy trình. Bài 1 nói vì sao tôi tách session chính thành orchestrator điều phối bốn vai. Bài 2 nói một task chạy qua team thế nào và làm sao cho vòng lặp không chết giữa đêm. Bài này tôi đem cả bộ đó ra chạy thật, qua mấy loại dự án khác nhau, rồi kể luôn lần tôi làm hỏng.
Tôi cố tình không tô hồng. Cách làm này ăn ở một số loại việc và vấp ở loại khác. Biết nó vấp chỗ nào còn quan trọng hơn biết nó ăn chỗ nào.
Loại việc hợp nhất với cách này là dự án dựng từ con số không.
Khi chưa có code cũ, không có ràng buộc gì phải tôn trọng, agent được tự do nhất. Tôi mô tả thứ mình muốn, orchestrator xé thành một xấp task, đẩy vào backlog, rồi để team cuốn chiếu qua đêm như bài 2 đã kể.
Sáng dậy, phần lớn backlog đã đi hết vòng: PM gọt, SWE code, QA soi, PM nghiệm thu. Tôi không ngồi canh giờ nào. Tôi chỉ mở ra đọc kết quả của từng task, và vì mỗi task có hồ sơ riêng kèm bằng chứng QA, tôi biết ngay cái nào tin được, cái nào cần nhìn kỹ.
Đây là chỗ cái loop tự chạy trả công rõ nhất. Một dự án mới có nhiều task độc lập, ít phụ thuộc chéo, nên hai task chạy song song hiếm khi đạp chân nhau. Backlog càng nhiều việc rời rạc, cách này càng lợi.
Tôi vẫn phải nói thẳng một điều, để khỏi ai đọc xong tưởng đây là máy in code miễn phí. Chất lượng đầu ra vẫn bằng đúng chất lượng cái spec PM viết ra ở đầu. Đề bài lỏng thì cả đêm agent chạy chỉ ra một đống thứ chạy được nhưng lệch ý. Tôi mất kha khá lần để học rằng công sức bỏ vào khâu PM ở đầu được hoàn lại gấp nhiều lần ở khâu QA và nghiệm thu cuối.
Loại thứ hai hợp không kém: mấy việc nhỏ, phạm vi rõ, một mục đích.
Một cái tracker chạy serverless. Một thư viện tiện ích. Một bộ script benchmark đo hiệu năng. Những việc kiểu này có biên giới sắc, dễ mô tả thành tiêu chí nghiệm thu mà QA kiểm được tới nơi tới chốn.
Với loại này tôi thường không cần chạy song song nhiều luồng. Backlog ngắn, tôi cho chạy tuần tự cũng xong nhanh. Cái tôi được nhiều nhất ở đây là sự yên tâm: vì có QA tách rời và bước PM cuối, tôi không phải tự đọc lại từng dòng để tin rằng nó đúng.
Điểm chung của hai loại trên là gì? Cả hai đều cho agent một không gian sạch để làm. Ít di sản, ít ràng buộc ngầm, đề bài gói gọn được.
Giờ tới phần ít người kể.
Tôi đem đúng bộ này vào một việc khác hẳn: viết lại một phần hệ thống đã có, port nó sang một cách dựng khác. Là sửa trên nền cũ, với cả đống hành vi ngầm mà code hiện tại đang gánh.
Tôi làm hỏng. Và tôi làm hỏng đúng ở chỗ tôi tưởng mình đã hiểu rồi.
Tôi nóng vội bỏ qua khâu PM. Tôi nghĩ "việc này tôi nắm rõ rồi, cần gì viết spec dài dòng", nên tôi mô tả qua loa rồi thả cho team chạy. Backlog đầy, loop tự cuốn, hai task song song, y như mấy đêm trước.
Sáng ra tôi nhận một mớ code chạy được, test xanh hết, QA báo đậu. Nhìn mọi chỉ báo đều đẹp. Nhưng nó port sai cái cần port. Nó giữ lại mấy hành vi lẽ ra phải bỏ, và bỏ mất mấy hành vi lẽ ra phải giữ, vì chính tôi chưa bao giờ viết rõ ràng cái nào là cái nào.
Test không cứu được tôi, vì test chỉ kiểm "code có làm đúng điều ta bảo không". Tôi bảo sai từ đầu. QA cũng không cứu được, vì QA soi theo tiêu chí, mà tiêu chí lại sinh ra từ cái spec lỏng của tôi. Cả dây chuyền chạy hoàn hảo trên một đề bài hỏng.
Bài học đắt nhưng gọn: việc càng dính nhiều di sản và ràng buộc ngầm, khâu PM càng không được phép cắt. Đúng cái khâu tôi tưởng thừa lại là khâu giữ cho cả việc khỏi trật bánh. Tôi tự tay bỏ lớp bảo vệ rồi trách cái máy.
Ngẫm lại, lý do khá rõ.
Dự án dựng mới cho agent một tờ giấy trắng. Việc viết lại trên nền cũ thì ngược hẳn: phần khó nhất nằm ở những thứ không viết trong code, mà nằm trong đầu người đã sống với hệ thống đó. Vì sao chỗ này làm thế này. Cái quirk kia tồn tại để chiều một ca lỗi hiếm. Cái ràng buộc nọ là do một hệ thống khác ở xa đang phụ thuộc vào.
Agent không đọc được mấy thứ đó từ code. Tôi mới là người biết. Mà tôi lại lười không truyền nó vào spec. Nên agent đoán, và đoán sai theo cái cách trông rất giống đúng.
Cách team agent này không tự sinh ra hiểu biết về một hệ thống cũ. Nó chỉ khuếch đại cái hiểu biết tôi nạp vào. Nạp đầy đủ thì nó nhân lên. Nạp thiếu thì nó nhân cái thiếu lên, nhanh và gọn gàng tới mức tôi không kịp nghi ngờ.
Gom hết mấy đêm chạy được lẫn lần chạy hỏng, tôi rút lại còn ba thứ. Thiếu một trong ba là agent bắt đầu trôi.
Một, spec viết rõ. Đây là thứ tôi xem nhẹ và phải trả giá. Spec nghe như thủ tục giấy tờ, nhưng nó là nơi tôi rót cái hiểu biết mà agent không có cách nào tự lấy được. Spec lỏng thì mọi khâu sau đều chạy chuẩn trên một nền sai.
Hai, vai được phân. Người viết code không phải người chấm code. Nhờ tách vai mà chữ "xong" có nghĩa, và QA dám trả task về mà không sĩ diện. Bài 1 tôi đã nói kỹ chỗ này.
Ba, quy trình cố định. Mọi task đi đủ dãy bước, không ngoại lệ. Viết quy trình ra file để lần sau bê sang dự án mới mà không phải dạy lại. Bài 2 là chỗ này.
Đủ cả ba, agent đi gần như thẳng, tôi ít phải trông. Thiếu spec, nó đoán mò. Thiếu vai, nó tự chấm điểm mình. Thiếu quy trình, nó nhảy cóc và tuyên bố xong quá sớm. Lần tôi làm hỏng là lần tôi tự rút mất cái thứ nhất.
Nếu bạn hỏi tôi cái gì thật sự đổi sau mấy tuần này, tôi sẽ không chỉ vào con model hay cái prompt nào.
Cái đổi là tôi ngừng coi agent là một cái máy tôi ra lệnh, và bắt đầu coi nó là một team tôi phải tổ chức. Cùng một model, cùng mấy công cụ. Thứ tôi xếp lại là công việc quanh nó: ai làm, ai gác, ai chấm, đi qua bước nào, "xong" nghĩa là gì.
Và cái mẹo tự động chạy qua đêm, dù tôi rất thích, chỉ là lớp trên cùng. Nó chỉ an toàn khi ba thứ ở dưới đã chặt. Tự động hóa mà không có kiểm chứng chỉ giúp bạn tạo ra đống sai nhanh hơn, đúng như đêm tôi port hỏng.
Nếu bạn mang đúng một câu từ cả series này, mang câu này: con agent mạnh tới đâu cũng chỉ đi thẳng được khi bạn dựng đủ khung quanh nó để mỗi việc đều có người kiểm, và mỗi cái "xong" đều có bằng chứng đứng sau.
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