---
title: Native subagent là một cái bẫy
description: "Một tháng brief hỏng, quota cháy, worker không nói lại được. Tôi tắt native subagent và tự dựng lớp orchestration của mình."
date: 2026-08-15
---

Hóa đơn quota tháng Bảy của tôi có một dòng tôi nhìn mãi không hiểu. Một provider, một tuần, tiền gấp chừng ba lần mọi tháng. Không phải do model to hơn, cũng không phải dự án dài hơi. Là cái nút subagent. Tôi bật native subagent khắp nơi, thấy nó nở ra trong log đẹp thật, rồi cuối tháng trả tiền cho phần việc chủ yếu chỉ xác nhận lại điều main agent đã tin sẵn. Cái hóa đơn đó giờ tôi vẫn để mở một tab.

Chuyện sau đó là một tháng tôi đi tìm xem cái gì sai, thử đủ thứ, và cuối cùng dừng ở đâu.

## Cái brief tự trả lời chính nó

Kiểu hỏng này lộ ra trong transcript trước khi lộ ra trên hóa đơn. Main agent quyết đi theo hướng A, rồi đẻ ra một worker với chỉ thị kiểu: kiểm chứng A, tập trung vào 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. Worker làm đúng như thế, và làm tốt. Nó giỏi tìm lỗi bên trong A. Nhưng nó chưa bao giờ hỏi A có đáng tồn tại không, vì cái brief đã trả lời câu đó trước khi nó tới tay.

Tôi bắt đầu gọi đó là pre-solving, và một khi đã có tên, nó xuất hiện khắp nơi. 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. Cái worker đó có khả năng gì thì chẳng ai để ý. Worker của tôi chạy cùng model, cùng mức effort như các main. Độ sâu thì đủ. Chỉ là orchestration không bao giờ gọi tới nó.

Cái bẫy này có điều kiện, và tôi muốn ghi điều kiện đó ra cho rõ. Nó cắn khi coordinator đã quyết xong đáp án rồi mới gọi worker vào xác nhận. Nó không cắn khi việc vốn đã có giới hạn rõ: tách mấy endpoint này, implement đúng spec này, review diff này theo đúng danh sách này. Mấy job đó không cần một cái đầu mở lại được tiền đề, vì tiền đề không phải là rủi ro. Cái biến nó thành bẫy là việc giải sẵn đúng phần mình muốn nhờ giúp.

Nói thẳng ra, thứ tôi xây chỉ là một lời gọi hàm rất đắt. Input đi vào, phán quyết đi ra, kèm latency và một khoản quota.

## Cái gradient chẳng ai thiết kế

Có gì đó chạy ngầm bên dưới. Khi main agent giao việc cho subagent, worker nhận không chỉ là chỉ thị. Nó nhận một địa vị. Trong cuộc trao đổi đó nó là kẻ dưới, và nó cư xử đúng như kẻ dưới: giữ mình trong phạm vi, không chất vấn tiền đề, báo cáo lại bằng mấy gạch đầu dòng nén chặt. Thông tin chảy xuống dốc, càng đi càng mỏng. Quyết định cũng chảy xuống dốc, càng đi càng cứng.

Đặt cạnh đó hai agent đầy đủ nói chuyện với nhau như peer thì khác. Ai cũng mở lại bài toán được. Ai cũng nói được câu nền móng sai rồi. Cuộc trò chuyện vẫn mở, vì không bên nào bước vào với tư thế đã bị xếp dưới sẵn. Hai tuần đó tôi chạy cả hai kiểu trên cùng một loại task, cùng repo, cùng model, và chính tôi là người chấm cái gì tính là một phản đối. Đây là quan sát từ session của tôi, không phải nghiên cứu có kiểm soát: không chấm mù, không tập task cố định, không bảng đếm. Cái tôi thấy, đều đủ để tôi hành động: kiểu peer liên tục đưa ra những phản đối mà kiểu phân cấp chưa từng nói ra. Phản đối không phải lúc nào cũng đúng. Nhưng chỉ cần nói ra được thôi là thứ được xây đã khác rồi.

Một lead tôi làm cùng mô tả kiểu cũ từ phía worker: main agent chỉ vào file, ra lệnh sửa, rồi chờ nó nghe lời. Chăn gia súc, chỉ khác là logging xịn hơn. Tôi cười, rồi chiều hôm đó tắt luôn native subagent.

## Những câu chuyện quota

Hóa đơn của tôi chưa phải tệ nhất. Một người tôi làm cùng kể lại mức đốt bằng hai ngày ngân sách, chỉ trong hai session với bản subagent mới. Một người khác đứng nhìn một search worker nuốt hơn một triệu token trong một lần gọi mà trả về chẳng mấy thứ đáng giữ. Lần nào cũng một kiểu: fan-out trông đẹp trên transcript viewer và thảm họa trên hóa đơn.

Cơ chế đáng nói rõ. Bản subagent mới ra không có chỗ cấu hình model, hành vi mặc định nặng hơn, và không có công tắc tắt cho sạch. Tắt trong config chẳng ăn thua với một số dòng model; cái setting nằm trong model cache, phải vá bằng tay. Một người tôi làm cùng viết hẳn một hook chỉ để chặn lệnh spawn. Một người khác moi được mẹo downgrade từ một issue thread. Tôi tiêu thời gian engineer chỉ để đánh nhau với chính tooling của mình. Tới lúc đó thì tôi thôi hỏi cách cấu hình tính năng, mà bắt đầu hỏi có nên giữ nó không.

