Bàn về multi-agent orchestration và mô hình SLP

— 27/09/2026 · 10 Min read

SLP là Supervisor - Lead - Peer. Trước đây tôi không đặt tên nhưng để dễ nói chuyện tôi đành gọi là SLP. Đây là một phương pháp phối hợp có chủ kiến cá nhân (opinionated) được hình thành quanh loại dự án, workflow và thói quen làm việc của tôi.

Bàn về multi-agent orchestration và mô hình SLP

Chiếc kim trong bọc lâu ngày cũng lòi ra, nên tôi đành phải viết bài này. Để hiểu bài này bạn cần thông minh hơn học sinh lớp 5.

Trải nghiệm khiến tôi bắt đầu nghi ngờ cách Codex điều phối sub-agent đến từ thời multi-agent v1, khi dùng nó trên những dự án đòi hỏi tối ưu phần cứng cực đoan và các subsystem chồng chéo phức tạp như:

  • Nova - 1 MMORPG Networking Framework (Rust, C++ Unreal SDK)

  • Quark - 1 low-level netcode runtime cho multiplayer game, hình dung nó như Iris của Unreal hay NfE của Unity.

  • Và hệ thống CRM với business đồ sộ của các chuỗi phòng khám, bệnh viện tại HCMC mà tôi cộng tác.

Đây là những codebase lớn, nơi một feature có thể chạm đồng thời vào nhiều module, kéo theo những vấn đề về ownership, lifecycle và các quyết định kiến trúc đã tồn tại từ trước.

Ownership: GPT và cả CLAUDE thích dùng từ này và tôi thấy ổn, thay vì phải dùng 1 đoạn dài để mô tả về quyền làm chủ và trách nhiệm.

  • Agent ownership: "Mỗi phạm vi có một agent chịu trách nhiệm chính và nắm quyền chỉnh sửa."

  • State ownership: "State này do thành phần nào quản lý?"

Tôi nói rõ bối cảnh này vì nếu bài toán chỉ là một web service với vài trăm API CRUD, lifecycle đã rõ, các phần việc tương đối độc lập và có thể chia ngang để chạy song song, thì trải nghiệm sẽ rất khác. Main chia task, sub implement, gom kết quả lại: cách đó hoàn toàn có thể chạy tốt. Nhiều trường hợp main tự làm tuần tự cũng xong, chưa cần dựng cả một orchestration methodology.

Nhưng những dự án tôi làm thường có vertical dependency: slice sau phụ thuộc không chỉ vào code, mà cả architecture và design mà slice trước vừa tạo ra. Bạn bắt đầu implement feature tiếp theo rồi mới phát hiện API cũ thiếu một khả năng, trách nhiệm đặt sai chỗ, lifecycle không hỗ trợ yêu cầu mới, hoặc một mechanism trong plan phải hoãn lại. Đó là lúc, trong 1 dự án vận hành bởi con người, người thực hiện cần quay lại trao đổi với lead, hoặc cần yêu cầu owner của module khác thay đổi, thậm chí đề nghị làm lại foundation.

Và cũng chính ở đó, cách main agent giao việc cho sub-agent v1 làm tôi khó chịu. Main thường đã tự định nghĩa bài toán, chọn giả thuyết, giới hạn phạm vi, rồi quy định cả format câu trả lời trước khi sub bắt đầu. Phần cần một kỹ sư độc lập suy nghĩ lại bị giải hộ gần hết. Đến lượt sub, nó chỉ còn cố hoàn thành task trong cái khung ấy - kể cả khi cái khung đang bảo nó tiếp tục xây trên một quyết định sai, một foundation vốn chưa thực sự ổn định và sẵn sàng cho feature.

Lấy bài toán multi-cell seamless handoff trong Nova, giản lược một chút cho dễ hình dung. Một world khoảng 5 km mỗi chiều có thành phố, bãi farm và khu PvP. Thành phố đông người nhưng phần lớn chỉ AFK treo shop hoặc chat. Ngoài khu PvP, ít người hơn vẫn có thể tạo ra tải simulation lớn vì combat liên tục. Chia world thành nhiều cell là một cách phân bố những loại tải ấy, với yêu cầu người chơi đi qua ranh giới cell một cách liền mạch, không loading.

Tất nhiên tôi không ngây thơ giao một task siêu lớn như này, set goal rồi ngồi rung đùi chờ kết quả. Tôi phải nghiên cứu những source code gần tương tự, vốn khá hiếm, thảo luận với AI, với expert, đọc paper và blog kỹ thuật từ Tencent, Amazon. Từ kinh nghiệm cá nhân, tôi đã dự tính cần một Edge Layer giữ connection ổn định, tách kết nối của người chơi khỏi cell đang xử lý nhân vật.

Nhưng vẽ được Edge trên sơ đồ chưa giải quyết hết handoff. Khi nhân vật rời cell A, input đang chờ ở đâu? Input nào đã được xử lý, input nào cell B phải tiếp tục nhận? Cell mới bắt đầu có quyền xử lý từ tick nào? Những dữ liệu cell cũ chưa kịp gửi ra phải được tiếp nối ra sao? Một người chơi thứ ba đứng gần ranh giới sẽ thấy cùng một nhân vật di chuyển liên tục, hay thấy nó biến mất rồi xuất hiện lại?

Trong một vòng hoàn thiện handoff của Nova, có một chi tiết rất cụ thể: thứ tự nhận dữ liệu từ cell bên cạnh phải được đưa lên trước bước setup trạng thái bàn giao và chạy simulation ở cell đích. Để bước nhận ấy phía sau simulation sẽ tạo ra thêm một tick trễ ngay trong cấu trúc vòng chạy. Có Edge, có đường truyền, có dữ liệu handoff vẫn chưa đủ nếu dữ liệu đến đúng nơi nhưng được xử lý sai thời điểm.

