Model đắt gấp 5 — đo đúng hiệu quả routing bằng RDD

Model đắt gấp 5 — đo đúng hiệu quả routing bằng RDD

Team bạn route query theo confidence score, nhưng đo hiệu quả routing sai cách. Playbook dùng Regression Discontinuity Design để trả lời: model premium có thực sự đáng tiền?

Bạn đang đốt tiền hay đang đầu tư?

Bạn dựng routing layer: query nào confidence score dưới 0.85 thì chuyển sang model premium (đắt gấp 5), trên 0.85 thì model distilled rẻ hơn. Chạy được vài tuần, sếp hỏi: "Model đắt kia có thật sự cải thiện kết quả không?"

Phản xạ đầu tiên: so sánh tỷ lệ hoàn thành task giữa hai nhóm. Nhóm premium cao hơn → kết luận premium tốt hơn → xin thêm budget.

Sai. Vì premium nhận toàn query khó — đó là lý do bạn route chúng sang đó. So sánh thẳng giống như nói đầu bếp A giỏi hơn đầu bếp B vì A nấu bò wagyu ngon hơn B nấu cơm rang — hai người đang làm hai bài khác nhau.

Bạn cũng không A/B test được, vì routing hoàn toàn deterministic: 0.84 luôn đi premium, 0.86 luôn đi rẻ. Không random assignment, không A/B.

Vậy đo bằng gì? Regression Discontinuity Design — viết tắt RDD — một kỹ thuật causal inference (suy luận nhân quả) tận dụng chính cái ngưỡng 0.85 làm thí nghiệm tự nhiên. Query 0.849 và query 0.851 gần như giống nhau về độ khó, chỉ khác model xử lý. Mọi chênh lệch kết quả → do model, không do bài toán.

Điều kiện để dùng được

Trước khi đi vào từng bước, kiểm tra hệ thống bạn có đủ 4 điều kiện:

Thiếu bất kỳ điều kiện nào → dừng ở đây. RDD không phải công cụ phù hợp.

Ba bước chạy RDD trên dữ liệu routing

Bước 1 — Chuẩn bị dữ liệu

Bạn cần bảng telemetry với ít nhất 3 cột: confidence_score, routed_to (premium/cheap), và task_completed (0/1). Export từ logging pipeline hoặc observability stack.

Giả sử team bạn ở một startup fintech Việt Nam, 5 người, đang route câu hỏi khách hàng giữa một model lớn và một model distilled nhỏ hơn. Mỗi ngày khoảng 2.000 query, chạy 3 tuần là đủ tầm 40.000 dòng — vừa đủ để phân tích.

Bước 2 — Chạy local linear regression quanh ngưỡng

Dịch ra tiếng đời thường: bạn chỉ nhìn vào dữ liệu sát ngưỡng 0.85 — ví dụ từ 0.82 đến 0.88. Trong vùng hẹp này, query hai bên ngưỡng gần như giống nhau về độ khó. Bất kỳ khác biệt outcome nào → do model xử lý.

Khoảng dữ liệu quanh ngưỡng gọi là bandwidth — cửa sổ quan sát. Chọn bandwidth quá rộng thì lẫn query khác độ khó, quá hẹp thì thiếu data. Giống nêm muối: nhạt quá thì không ra vị, mặn quá thì hỏng cả nồi.

Với Python, dùng statsmodels hoặc thư viện rdrobust (open-source, có bản Python lẫn R). Sweep nhiều bandwidth (0.02, 0.03, 0.05, 0.07) rồi xem estimate có ổn định không. Kết quả nhảy lung tung khi đổi bandwidth → data chưa đủ hoặc threshold không sắc.

Bước 3 — Kiểm tra sức khỏe kết quả

Ba bài test bắt buộc trước khi tin vào con số:

  1. Manipulation test: vẽ histogram của confidence score quanh 0.85. Nếu thấy đột biến dồn về một phía → có gì đó đang can thiệp score trước khi nó tới routing layer. Dùng McCrary test hoặc đơn giản là nhìn biểu đồ.
  1. Placebo test: dời ngưỡng sang 0.80 hoặc 0.90 — nơi không có routing change — rồi chạy lại RDD. Nếu vẫn thấy "hiệu ứng" ở ngưỡng giả → model bạn đang overfit, kết quả ban đầu không đáng tin.
  1. Bootstrap confidence interval (khoảng tin cậy bằng lấy mẫu lặp): lặp lại phân tích 1.000 lần trên các mẫu ngẫu nhiên, xem kết quả dao động bao nhiêu. Khoảng tin cậy 95% chứa 0 → chưa có bằng chứng premium tốt hơn.

Sai lầm phổ biến khi team Việt Nam áp dụng

"Data nhiều là đủ" — Một team e-commerce có hàng trăm nghìn query mỗi tháng, tự tin chạy RDD. Nhưng confidence score phân bố lệch: hơn 90% query nằm trên 0.90, chỉ vài trăm query quanh ngưỡng 0.85. RDD cần data quanh ngưỡng, không phải data tổng. Kết quả ra một con số đẹp nhưng confidence interval rộng đến vô nghĩa — giống khoe món ăn trông đẹp mà chưa ai nếm thử.

"Một lần đo là xong" — Threshold tối ưu hôm nay có thể lệch tuần sau. Khi distribution query thay đổi (mùa sale, tính năng mới, user mới), bandwidth cũ cho kết quả sai. Nên chạy lại ít nhất mỗi tháng hoặc khi traffic pattern thay đổi rõ rệt.

Quên đo cost-effectiveness — RDD cho biết premium model tăng task completion thêm bao nhiêu tại ngưỡng. Nhưng nếu mức tăng chỉ vài điểm phần trăm mà chi phí gấp 5 lần, quyết định kinh doanh có thể vẫn là dùng model rẻ. Hiểu nôm na: biết nguyên liệu đắt tiền cho vị ngon hơn thật, nhưng khách có sẵn sàng trả gấp đôi cho tô phở đó không?

Sau khi có con số — quyết định gì?

RDD không nói "nên dùng model nào". Nó nói: "tại ngưỡng X, model premium tạo ra Y% khác biệt so với model rẻ". Từ đó bạn có ba hướng:

  1. Điều chỉnh ngưỡng: nếu premium effect lớn và có ý nghĩa thống kê, hạ threshold (ví dụ từ 0.85 xuống 0.80) để nhiều query khó hơn được premium xử lý. Nếu effect nhỏ, nâng threshold lên để tiết kiệm.
  1. Thay model rẻ hơn: nếu premium effect gần bằng 0, model rẻ đang làm tốt — cơ hội cắt cost mà không mất chất lượng.
  1. Thêm tầng routing: chia thành 3 tier dựa trên confidence score, mỗi tier một model. Dùng RDD tại từng ngưỡng để đo từng bước nhảy.

Với team nhỏ ở Việt Nam — giả sử 3-5 dev, budget cloud hạn chế — hướng thực tế nhất thường là hướng 1: giữ architecture đơn giản, chỉ tinh chỉnh ngưỡng dựa trên data. Phức tạp hóa routing khi chưa đo được hiệu quả từng tầng là cách nhanh nhất để tạo ra hệ thống không ai debug nổi.

Bản chất là: đừng hỏi "model nào tốt hơn", hãy hỏi "tại điểm chuyển giao, sự khác biệt có đủ lớn để justify chi phí không". RDD cho bạn con số để trả lời câu đó — phần còn lại là quyết định kinh doanh.

---

Bụi Wire — nghiện đọc release notes lúc 2 giờ sáng

Nguồn tham khảo