Vấn đề
Một phiên AI coding thường chạy mọi task trên cùng một model, cùng một mức effort. Đổi tên biến hay refactor xuyên module đều dùng chung model đắt tiền. Như vậy vừa tốn tiền cho việc vặt, vừa có thể thiếu sức cho việc rủi ro, và không để lại dấu vết model nào đã làm hay kết quả có đúng không.
Tôi muốn một router chọn tier model rẻ nhất mà vẫn làm được việc, nâng cấp khi rủi ro là thật, và ghi lại những gì đã xảy ra theo cách kiểm tra lại được. Phần khó là sự trung thực. Một router tự đoán tỉ lệ thành công của chính nó còn tệ hơn không có router, vì tôi sẽ tinh chỉnh nó dựa trên những con số sai.
Tôi xây nó thành một router với hai adapter. Adapter định tuyến theo độ khó điều khiển một CLI coding agent và chọn model theo độ khó của task. Adapter định tuyến theo vai trò điều khiển một CLI coding agent khác và chọn model theo vai trò trong quy trình test-first. Cả hai dùng chung các script Python để định tuyến và ghi log, một wrapper PowerShell và một định dạng telemetry.
Tôi đã làm gì
Định tuyến bằng tín hiệu rủi ro, không cần gọi model
Trước khi bất kỳ model nào chạy, một bước preflight tất định xếp request vào một nhóm, chấm điểm những file trong repo có vẻ liên quan, rồi rút ra các tín hiệu như độ phức tạp, độ bất định, blast radius và việc thay đổi có xuyên nhiều thành phần hay không. Adapter định tuyến theo độ khó mặc định giao việc cho executor miễn phí. Nó chỉ nâng lên executor premium khi có tín hiệu cao, việc xuyên thành phần, lần trước đã thất bại, hoặc tôi yêu cầu. Model planner chỉ được gọi trong các trường hợp đó, kèm một gói context nhỏ đã che các giá trị giống secret. Một phần cố định các task mức trung bình cũng được cố ý gửi sang tier premium để router có dữ liệu so sánh. Đánh đổi: preflight dựa trên từ khóa khá thô và có thể đánh giá sai. Tôi chấp nhận vì nó rẻ, lặp lại được và dễ debug.
Giới hạn vòng lặp ngay trong code
Với việc cần chạy trong repo, adapter chạy executor, rồi verifier, rồi planner đưa ra kết luận: xong, làm tiếp, hoặc hỏi tôi. Phiên bản trước chỉ ghi giới hạn số lần gọi trong hướng dẫn, và lịch sử cho thấy giới hạn đó đã bị vượt. Tôi chuyển nó vào code thành một mức trần cứng cho số vòng lặp và số lần gọi ủy quyền. Hết ngân sách thì router hỏi tôi thay vì thử lại. Verifier phải báo exit code thật; bước kiểm tra nào không chạy được thì tính là “không xác minh được”, không bao giờ tính là pass. Đôi khi việc dừng sớm hơn một chút. Tôi chọn vậy còn hơn một hóa đơn không giới hạn.
Tách riêng ba kết luận
Mỗi lần chạy ghi ba thứ không bao giờ suy ra từ nhau: task có thành công không, việc định tuyến có đúng policy không, và telemetry có được ghi không. Một route chỉ được tính là “quan sát được” khi lấy từ metadata lúc chạy hoặc từ execution receipt. Thiếu receipt thì gắn nhãn unverified, mâu thuẫn thì gắn nhãn noncompliant. Telemetry không bao giờ lưu prompt, nội dung lệnh, output của tool hay credential. Nếu chưa có quyền sync, bản ghi nằm chờ trong một queue cục bộ và được khử trùng lặp sau. Cái giá là nhiều bản ghi vẫn ở trạng thái “không quan sát được”, khiến con số kém đẹp hơn.
Đo, nhận ra, rồi thay đổi
Adapter định tuyến theo vai trò đã qua ba policy. Ban đầu là các tier theo độ khó. Sau đó tôi thử một policy chặt: chỉ dùng một model premium nhanh, và chỉ khi có receipt đã xác minh. Log cho thấy trong 19 task theo policy đó, chỉ 1 task hoàn tất với receipt đã xác minh. Số còn lại fail closed vì timeout hoặc vướng phê duyệt, và không task nào bị đánh dấu tuân thủ sai. Cơ chế bảo vệ làm đúng việc của nó. Còn policy thì quá cứng để dùng hằng ngày. Tôi thay nó bằng định tuyến theo vai trò, bám theo playbook test-first của mình: tester, implementer và reviewer chỉ đọc, mỗi vai một tier riêng, chỉ nâng cấp khi rủi ro cao, có tranh chấp về test, hoặc một lần thất bại đã được xác minh.
Học chậm, có tôi duyệt
Một routing profile theo dõi tỉ lệ thành công theo từng loại task bằng khoảng tin cậy, và chờ đủ mẫu mới tin vào số liệu. Việc bảo trì router, lỗi môi trường và route không quan sát được đều bị loại ra. Policy mới đi qua chế độ shadow, rồi canary, rồi mới rollout toàn bộ, và bước cuối cần tôi duyệt.
Kết quả
Adapter định tuyến theo độ khó có con số rõ nhất. Trong các task của nó mà route model thực sự quan sát được, ~81% chạy trên tier executor miễn phí. Phần còn lại chia giữa executor premium và các lần chỉ chạy planner, và đa số task bỏ qua planner hoàn toàn.
Nói thẳng điểm cần lưu ý: tỉ lệ này hơi bị thổi phồng, vì các lần chạy verifier được ghi trên route miễn phí theo thiết kế. Cũng chưa có baseline về token hay chi phí. Bản CLI agent mà adapter này điều khiển không cung cấp số liệu usage cho từng lần gọi, nên tôi không thể khẳng định là tiết kiệm được tiền, và tôi không khẳng định điều đó. Adapter định tuyến theo vai trò có ghi số token nhưng không có so sánh trước và sau, nên những con số đó cũng không nói được gì về router.
Nếu làm lại
Tôi sẽ dựng baseline chi phí trước khi viết bất kỳ logic định tuyến nào, để kết quả chính đo được bằng tiền thay vì bằng tỉ lệ route. Tôi sẽ ghi các lần chạy verifier dưới route riêng để tỉ lệ tier miễn phí chính xác. Tôi cũng sẽ thử policy chỉ-dùng-model-nhanh dưới dạng canary nhỏ trước, vì chỉ vài ngày là receipt đã cho thấy vướng mắc.