Đây là loại vấn đề mà một task "implement chuyển nhân vật từ A sang B" rất dễ che khuất. Người implement phải có quyền quay lại bàn về thứ tự chạy, quyền xử lý và trạng thái cần bàn giao. Những phần tưởng đã ổn định ở slice trước có thể phải mở ra sửa. Thêm một hàng đợi hoặc một lớp đồng bộ chưa chắc xử lý được nguyên nhân; đôi khi nó chỉ khiến hệ thống cố bù cho một tick trễ mà chính thiết kế đang tạo ra.

Tôi muốn orchestration hỗ trợ cuộc trao đổi đó. Nếu agent đang đụng code phát hiện tiền đề sai, phát hiện ấy phải có khả năng thay đổi plan.

Phần giải thích cho học sinh lớp 5

Để bỏ bớt thuật ngữ netcode, hãy hình dung cả đội đang làm một chiếc xe đạp.

Tôi giao agent thiết kế một hệ thống giảm tốc hiện đại. Trong trải nghiệm của tôi, những model như GPT-5.6 Sol thường overengineering. Với một yêu cầu như vậy, nó có thể thiết kế hẳn một bộ dù giảm tốc: cơ cấu bung dù, cảm biến vận tốc, bộ điều khiển và cơ chế thu hồi. Nhìn bản thiết kế rất công phu, yêu cầu giảm tốc cũng được đáp ứng.

Rồi tôi nhận xét xe quá nặng. Agent tiếp theo được giao tối ưu trọng lượng của bộ dù. Nó thay vật liệu, làm nhẹ khung bung, tinh chỉnh cơ cấu thu hồi. Khi tôi nói xe vẫn dừng quá chậm, một agent khác tăng diện tích dù rồi tối ưu khí động học. Mỗi agent đều giải quyết khá tốt vấn đề được giao. Chiếc xe ngày càng tinh xảo, còn cái dù thì ngày càng khó bỏ.

Câu hỏi tôi cần nghe lại không xuất hiện:

"Vì sao chúng ta chọn dù để giảm tốc cho xe đạp? Yêu cầu nào khiến một bộ phanh thông thường không đáp ứng được?"

Đó là cách một lựa chọn thiết kế của agent đầu tiên âm thầm trở thành constraint cho những agent đến sau. Mong muốn của tôi là xe nhẹ hơn và dừng tốt hơn. Nhưng qua bước phân rã task, nó bị chuyển thành yêu cầu làm nhẹ cái dù và tăng hiệu quả của cái dù. Mục tiêu của user đã bị thu hẹp thành việc tối ưu phương án mà agent chọn.

Nếu người thực hiện chỉ được sửa bộ dù, chỉ đọc tài liệu về bộ dù và được đánh giá bằng hiệu quả của bộ dù, thêm nhiều agent mạnh có thể chỉ giúp cả đội đi xa hơn trên cùng một quyết định sai. Giải pháp của slice trước đã biến thành yêu cầu của slice sau, dù user chưa từng yêu cầu phải giữ giải pháp đó.

Cái dù ở đây là một tình huống minh họa. Điều tôi muốn mô tả là quá trình một phương án được miễn xét lại qua nhiều lần giao việc. Trong phần mềm, quá trình ấy khó nhận ra hơn vì mỗi lớp bổ sung đều có thể mang một cái tên rất hợp lý.

Main đã giải hộ phần đáng lẽ cần được tranh luận

Trong trải nghiệm sub-agent v1 của Codex, tôi thường gặp kiểu initial prompt như thế này:

"Kiểm tra xem phương án A có đúng không. Tập trung vào khía cạnh X, không bàn lại khía cạnh Y. Trả lời PASS/FAIL và tối đa 5 bullet."

A đã là phương án trung tâm. X đã là tiêu chí chính. Y được miễn xét lại. Câu trả lời phải hội tụ nhanh. Sub có thể rất giỏi tìm lỗi trong A, nhưng không còn nhiều không gian để hỏi liệu A có phải thứ cần xây hay không.

Tôi gọi đó là pre-solve. Main định nghĩa bài toán, dựng giả thuyết, chọn tiêu chí, giới hạn phạm vi rồi gọi thêm một agent đến xử lý phần còn lại. Trong trường hợp cực đoan, sub gần như trở thành một hàm f(x) -> confirm / reject.

Với chiếc xe đạp, brief sẽ là: "Đánh giá vật liệu dù. Không thay đổi cơ chế giảm tốc. Chỉ báo vấn đề ảnh hưởng trọng lượng." Một chuyên gia về phanh nhận task ấy cũng bị kéo thành chuyên gia làm nhẹ cái dù.

Những brief hẹp vẫn hữu ích khi tôi thực sự cần kiểm tra một invariant hoặc implement một contract đã được xác lập. Nhưng discovery cần quyền mở lại giả thuyết. Nếu hai loại công việc này cùng được giao theo một kiểu, sự gọn gàng của task sẽ che mất phần thiết kế chưa được giải quyết.

Giới hạn quyền sửa và giới hạn quyền chất vấn là hai việc khác nhau. Agent chịu trách nhiệm bộ phanh không được tự ý cắt khung xe của người khác. Nó vẫn phải được phép đọc thiết kế khung và báo rằng vị trí bắt phanh hiện tại không chịu được lực cần thiết.

