Cho agent quyền cãi lại
Tôi chạy coding agent như phần lớn mọi người: một main agent lập kế hoạch, subagent implement, rồi merge kết quả. Suốt mấy tháng, cấu hình này thấy ổn. Rồi dự án khó lên, các slice bắt đầu chồng lên nhau, và tôi bắt đầu thấy một kiểu lặp lại, thấy rồi thì không bỏ qua được nữa. Subagent của tôi giỏi ngang main agent, mà chưa từng có dịp chứng minh. Brief nào tới tay cũng đã giải sẵn. Phát hiện nào đe dọa kế hoạch thì chết lặng lẽ.
Tôi dành cả quý vừa rồi để làm lại cách các agent làm việc với nhau. Ba vai, luật nghiêm về ai được nói với ai, và một nguyên tắc trên hết: phản đối của worker phải tới được tay người làm được gì đó với nó.
Cái brief tự giải quyết vấn đề của chính nó
Lúc đầu chẳng có gì. Bạn bảo main agent kiểm chứng hướng A. Nó viết một brief: kiểm khía cạnh X, đừng mở lại khía cạnh Y, trả lời PASS hay FAIL trong năm gạch đầu dòng. Subagent làm đúng như thế, làm tốt, và không làm gì khác. A có đáng tồn tại không thì không ai hỏi, vì cái brief đã trả lời câu đó trước khi worker tới.
Tôi bắt đầu gọi đó là pre-solving. Coordinator định nghĩa bài toán, chọn giả thuyết, đặt tiêu chí, chốt phạm vi, rồi thuê người làm nốt phần còn lại. Đẩy đủ xa thì subagent biến thành một hàm. Input đi vào, phán quyết đi ra, và chẳng có gì học được trên đường mang ngược trở lên.
Chỗ lãng phí rất cụ thể, đo được. Sub của tôi chạy cùng model, cùng mức effort như các main. Độ sâu phân tích thì có. Chỉ là orchestration không bao giờ gọi tới nó. Tôi đang trả giá của senior engineer cho một việc phân loại theo kịch bản.
Những dự án mà điều này thực sự đau
Việc nhỏ chạy song song thì không cần mấy thứ này. Vài trăm endpoint CRUD với vòng đời rõ ràng thì tách ngang ngon lành. Main chia, sub implement, merge, xong. Có job một agent làm thẳng một mạch còn nhanh hơn bất kỳ hội đồng nào tôi dựng được.
Các dự án khó của tôi trông khác hẳn. Tính năng chồng theo chiều dọc: mỗi slice phụ thuộc vào architecture mà slice trước đó phát minh ra sáng hôm ấy. Bạn bắt tay vào tính năng kế tiếp thì API cũ thiếu mất một năng lực. Một trách nhiệm nằm nhầm module. Một cơ chế trong kế hoạch phải chờ thêm một chu kỳ. Trên team người, người làm việc đi bộ về chỗ lead và nói ra. Có khi họ xin chủ module khác đổi một thứ. Có khi nền móng cần làm lại.
Cấu hình cũ của tôi không có con đường nào cho cuộc trò chuyện đó. Phát hiện hoặc chết, hoặc bị nhồi vào những workaround để bảo vệ kế hoạch. Test rồi chứng nhận cho các workaround ấy. Rồi mọi người đi tiếp. Model mạnh hơn còn làm mọi thứ tệ hơn: một agent giỏi mà chỉ được phép hoàn thành task sẽ bảo vệ một quyết định tồi lâu hơn và trôi chảy hơn một agent yếu. Cách sửa chưa bao giờ là dùng agent yếu hơn. Mà là được phép phản đối, cộng thêm một con đường để phản đối hạ cánh ở đâu đó có quyền đổi.
Mặt trái của nó tôi cũng học được, mà học đau. Hồi đầu tôi sửa quá đà, thế là mọi agent bắt đầu diễn màn độc lập. Các cuộc tranh luận chồng chéo nhấn chìm hai sprint trước khi tôi dẹp cái luật đó đi. Mục tiêu chưa bao giờ là tranh cãi nhiều hơn. Mà là phản đối đúng tới đúng người, và làm thay đổi công việc khi cần thay đổi. Mọi thứ khác là nhiễu, và giờ tôi coi khối lượng tranh luận là một chỉ số chi phí, không phải chỉ số sức khỏe.
Ba công việc, không phải ba nhân cách
Cấu hình của tôi có ba vai. Supervisor giữ shared state, theo dõi mọi workspace, nhớ những thất bại trước đó, và nói chuyện với tôi. Lead sở hữu một dự án: lập kế hoạch, phối hợp, tích hợp, nghiệm thu. Peer làm phần việc có phạm vi, và trong phạm vi đó thì được chất vấn tiền đề.
Cái tên ít quan trọng hơn sơ đồ. Đây là trách nhiệm và ai làm được gì, không phải nhân vật. Không có persona kiến trúc sư nghiêm khắc, không có giọng senior hoài nghi. Mai tôi đổi tên hết mà giữ nguyên dòng chảy thông tin, các đường leo thang, và ai được đổi cái gì, hệ thống vẫn chạy y hệt. Ba agent với chức danh cầu kỳ chia sẻ một context và quyền ghi ngang nhau thì không phải hệ thống này. Đó là hóa trang.
Human
|
| briefs, steers, accepts
v
Supervisor ---- monitors, patches instructions, spawns fresh leads
| (read-only, on demand, never polls)
| assigns workspace + outcome
v
Lead ---------- plans, coordinates, integrates, accepts
| (never implements, never presolves)
| delegates scoped work
v
Peer(s) ------- implements, reviews, challenges premises
(believes it works for a human)
Để ý thứ còn thiếu: không có mũi tên nào từ Peer quay lại brief ngoại trừ qua Lead, và không có mũi tên nào từ Supervisor vào phần implementation. Mỗi đường trong sơ đồ là một quyền. Bỏ một đường là có thứ cụ thể hỏng. Để Supervisor implement thì Lead thôi sở hữu kết quả. Để peer chia sẻ một context thì các xu hướng sụp thành groupthink. Sơ đồ đủ nhỏ để giữ trong đầu, và đó chính là điểm mấu chốt. Nếu orchestration của bạn cần một trang wiki mới giải thích được, nó đã hỏng rồi.
Peer tin rằng nó làm việc trực tiếp cho một con người. Nó không bao giờ nghe về supervisor, room, hay orchestration. Nó nhận chỉ thị mặc định cộng vài dòng chống những thói quen xấu đã biết, và nó phán đoán trong phạm vi của mình. Một worker biết mình bị dàn dựng sẽ diễn cho người quản lý, thay vì diễn cho công việc. Một profile phủ mọi kiểu peer: giờ này engineer, giờ sau reviewer, architect khi lead cần một câu hỏi thiết kế hóc búa được trả lời. Lead chọn theo từng task. Peer cứ đơn giản.
Supervisor phần lớn thời gian nằm không và chỉ đọc. Nó quan sát, ghi chú, vá chỉ thị khi thấy một anti-pattern lặp lại, và dựng một Lead mới khi Lead hiện tại lún quá sâu vào lối mòn để gượng lại. Tôi gọi nó lên khi cần. Không bao giờ để nó poll: một phiên bản đầu vòng lặp qua các pane worker để kiểm tra hoàn thành và đốt context vô ích. Notification thay polling trong vòng một tuần.
polling (before) notify (after)
--------------- --------------
sup ----ask----> lead sup lead
sup <---busy---- lead sup <---done---- lead (one message)
sup ----ask----> lead sup <---stuck--- lead (only on trouble)
sup <---busy---- lead
...10,000 tokens later...
Cột bên trái scale theo mức sốt ruột. Cột bên phải scale theo event. Với một dự án yên ắng thì khác biệt nhỏ. Với một dự án bận rộn thì đó là khác biệt giữa một supervisor gần như không tốn gì và một supervisor nuốt quota của một junior engineer chỉ để xem có ai cần mình không.
[lead]
presolve = false # never implement while leading
implement = false
delegate_via = "rooms" # no native subagents under this lead
poll_workers = false # wait for completion notices
expect_challenge = true # peers may dispute material premises
verdict = "one binding call per disagreement, then move"
Routing model như xếp đội hình
Mỗi vai nhận model rẻ nhất mà vẫn giữ được constraints của nó. Model nhỏ nhanh đi do thám và xử lý implementation có phạm vi. Model tầm trung dẫn dắt các dự án có phạm vi. Model nặng làm review, thiết kế và phân xử. Đội hình thường trực của tôi: một model hạng trung dẫn dắt, một model max-effort review, một model nhanh rẻ implement. Các lựa chọn xoay theo giá và theo bản release. Nguyên tắc thì không: đừng bao giờ xếp một model coi constraints là gợi ý vào vai buộc phải theo constraints. Tôi học được điều đó khi trả giá đầy đủ, nhìn các model rẻ implement những thứ bị cấm rõ ràng, kể cả đẻ thêm worker trùng lặp khi một cái có vẻ đang kẹt.
Effort theo cùng logic. Các slice thường ngày chạy nhẹ. Khi một task tỏ ra khó, cả nhóm peer cùng bước lên một mức với nhau, thay vì để một agent anh hùng đốt quota một mình. Mấy thứ này là luật tôi tự rút ra từ một quý chạy trên chính dự án của mình, không phải ngưỡng mà cả ngành đã chốt. Handoff sau năm sáu vòng, đội hình ở trên, mặc định không polling: tất cả đều là những thứ chạy được với tôi, và tôi nói chúng đúng ở mức đó.
Handoff trước khi mục nát
Context xuống cấp theo compaction. Sau năm sáu vòng, một lead bảo vệ những quyết định mà nó không còn dựng lại được nữa. Câu trả lời của tôi là handoff: supervisor đánh dấu session đã bão hòa, lead cũ làm nốt phần đang dở dang, viết lại những gì nó học được, và một lead mới tiếp quản với ghi chú đó đính kèm. Tôi còn đặt cho thao tác này một command một từ. Nói nó ra là agent thu xếp, bàn giao, và đứng xuống.
Thứ tôi chưa giải quyết là kinh nghiệm sống ở đâu sau đó. Ai đọc ghi chú handoff, làm sao nó ngắn đủ để có ý nghĩa, khi nào nó hết hiệu lực. Team nào chạy thứ gì đó tương tự cũng đều liệt kê đúng mục còn mở ấy. Tôi thà nhận điều đó còn hơn công bố một định dạng tự tin mà chẳng ai theo. Với lại còn hai đề nghị nữa cho tooling của tôi: event ở tầng control-plane cho phần trăm context và số lần review, để supervisor được page thay vì phải tự kiểm tra; và một hình dạng chuẩn cho chính cái ghi chú kinh nghiệm.
Hóa đơn token uốn nắn thiết kế
Session đơn lẻ đắt nhất của tôi chạy 4 tỷ token qua gần 400 subagent. Một search worker có lần đốt hơn một triệu token trong một lần gọi và trả về chẳng mấy thứ đáng giữ. Một cửa sổ quota năm tiếng cho ra chưa đầy một giờ làm việc thật. Đây là số từ chính session của tôi: đếm từ transcript và hóa đơn, không phải đo đạc có kiểm soát, và "giờ làm việc thật" là tôi tự chấm cái gì đẩy được dự án đi, không phải chỉ số ai khác chạy lại được. Kết luận tôi rút từ chúng cũng xứng với mức đó thôi: một lý do để vừa làm vừa ngó chi phí, không phải một định luật về swarm. Những ultra mode đẻ ra swarm để trông có vẻ bận rộn là thuế đánh vào sự chú ý núp bóng nỗ lực, trong cấu hình của tôi, trên loại workload tôi chạy.
Nên giờ mỗi vòng message, mỗi vòng review, mỗi nghi lễ đều phải kiếm đủ token cho chính nó. Những nâng cấp tốt nhất của tôi quý này đều là phép trừ: bỏ đi một vòng message, trả một trách nhiệm về đúng chủ của nó, giải phóng một loại task khỏi sự giám sát mà nó chưa từng cần. Một phương pháp tự theo dõi chi phí của chính nó sẽ ngày càng đơn giản. Một phương pháp không làm thế sẽ ngày càng rườm rà, rồi gọi đó là sự trưởng thành.
where a 5-hour quota window actually goes (our worst session)
|████████████████████████| agent working ............ ~1.0h
|░░░░░░░░░░░░░░░░░░░░░░░░| polling + status checks .. ~1.5h
|▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒| redundant reviews ........ ~1.0h
|························| stalled / waiting ........ ~1.5h
0h 2.5h 5h
Tôi vẽ cái chart này sau session, không phải trong lúc chạy, và bản thân điều đó đã là bài học. Không ai ngó đồng hồ đo khi swarm trông có vẻ bận rộn. Cách sửa đầu tiên không phải một model tốt hơn hay một prompt khôn hơn. Mà là một luật: supervisor được page theo event thay vì tự kiểm tra, review diễn ra một lần với một phán quyết thay vì lặp tới khi mọi người đồng ý, và worker đang kẹt thì bị giết thay vì bị giám sát. Session kế tiếp, trên công việc tương tự, xong trong vòng hai tiếng. Tương tự chứ không giống hệt: cùng dự án, cùng loại slice, tôi tự so trước-sau, không có lần chạy đối chứng. Tôi ghi nó như một quan sát đủ để tôi giữ cái luật đó, không phải bằng chứng là luật đó đúng ở mọi nơi.
Khi nào không nên dùng
Thay đổi nhỏ thì một agent làm từ đầu tới cuối nhanh hơn. Việc cần phán đoán liên tục của con người về cảm giác, game feel, gu giao diện, nhịp độ combat, không thuộc về một room đầy agent. Có job muốn một cuộc trò chuyện, chứ không phải một hội đồng.
Cấu hình của tôi hợp với việc có phụ thuộc theo chiều dọc, nền móng chia sẻ, và những quyết định sống lâu hơn session. Nó hợp với team sẵn lòng duy trì telemetry để giữ nó trung thực: xung đột nào lặp lại, leo thang nào thay đổi được gì, review nào bắt được lỗi thật, can thiệp nào tới muộn, nghi lễ nào chỉ đốt token.
Cho worker một con đường quay lại kế hoạch. Xem có gì đi trên con đường đó. Rồi đổi những con đường.