```text
native subagent session (one of mine, July)

main .......... plans, presolves, spawns 6 workers
worker x6 ..... confirm fragments of the plan
main .......... merges confirmations, declares done
bill .......... ~3x a single-agent session
finding ....... zero premises challenged, zero
```

Tôi hỏi khắp một vòng: có quyết định nào đổi vì có worker lên tiếng không? Không ai kể ra nổi một cái. Đó là chuyện nghe lại từ một nhóm nhỏ, và nó chỉ đứng được ở mức đó, không phải bằng chứng. Cái tôi nói được từ log của chính mình thì hẹp hơn: cả tháng đó tôi không đếm phản đối đưa ra với phản đối được nghe theo, và bài này là ghi lại những gì tôi nhận thấy, không phải một nghiên cứu về nó.

## Thứ tôi thử thay thế

Đầu tiên tôi thử tách hẳn session ra, chạy qua một terminal multiplexer: agent đầy đủ, không có parent, phối hợp bằng một protocol đọc được. Tốt hơn thấy rõ. Worker giữ được phán đoán của mình, vì không có gì bảo nó rằng nó là worker. Cái giá là sự chú ý của tôi. Phải có người ngồi làm dispatcher, mà dispatch thì không scale quá vài job chạy song song.

Rồi tôi thử một công cụ dạng room với các thread riêng: mỗi worker là một agent tách biệt thật, có context riêng, phối hợp qua message tường minh thay vì spawn-rồi-chờ. Còn tốt hơn nữa. Worker cư xử như peer, vì về cấu trúc chúng đúng là peer. Chọn model theo từng task thành ra miễn phí: model rẻ chạy nhanh cho implementation có phạm vi, model nặng cho review và architecture.

Cái bẫy nằm ngay trong cách sửa: chồng orchestrator lên nhau. Chạy worker của công cụ room bên dưới hệ native subagent thì có hai coordinator, hai nguồn sự thật, và hỏng ở đâu thì không ai quy được cho ai. Chọn một tầng thôi. Tôi chọn tầng tường minh và tắt hẳn tầng native.

Suốt thời gian đó, một đồng nghiệp hoài nghi cứ hỏi mãi một câu hiển nhiên: sao không dùng một agent? Với phần lớn task thì anh đúng, tới giờ vẫn đúng. Trả lời thật thì phải xem khối lượng và hình dạng công việc. Việc gì tuyến tính thì một agent nhanh hơn. Multi-agent chỉ đáng công khi các slice cần phán đoán độc lập chạy song song, hoặc khi việc kiểm chứng phải đến từ một cái đầu không viết ra code. Giờ tôi mặc định một agent, chỉ nâng lên thành room khi task xứng đáng. Cái mặc định đó tiết kiệm quota hơn mọi lần đổi model tôi từng thử.

## Những câu hỏi còn để ngỏ

Ba câu hỏi từ tháng đó tới giờ vẫn để mở.

Thứ nhất, câu hỏi về harness. Ở tầng harness thì agent-điều-phối-agent khác parent-đẻ-ra-subagent ở chỗ nào? Thực tế tôi có câu trả lời chạy được: context tách biệt, địa vị peer, protocol tường minh. Nhưng chưa có phát biểu nào gọn về cơ chế. Đáng ra phải có người viết nó ra cho tử tế.

Thứ hai, routing model theo vai. Tôi có một lineup chạy được, còn lineup của người khác trông mỗi người một khác. Cả ngành chưa hội tụ, mà giá thì biến động hàng tháng, có khi chẳng bao giờ hội tụ thành một bảng ổn định. Nguyên tắc thì sống lâu hơn lựa chọn cụ thể: khớp giá với mức phán đoán cần thiết, đừng bao giờ giao vai buộc phải theo constraints cho model coi constraints là gợi ý.

Thứ ba, công tắc tắt. Một tính năng nền tảng không tắt được trong config thì không phải là tính năng. Nó là một dependency có chính kiến. Giờ tôi xét mọi thứ agent làm được bằng ba câu hỏi: nó hỏng thế nào, nó tính tiền thế nào, và tắt nó ra sao. Đúng theo thứ tự đó.

## Sau tất cả thì tôi ở đâu

Đến giữa tháng Tám, cấu hình của tôi là: native subagent tắt khắp nơi, mặc định một agent, peer dạng room cho phán đoán song song, routing model tường minh theo vai. Dòng quota trở lại bình thường. Quan trọng hơn, peer bắt đầu chất vấn tiền đề trở lại. Lần đầu một worker nói với lead rằng nền móng sai, và lead đổi hướng, cả tháng đó coi như tự trả tiền cho chính nó.

Câu hỏi orchestration không dừng lại ở đó. Một khi worker đã biết nói lại, tôi cần luật về ai nghe, ai quyết, và ai nhớ. Nó thành một mô hình ba vai mà giờ tôi chạy ở mọi nơi: [cho agent quyền cãi lại](/posts/slp-supervisor-lead-peer).