Với vertical plan, điều này càng quan trọng. Phần việc sau phụ thuộc cả vào code lẫn những quyết định thiết kế mà phần trước vừa tạo ra. Một API đủ dùng hôm nay có thể thiếu khả năng cần thiết cho feature tiếp theo. Một cách quản lý state tưởng hợp lý có thể lộ vấn đề khi phải xử lý mất kết nối hoặc nhiều thao tác cùng lúc. Có những vấn đề chỉ lộ ra khi các phần thực sự chạy cùng nhau.

Đến đây, sẽ có người nói: "Vậy là do plan chưa tốt, chưa hoạch định đủ rõ." Tất nhiên, có những lỗi đáng lẽ phải phát hiện từ lúc planning. Nhưng cho rằng một bản plan đủ tốt sẽ khiến quá trình implement luôn trơn tru từ đầu tới cuối là một kỳ vọng ngây thơ, nhất là với những hệ thống phức tạp.

Trước khi bắt tay vào code, nhiều thứ vẫn chỉ là giả định: thư viện có thực sự hỗ trợ thứ mình cần không, hai module ghép lại có chạy đúng không, cách đồng bộ đã chọn có quá chậm không. Đọc source, làm prototype và chạy thử giúp trả lời những câu hỏi đó. Đôi khi câu trả lời buộc ta thay đổi thiết kế. Không thể vừa yêu cầu người implement tìm ra những điều chưa biết, vừa coi mọi phát hiện làm thay đổi plan là lỗi của planning.

Ngay trong Nova, việc tôi đã tính trước cần Edge Layer không có nghĩa bài toán handoff đã được giải xong. Giữ connection ổn định là một chuyện. Cell mới tiếp quản lúc nào, input đang chờ được xử lý ở đâu, người đứng gần có thấy nhân vật khựng lại hay không là những chuyện khác. Vẽ đủ các thành phần trên sơ đồ chưa bảo đảm chúng phối hợp đúng khi chạy.

Nếu bắt main hoạch định hoàn hảo mọi trách nhiệm, quan hệ phụ thuộc, vòng đời dữ liệu và tình huống lỗi ngay từ đầu, ta gần như đang yêu cầu nó implement cả hệ thống trong file plan. Muốn biết bản plan ấy có đúng không, nó vẫn phải viết code, thử thư viện, chạy test và đo đạc. Tức là phải làm trước chính phần việc đang định giao cho các agent khác.

Vì vậy, tôi cần một plan nói rõ mục tiêu, những giới hạn phải giữ, những điều còn chưa chắc và cách kiểm chứng chúng. Khi người làm feature sau phát hiện thiết kế trước đó không đáp ứng được, họ phải có đường quay lại trao đổi, yêu cầu sửa module liên quan hoặc đổi thứ tự triển khai. Việc sửa plan cần có căn cứ, nhưng giữ nguyên plan cũng phải có lý do.

Quay lại chiếc xe đạp: nếu chạy thử mới phát hiện cơ chế giảm tốc không đáp ứng yêu cầu, người làm phải được phép xét lại lựa chọn cái dù. Nếu chỉ được tăng kích thước dù để giữ nguyên plan, từng task vẫn có thể hoàn thành trong khi cả thiết kế tiếp tục đi sai.

Một bản plan tốt vẫn có thể phải sửa nhiều lần. Điều tôi cần ở orchestration là phát hiện từ người đang làm có thể khiến cả đội sửa hướng, thay vì bị ép thành một workaround để bảo vệ plan cũ.

Ở một đội kỹ thuật, người làm feature sau sẽ có lúc yêu cầu lead đổi thứ tự, yêu cầu owner khác thêm API, thay dependency hoặc hoãn một mechanism. Tôi cần agent có cùng con đường trao đổi ấy.

Ở đây, bạn nào tinh ý sẽ thấy một nghịch lý: sub-agent dùng cùng model và effort vốn có năng lực nền ngang main, nhưng orchestration lại ép nó hành xử như một model RLCD chuyên phán định như Jev: nhận đầu vào, đánh giá trong khung tiêu chí có sẵn và trả về một đáp án định trước. Khả năng phân tích sâu và mở lại bài toán vẫn còn đó, chỉ là không được dùng tới. Tôi cần một kỹ sư hỏi tại sao xe đạp phải gắn dù, nhưng lại nhận được một Jev đắt tiền để chấm điểm cái dù.

Khi green test chỉ chứng minh cái dù bung được

Quark cho tôi một ví dụ cụ thể hơn về chuyện test xanh nhưng thiết kế vẫn có vấn đề. Trong vòng review trước một đợt rework, cả 47 test Rust ban đầu đều pass. Nhưng khi bổ sung bốn regression test cho những tình huống bị bỏ sót, cả bốn đều fail trên code cũ. Những lỗi này sau đó đã được sửa. Điều đáng nói là bộ test ban đầu chưa chạm tới những tình huống khiến các giả định trong thiết kế không còn đúng.

Một lỗi nằm trong cơ chế replication. Client đã xác nhận state A, sau đó nhận state B nhưng ACK gửi về server bị mất. World trên server quay lại A, còn các packet gửi để đưa client về A cũng tiếp tục bị mất. Lúc này server và client đang lệch state: server ở A, client vẫn ở B.

Server có giữ history của các packet đã gửi, nhưng history ấy có giới hạn. Khi packet chứa B bị loại khỏi history, server mất dấu việc client có thể đang giữ B. State cuối cùng được xác nhận là A, state hiện tại trên server cũng là A, nên nó có thể tưởng không còn gì cần đồng bộ và ngừng gửi correction. Client cứ thế giữ B.

Nếu task được đóng khung thành "history quá ngắn, cần lưu nhiều packet hơn", một hướng vá dễ nghĩ tới là tăng giới hạn từ 128 lên một con số lớn hơn. Nhưng tăng history chỉ đẩy tình huống lỗi ra xa hơn, đồng thời tốn thêm bộ nhớ. Packet bị xóa khỏi history không có nghĩa state của client đã được xác nhận.

Đây chính là làm cái dù to hơn. Cách sửa trong vòng đó là giữ thông tin về state transition cần được xác nhận cho tới khi có ACK bao phủ nó. History của packet có thể được thu hồi, nhưng server vẫn phải nhớ mình còn cần đồng bộ gì cho client. Hai loại thông tin này liên quan với nhau, nhưng không thể mặc nhiên có cùng vòng đời.

Một lỗi khác cũng xuất phát từ việc gộp những trách nhiệm tưởng gần nhau. Client đã nhận lệnh spawn một entity. Sau đó entity ra khỏi vùng quan tâm của client, nên server cần gửi despawn để client xóa nó. Nhưng thao tác reset baseline lại xóa luôn thông tin cần để biết client có thể vẫn đang giữ entity ấy. Baseline ở đây là state tham chiếu dùng để tính phần dữ liệu thay đổi cần gửi.

Kết quả là cache trên server đã được dọn sạch, còn entity ma vẫn có thể nằm trên client vì không nhận được despawn. Muốn sửa đúng, trạng thái chuyển tiếp của entity phải được giữ độc lập với ACK cache. Việc bỏ dữ liệu phục vụ tính delta không được làm mất trách nhiệm thông báo rằng entity đã rời khỏi thế giới mà client cần nhìn thấy.

Hai lỗi này cho thấy vì sao người implement cần được phép quay lại chất vấn thiết kế. Task ban đầu có thể chỉ là mở rộng replication hoặc giảm bộ nhớ. Nhưng khi đọc code và viết test, họ phát hiện cách quản lý state hiện tại đang gộp những thứ có vòng đời khác nhau. Phát hiện ấy có thể buộc cả đội sửa phần nền trước khi tiếp tục feature.

Nếu main đã chốt sẵn nguyên nhân trong brief, chẳng hạn "tăng history để xử lý mất gói", agent nhận việc rất dễ tối ưu theo hướng đó. Nếu nó được giao điều tra vì sao client không về đúng state, đồng thời được phép mở lại các giả định liên quan, cơ hội tìm ra vấn đề gốc sẽ khác. Những bug này tự chúng chưa chứng minh orchestration gây ra lỗi; chúng cho thấy loại phát hiện mà orchestration phải có khả năng tiếp nhận và biến thành thay đổi thiết kế.

Quark còn có một vấn đề ở cấp độ ghép các module. Clock, input, prediction và replication từng tồn tại tương đối tách biệt, trong khi game mẫu giữ thêm một phần logic riêng. Có đủ các thành phần ấy chưa có nghĩa chúng đã tạo thành một runtime hoạt động thống nhất.

Input này thuộc tick nào? Prediction đang chạy trước server bao xa? Snapshot vừa nhận mô tả state ở thời điểm nào, và client phải dùng nó để sửa phần dự đoán nào? Những câu hỏi đó đi xuyên qua nhiều module. Mỗi phần có thể pass test riêng nhưng vẫn phối hợp sai nếu chúng không thống nhất cách hiểu thời gian và state. Thêm feature vào từng module cũng không tự giải quyết được sự lệch nhau ấy.

Quay lại chiếc xe đạp, ta có thể kiểm tra dây kéo không đứt, dù bung đúng lệnh và cảm biến báo đúng tốc độ. Từng bộ phận đều làm đúng việc được giao. Nhưng người đi xe cần cả hệ thống giúp họ dừng lại trong điều kiện sử dụng thực tế. Nếu cảm biến báo đúng mà cơ cấu bung phản ứng quá muộn, hoặc cái dù vốn không phù hợp với tốc độ đang chạy, kết quả kiểm tra từng bộ phận riêng lẻ vẫn chưa trả lời được yêu cầu đó.

Điều tôi cần ở agent là có người nhìn xuyên qua ranh giới task để chỉ ra vấn đề ấy, rồi có đường trao đổi với những owner liên quan để sửa. Nếu chỉ được chứng minh phần mình phụ trách đã pass, cả đội có thể kiểm tra cái dù rất kỹ, tối ưu nó qua nhiều vòng, mà vẫn bỏ sót câu hỏi chiếc xe có thực sự dừng được hay không.

Model càng mạnh, đường vòng càng đáng lo

Với những model mạnh như Sol 5.6 và hiện tại là Astra hay Opus 5.5, điều khiến tôi lo lại là chúng quá giỏi tìm đường vòng. Viết hàng nghìn, thậm chí hàng chục nghìn dòng code để ép mọi thứ chạy đúng expectation có thể nằm trong khả năng của chúng. Nếu task chỉ yêu cầu giữ nguyên các quyết định cũ và hoàn thành feature mới, năng lực ấy có thể được dùng để bảo vệ chính những quyết định cần thay đổi.

Reconnect ngầm chưa đủ thì thêm bảng ánh xạ ID, thêm state trung gian, thêm một lớp đồng bộ để giữ các lớp trước không lệch nhau. Đây là những kiểu đường vòng tôi lo ngại khi giao bài toán seamless handoff trong một scope quá chặt. Từng cơ chế đều có ứng dụng hợp lý; điều đáng ngờ là phải liên tục bổ sung chúng để bù cho cùng một mâu thuẫn nền tảng mà không ai được mở lại.

Tôi hay nói vui rằng đưa cho nó hai cái bánh xe rồi bảo muốn tới đảo Guam, nó sẽ ráp một chiếc thủy xe đạp trông luxury as fuck và đạp thẳng tới đó. Trong khi điều tôi cần ở một kỹ sư độc lập là nó hỏi lại: "Tại sao phải dùng hai cái bánh này? Mình đang cần một con thuyền mà?"

Quyền phản kháng có giá trị ở thời điểm ấy. Agent phải được chỉ ra rằng phương tiện đang không phù hợp với mục tiêu, trình bày bằng chứng, đề nghị đổi thiết kế hoặc mở lại scope. Nếu chỉ được tối ưu để hoàn thành task, model càng mạnh đôi khi càng khiến một quyết định sai sống lâu hơn.

Tất nhiên câu "cần redesign" cũng phải chịu chất vấn. Agent có thể overengineering ngay trong phương án thay cái dù. Main phải hỏi lỗi xảy ra ở điều kiện nào, sửa nhỏ có đủ không, phương án mới bỏ được trách nhiệm nào và tạo thêm trách nhiệm nào. Phản kháng có ích khi nó giúp đội ra quyết định tốt hơn.

V2 đã cải thiện, quyền kiểm soát của user vẫn là điều tôi concern

Những phê bình đầu bài đến từ trải nghiệm multi-agent v1. Codex hiện đã có những cải thiện trong multi agent v2. Tôi không muốn lấy trải nghiệm đời trước để khẳng định sub-agent hiện nay không thể hỏi ngược hoặc trao đổi với main.

Khả năng gửi message hai chiều đã mở ra đường để sub báo blocker, bổ sung evidence và phản bác brief. Tuy nhiên, việc có đường truyền chưa giải quyết hết chuyện user kiểm soát đội agent như thế nào.

Main vẫn có thể chọn ngữ cảnh truyền xuống, biến yêu cầu "xe nhẹ hơn" thành task "làm nhẹ dù", rồi chỉ báo lại rằng đội đã giảm được bao nhiêu gram. Sub có thể từng hỏi về bộ phanh, nhưng nếu câu hỏi ấy bị bỏ qua khi tổng hợp, user vẫn chỉ thấy một tiến trình tối ưu cái dù rất hiệu quả.

Tôi cần biết agent đang làm theo brief nào, constraint nào thực sự đến từ tôi, quyết định nào do main tự chọn, và bất đồng nào còn chưa được giải quyết. Khi tôi sửa hướng, thay đổi ấy phải tới được người đang thực hiện và cập nhật vào kế hoạch chung.

Đọc được transcript giúp tôi giám sát, nhưng tôi vẫn mất quyền kiểm soát sub agent. Quyền kiểm soát thực tế còn đòi hỏi biết sự can thiệp đó đã làm thay đổi công việc hay chưa, được chủ động steering khi cần. Tôi không muốn trở thành dispatcher duyệt từng method, nhưng cũng không muốn giao việc đồng nghĩa với mất đường tiếp cận sub agent đang implement.

SLP là cách tôi tổ chức công việc quanh những vấn đề đó

SLP là Supervisor - Lead - Peer. Trước đây tôi không đặt tên nhưng để dễ nói chuyện tôi đành gọi là SLP nghe cho nó nguy hiểm và hào nhoáng. Đây là một phương pháp phối hợp có chủ kiến cá nhân (opinionated) được hình thành quanh loại dự án, workflow và thói quen làm việc của tôi. Tôi dùng Paseo làm lớp duy trì room, session và truyền message. SLP là cách tổ chức công việc trên các primitive mà Paseo cung cấp (không dùng các orchestration skill mà Paseo offer).

Tôi vẫn cần một người giữ trạng thái chung và chịu trách nhiệm tích hợp. Đồng thời, người trực tiếp làm việc phải sở hữu cả phán đoán kỹ thuật trong phạm vi của mình. Giao một module nhưng giữ toàn bộ quyền suy nghĩ ở main thì khó kỳ vọng xuất hiện góc nhìn độc lập.

Vai trò

Trách nhiệm tôi cần

Human

Giữ mục tiêu, ưu tiên và những đánh đổi thuộc quyền quyết định của mình; có đường tiếp cận và sửa hướng công việc.

Supervisor

Trao đổi với human về kiến trúc và hướng đi; theo dõi những vấn đề xuyên phạm vi, phát hiện lệch hướng và can thiệp trong quyền được giao.

Lead

Giữ trạng thái chung của room, phân chia ownership, xử lý dependency, đánh giá evidence và chịu trách nhiệm integration, acceptance.

Peer

Chịu trách nhiệm chuyên môn cho công việc được giao; điều tra, thiết kế, implement hoặc review; được chất vấn tiền đề và đề nghị thay đổi phạm vi.

Với chiếc xe đạp, Peer phụ trách việc giảm tốc có thể báo rằng cái dù là lựa chọn không phù hợp. Lead phải xét bằng chứng và phối hợp với owner của khung xe nếu cần gắn bộ phanh. Nếu thay đổi tác động tới mục tiêu hoặc chi phí mà tôi chưa chấp thuận, Supervisor đưa quyết định đó về trao đổi với tôi.

Supervisor có thể nói trực tiếp với Peer khi cần. Tôi cũng muốn có khả năng tiếp cận agent đang thực hiện. Nhưng những can thiệp làm đổi hướng phải quay về trạng thái chung mà Lead quản lý. Nếu một người được bảo giữ dù, người khác được bảo tháo dù, còn Lead không biết gì, chúng ta chỉ vừa tạo thêm một nguồn conflict.

Một invariant vận hành tôi cần là một phạm vi đang thay đổi có một owner cho tới khi bàn giao rõ ràng. Lead không vừa giao Peer sửa phanh vừa tự chỉnh cùng bộ phanh để "hỗ trợ". Reviewer phải biết mình đang review phiên bản nào. Peer phát hiện vấn đề ở khung xe có quyền yêu cầu sửa, nhưng không tự nhiên có quyền ghi đè công việc của owner khung.

Độc lập trong phán đoán cần đi cùng trách nhiệm phối hợp. Nếu mọi agent đều tự mở scope và tự sửa mọi thứ, chiếc xe sẽ có rất nhiều người cầm cờ lê chọc ngoáy và không ai biết hình dạng cuối cùng của nó.

Một điểm tôi muốn nói rõ: SLP không phải role-play cho agent.

Supervisor, Lead và Peer không phải ba personality prompt kiểu "bạn là một kiến trúc sư khó tính", "bạn là senior engineer thích phản biện" hay "hãy hành xử như engineering manager". Tôi không quan tâm chúng nói chuyện giống một team người đến mức nào. Role trong SLP mô tả trách nhiệm vận hành và quyền hạn, không mô tả tính cách.

Lead giữ trạng thái chung nào, được quyết định điều gì, khi nào phải escalation. Peer sở hữu phạm vi nào, được sửa gì, được chất vấn những giả định nào và phải trả evidence về đâu. Supervisor quan sát những vấn đề xuyên phạm vi nào, lúc nào nên can thiệp và quyết định nào phải đưa lại cho human. Những thứ đó mới tạo thành role.

Còn Peer thì sao, Lead có thể tạo 1 peer là Implementer, Reviewer, cũng có thể tạo 1 peer là System Architect để hỏi ý kiến về một quyết định design khó khăn, hoặc 1 Auditor để điều tra về chất lượng TDD cũng như các e2e proof

Nếu bỏ tên Supervisor, Lead, Peer và thay bằng DCM mà phạm vi trách nhiệm, luồng thông tin, quyền hạn và escalation path vẫn giữ nguyên, SLP về cơ bản vẫn hoạt động như cũ. Ngược lại, cho ba agent những system prompt mô tả chức danh rất chi tiết nhưng tất cả cùng đọc cùng một context, cùng được sửa mọi file, cùng có quyền đổi plan và không ai chịu trách nhiệm integration thì đó không phải SLP. Đó chỉ là 3 agent đang role-play một engineering team. Nếu có thời gian hoặc bị trigger đủ mạnh nhiều khi tôi sẽ chi tiết hơn về cách tôi setup SLP và cung cấp case study thực tế. Nhưng nói chung là tôi lười nên chắc không có đâu.

Tôi dùng tên các vai trò vì chúng là cách ngắn nhất để diễn đạt cấu trúc trách nhiệm. SLP là mô hình tổ chức công việc và trao đổi, không diễn lại sơ đồ tổ chức của con người.

Một cuộc phản biện phải thực sự đưa ra 1 outcome hữu ích

Với tôi, vòng phối hợp có giá trị phải đi đủ từ phát hiện tới quyết định. Peer chỉ ra thiết kế hiện tại có vấn đề, đưa test tái hiện hoặc evidence cụ thể. Lead xem xét, đối chiếu với mục tiêu và constraint, phối hợp với owner liên quan rồi điều chỉnh công việc nếu cần. Sau khi sửa, evidence mới phải chứng minh vấn đề đã được xử lý trên chính trạng thái code sẽ được chấp nhận.

Đây là chỗ instruction dành cho Lead, Peer và Supervisor cần đủ tinh tế. Tôi cố tình không đưa ra một system prompt thần kỳ nào cho SLP, vì cách viết instruction phụ thuộc rất nhiều vào model, loại công việc và mức độ trưởng thành của codebase. Phần đó, nếu bạn adapt mô hình này, bạn sẽ phải tự thử và tinh chỉnh.

Điều quan trọng là đừng biến quyền phản biện thành nghĩa vụ phải phản biện.

Nếu prompt liên tục nhấn mạnh "hãy tìm lỗ hổng", "hãy thách thức mọi giả định", "đừng tin Lead", agent rất dễ học ra một hành vi khác: muốn chứng minh mình đang làm tốt vai trò thì phải tìm ra thứ để phản đối. Với những model reasoning mạnh, vấn đề này còn rõ hơn. Sol/Astra có thể bẻ gần như bất kỳ luận điểm nào nếu bạn trả đủ token cho nó. Một thiết kế đang ổn vẫn luôn có thể được nhìn từ một giả định khác, một failure mode hiếm khi xảy ra, một abstraction "sạch" hơn hoặc một kiến trúc tổng quát nhiều abstraction trông có vẻ elegant hơn (mà tôi không cần).

Lúc ấy chúng ta không còn trả token để tìm lỗi đáng sửa nữa. Chúng ta đang trả token để thưởng cho sự tranh biện.

Peer vì thế không cần chứng minh Lead sai. Nó cần có quyền nói Lead sai khi evidence buộc phải nói như vậy. Lead cũng không cần bảo vệ plan. Nó cần phân biệt được đâu là phát hiện làm thay đổi quyết định, đâu chỉ là một phương án khác cũng hợp lý, và đâu là một cuộc tranh luận không đủ giá trị để làm gián đoạn công việc.

Brief cũng nên phân biệt rõ ba thứ: mục tiêu, constraint thực sự bắt buộc và lựa chọn thiết kế hiện đang được dùng. "Xe phải dừng được trong điều kiện X" là requirement. "Xe phải dùng dù để dừng" chỉ là requirement nếu chúng ta thực sự đang làm một thí nghiệm về dù. Nếu cái dù đơn giản là phương án agent trước nghĩ ra, Peer sau phải biết rằng nó được phép đặt câu hỏi về cái dù.

Trong các vòng benchmark Quark của tôi với Iris của Unreal, NfE của Unity để tự sướng, các lượt đo trước và sau phải được chạy trong điều kiện có thể so sánh. Hai agent cùng chiếm CPU, một agent compile project khác trong lúc agent của Quark thực hiện benchmark, hoặc workload bị sửa giữa hai lượt đo đều có thể khiến con số vẫn hoàn toàn "thật" nhưng kết luận từ chúng không còn đáng tin.

Quay lại chiếc xe đạp: một người đang đo sức đạp, người khác chạy phía sau đẩy xe, rồi cả đội công bố hiệu suất truyền động đã tăng. Đồng hồ không nói dối nhưng điều kiện thí nghiệm đã thay đổi và kết quả không hề đáng tin.

Trao đổi cross workspace nơi mà 1 supervisor có được góc nhìn xuyên suốt các project vì vậy có thể được dùng cho những việc rất thực dụng: ai đang giữ máy để benchmark, tiến trình nặng nào phải dừng, khi nào người khác được chạy lại. Nhưng một message "tôi sẽ nhường CPU" cũng chưa phải evidence rằng CPU thực sự đã rảnh. Cuối cùng vẫn phải kiểm tra trạng thái thật.

Tôi thường ví chính SLP với một chiếc xe đạp. Nếu muốn adapt mô hình này, hãy bắt đầu đơn giản, dùng nó trong công việc thật rồi tinh chỉnh dần. Thấy agent chỉ biết làm theo thì mở thêm không gian chất vấn. Thấy chúng tranh luận mọi thứ thì chỉnh lại instruction để phản biện phải gắn với một vấn đề cụ thể và một quyết định đáng xem xét. Không có lý do gì phải dựng sẵn cả một bộ máy điều phối chỉ vì trên giấy nó trông đầy đủ.

Từ một đội agent phục tùng mọi brief, chúng ta rất dễ đi sang thái cực còn lại: agent nào cũng muốn chứng minh mình có tư duy độc lập, còn cả đội chìm trong những cuộc phản biện chồng chéo. SLP cũng cần được điều chỉnh để tránh chuyện đó. Tôi muốn chiếc xe chạy được, và người đang sửa nó biết lúc nào cần lên tiếng.

Mục tiêu của orchestration không phải tạo ra càng nhiều phản biện càng tốt. Mục tiêu là để đúng phản biện có thể đi tới đúng người và thực sự thay đổi công việc khi nó đáng để thay đổi.

Better SLP

Tôi đánh giá orchestration bằng chuỗi thay đổi: Lead biết gì khi giao việc, Lead có can thiệp đúng lúc không, Peer phát hiện thêm điều gì, evidence ấy có đủ để sửa nhận định không, quyết định mới được truyền tới những owner nào, và kết quả cuối cùng đã thay đổi ra sao, không phải số lần chúng phản biện lẫn nhau hay số lần plan bị thay đổi.

Và nếu đã yêu cầu agent không được bảo vệ một thiết kế chỉ vì nó đang tồn tại hoặc 1 doctrine sẵn có, thì bản thân orchestration methodology cũng không nên được miễn nguyên tắc đó.

SLP không phải một bộ luật tôi viết xong rồi bắt mọi project tuân theo. Nó cũng là một thiết kế đang được kiểm chứng bằng công việc thực tế. Có những lúc tôi nhận ra Lead đang ôm quá nhiều trách nhiệm, Supervisor can thiệp quá muộn, Peer báo vấn đề đúng nhưng message không đủ context để người khác hành động, hoặc một bước review tạo nhiều ceremony hơn giá trị mà nó mang lại. Những vấn đề đó không nên được giải bằng cách thêm tiếp một role, một checklist hay một vòng approval chỉ để giữ nguyên SLP.

Tôi có Better-SLP cũng từ lý do đó: một framework để quan sát chính SLP, sửa và đơn giản hóa dần từ những failure mode tôi gặp khi sử dụng nó.

Điểm quan trọng ở đây không phải Better-SLP là "SLP phiên bản tốt hơn" theo nghĩa mỗi vài tuần lại thêm feature. Nhiều cải tiến tốt nhất của orchestration có thể là bỏ bớt một cơ chế, giảm một vòng message, chuyển một trách nhiệm về đúng owner hoặc nhận ra rằng một loại task vốn không cần Supervisor tham gia.

Nếu Peer liên tục phải escalation cùng một loại vấn đề, có thể lỗi nằm ở instruction của Lead. Nếu Lead luôn phải đọc lại toàn bộ transcript mới hiểu Peer đang nói gì, có thể protocol báo cáo đang thiếu context. Nếu Supervisor cứ phải cứu những quyết định lẽ ra Lead tự xử lý được, boundary giữa hai role đang sai. Nếu một reviewer peer hiếm khi thay đổi kết quả nhưng luôn tiêu tốn thêm một lượng lớn token, reviewer đó cũng phải chứng minh vì sao nó còn tồn tại, không chứng minh được thì bỏ.

Nói cách khác, tôi muốn SLP có khả năng self-improve từ chính telemetry của quá trình làm việc: conflict nào lặp lại, escalation nào thực sự dẫn tới thay đổi, review nào bắt được lỗi có giá trị, intervention nào đến quá muộn, và ceremony nào chỉ tạo thêm traffic rác ngốn token.

Nhưng self-improve ở đây cũng cần cẩn thận. Một orchestration nhìn thấy ba lần Peer bắt lỗi thành công rồi kết luận "hãy tăng phản biện lên gấp đôi" rất dễ tối ưu nhầm metric. Tương tự như benchmark, thứ cần quan tâm không phải activity tăng bao nhiêu mà outcome thay đổi thế nào. Chiếc xe đạp lại là ví dụ dễ hiểu nhất. Nếu sau vài chuyến đi chúng ta thấy tay phanh quá xa, ta chỉnh vị trí tay phanh. Nếu xích hay tuột, ta sửa truyền động. Nhưng đừng vì thấy ba lần sửa xe hữu ích rồi kết luận rằng từ giờ cứ mỗi kilomet phải dừng lại tháo xe ra kiểm tra toàn bộ. Chỉ có ai ngoo hơn học sinh lớp 5 mới làm thế.

Một methodology tốt phải học được cả khi nào nên thêm cơ chế và khi nào nên thôi can thiệp. Với tôi, đó mới là trạng thái trưởng thành hơn của orchestration: không chỉ cho phép plan thay đổi khi evidence mới xuất hiện, mà chính cách chúng ta lập plan, chia ownership, review và escalation cũng được phép thay đổi theo evidence.

Những hướng tiếp cận đang gặp nhau

Điều thú vị là nhiều hướng tiếp cận đang cùng chú ý tới cấu trúc phối hợp. Andrew Ng đã bàn về multi-agent collaboration từ năm 2024: các agent có vai trò, workflow, bộ nhớ riêng và có thể nhờ nhau hỗ trợ. Ông cũng lưu ý chất lượng đầu ra khó dự đoán khi agent tương tác tự do và dùng nhiều tool. Bài viết của Andrew Ng trên The Batch đặt ra một nền tảng hữu ích để bàn tiếp về cách điều phối.

Gần hơn, preprint tháng 8/2026 Graph Engineering in the Era of LLM Agents: From Individual Intelligence to System Intelligence của Yuyuan Feng và các đồng tác giả xem task, agent và trạng thái hệ thống qua những cấu trúc đồ thị có thể biến đổi. Trọng tâm mở rộng từ năng lực của một agent sang cách tổ chức cả hệ thống. Đây là một bài tổng quan riêng, không phải paper của Andrew Ng.

Tôi thấy sự tương đồng với SLP ở nhu cầu biểu diễn rõ quan hệ phụ thuộc, đường trao đổi và cách cấu trúc phối hợp thay đổi khi có bằng chứng mới. Đó là phần tôi đối chiếu giữa hai hướng tiếp cận; bài tổng quan này không phải một kiểm chứng cho SLP.

Một sơ đồ cây cho biết ai spawn ai. Trong công việc của tôi, còn phải biết ai sở hữu module, ai cần dữ liệu của ai, ai có quyền sửa quyết định và ai phải được thông báo. Các quan hệ đó không nhất thiết trùng với quan hệ cha-con giữa session. Chúng cũng thay đổi khi feature sau làm lộ một dependency chưa biết.

Ở phía công cụ, agent teams của Claude Code cho phép các session phối hợp, teammate trao đổi trực tiếp và user tương tác với từng teammate; tính năng này hiện được mô tả là experimental. Claude Code còn có cross-session messaging. Trong môi trường Codex tôi đang dùng, các tool trao đổi giữa agent và giữa những chat riêng cũng đã tạo thêm đường phối hợp. Những khả năng đó làm các workflow như báo blocker hoặc nhường tài nguyên để benchmark khả thi hơn.

Nhưng có thêm cạnh trên đồ thị chưa bảo đảm quyết định tốt hơn. Nếu mọi message vẫn xoay quanh làm cái dù nhẹ hơn, một đội giao tiếp rất sôi nổi vẫn có thể bỏ qua bộ phanh. Điều tôi quan tâm là bằng chứng có được đi tới đúng người, và người đó có quyền thay đổi quyết định hay không, và hơn hết tôi vẫn dùng Paseo-SLP là vì có thể phối hợp điểm mạnh của mỗi model.

SLP phù hợp với bài toán của tôi, có thể không hợp với bạn

Tôi chia sẻ SLP vì những người đang gặp vấn đề tương tự có thể lấy các pain point này để đối chiếu, rồi adapt cách phối hợp cho công việc của họ. Nó không phải north star cho mọi team dùng AI.

Với một thay đổi nhỏ, một agent làm từ đầu tới cuối có thể tốt hơn cả một room, với những task cần feedback từ tôi - human - một cách liên tục như game feel, combat feel, UI UX tôi thường không dùng SLP.

Cái dù là một trong những anti-pattern tôi muốn viết kỹ hơn trong bài tiếp theo về agent-driven development. Còn nhiều tình huống khác có thể nhìn qua cùng chiếc xe đạp: nhiều người cùng chỉnh một bộ phanh, kiểm tra xe trên giá rồi kết luận chạy ngoài đường ổn, hoặc thêm một cơ cấu mới chỉ để giữ lời hứa của cơ cấu cũ.

Tôi muốn một đội agent đủ năng lực làm ra chiếc xe, đủ độc lập để hỏi vì sao nó cần cái dù, và phối hợp đủ tốt để thực sự thay đổi thiết kế. Tất nhiên tôi không phải các khầy khuếch đại pain point rồi bán solution, nếu bạn không cùng pain point như tôi thì kệ bạn. Hàng tôi thấy ngon, ngu gì tôi bán, tôi viết bài này để collab với chủ hội kín nơi tôi đang cư ngụ, tất nhiên vì nó kín nên tôi thích, mong các bạn đừng vào. Bài viết có nhiều thuật ngữ ai không hiểu thì copy cho chatgpt, tôi thích viết thuật ngữ để học sinh dưới lớp 5 không hiểu và cũng là để cho sang cái mồm.

Bài tự viết, thằng nào bảo chatgpt xin nhẹ cái kèo nghị luận xã hội tại HCMC. Tất nhiên hình minh họa thì chatgpt rồi =))

Comments

Leave a comment