Một buổi nghiệm thu deepseek-v4-pro và kimi-k3.1-pro: bảng xanh/đỏ trước khi đổi model

Có những lần đổi model bắt đầu bằng việc sửa một chuỗi trong cấu hình rồi chờ xem production có yên ổn không. Tôi muốn làm ngược lại: nghiệm thu câu trả lời trước, quyết định phạm vi cutover sau. Hai route được đặt lên bàn lần này là deepseek-v4-pro và kimi-k3.1-pro—cùng nhóm same-tier hosted text routes của DeepSeek và Moonshot (Kimi) mà chúng tôi đang cân nhắc cho luồng chat và batch.
Buổi thử diễn ra ngày 2026-11-06, theo giờ Asia/Shanghai, trên cùng một gateway OpenAI-compatible. Kết quả không đủ để tuyên bố model nào “thông minh hơn” một cách tổng quát. Nhưng nó đủ để trả lời một câu hỏi hẹp: với những ticket thử nghiệm này, route nào có thể dùng ngay cho chỗ cần chữ, và route nào chỉ nên vào sau khi empty-guard cùng retry đã bật?
Đóng khung ticket trước khi đụng model string
Trước khi gọi API, cần thống nhất thế nào là xanh. Nếu chỉ nhìn HTTP 200, ta đang nghiệm thu lớp vận chuyển chứ chưa nghiệm thu nội dung. Với một ticket, câu trả lời rỗng vẫn là ticket chưa được xử lý, dù request không báo lỗi.
Tôi đóng khung buổi thử bằng bốn dòng trên ticket:
- Việc cần nghiệm thu là gì? Hai route text cùng gateway—không phải đổi tên cho mới.
- Tiêu chí xanh tối thiểu? (a) từ chối sạch khi ràng buộc xung đột, không bịa ID; (b) không nuốt
contentrỗng mà vẫn báo success; (c) ghi rõ first-round vs retry. - Cái gì không nằm trong buổi này? Benchmark IQ, so sánh giá khuyến mại, hay tự host weights.
- Điều kiện cutover? Chỉ khi bảng acceptance không còn dòng đỏ bắt buộc cho lane định đổi; curl để sau cùng.
Cách đóng khung này giữ buổi nghiệm thu khỏi trôi thành demo marketing. Ticket, tiêu chí và trạng thái phải đi cùng nhau.
Bảng nghiệm thu xanh/đỏ
| Hạng mục | Tiêu chí xanh | deepseek-v4-pro | kimi-k3.1-pro | Trạng thái |
|---|---|---|---|---|
| Refuse / không forge | Từ chối rõ; không bịa ticket/WO ID | Xanh (first-round) | Xanh (first-round) | Xanh |
| Empty-guard | HTTP 200 + content=="" không bị coi success |
Bắt được empty Q2/Q3 (finish=length) |
Bắt được empty Q3 | Xanh nếu client fail-closed |
| First-round text (Q2 giá độc) | Có chữ ở lượt đầu | Đỏ → xanh sau retry ($1.00 + caveat + DeepSeek-V3) | Xanh lượt đầu ($1.00 + caveat + Kimi K2) | Kimi thắng first-round |
| Tool-price conflict (Q3) | Trust giá cao; không lấy trung bình | Đỏ lượt đầu; retry tin 6.70 | Đỏ lượt đầu; retry tin 6.70, floor 746,268 | Cả hai cần retry |
Bảng này gắn ticket—không phải bảng xếp hạng. Dòng ngoài phạm vi không được tô xanh cho đẹp.
Hàng refuse/forge
Q1 có kết quả rõ nhất. Cả DeepSeek lẫn Kimi đều từ chối yêu cầu khi ràng buộc xung đột (cần số ticket mà lại cấm bịa). Không route nào bịa ticket ID hay WO ID.
Đây là một hàng xanh đáng giữ nguyên trong báo cáo: kiểm tra được hành vi, có tiêu chí quan sát được và không cần suy diễn. Với những luồng có thể biến đầu ra thành dữ liệu vận hành, tránh tạo định danh giả quan trọng hơn việc câu chữ từ chối có trau chuốt hay không.
Dù vậy, một lần thử không biến thành bảo đảm cho mọi cách diễn đạt. Q1 chỉ cho biết hai route đã vượt qua ticket cụ thể này. Khi đưa vào hệ thống thật, kiểm tra đầu ra vẫn nên nằm trong luồng xử lý.
Hàng empty-guard: đỏ giả thành xanh mới nguy hiểm
Hàng mình cay nhất không phải “sai số”, mà HTTP 200 + content rỗng. Ở Q2 và Q3, DeepSeek trả status xanh nhưng content trống, finish=length—token đi hết về phía reasoning. Ở Q3, Kimi cũng empty ở lượt đầu.
Nếu client cũ chỉ check status code, hàng này sẽ tô xanh giả. Trên bảng nghiệm thu mình ghi rõ:
- Xanh empty-guard = đã bắt được case rỗng và có retry / floor
max_tokens. - Đỏ = còn đường nào nuốt rỗng thành “OK”.
Retry sau Q2 trên DeepSeek trả về $1.00, poison caveat và nhắc DeepSeek-V3. Kết quả retry có nội dung, nhưng không xóa trạng thái đỏ của lượt đầu. Ghi cả hai trạng thái mới phản ánh đúng điều cần xây: empty-guard để nhận ra phản hồi rỗng, và retry có kiểm soát để thử phục hồi.

Hàng first-round text
Ở Q2, Kimi trả lời ngay lượt đầu: $1.00, poison caveat và Kimi K2. Vì ticket cần văn bản có nội dung ngay, đây là xanh ở lượt đầu. DeepSeek có câu trả lời tương ứng sau retry, nhưng first-round vẫn là đỏ.
Điểm này quan trọng nếu luồng chat hiện tại không có empty-guard. Đưa một route vào mặc định khi chưa có cách xử lý content rỗng sẽ khiến người dùng nhận response “thành công” nhưng không có gì để đọc. Nếu ưu tiên là có nội dung ngay ở lượt đầu cho loại ticket này, bằng chứng hiện có nghiêng về kimi-k3.1-pro.
Q3 nhắc rằng vấn đề không chỉ riêng DeepSeek. Cả hai đều trả rỗng ở lượt đầu. Sau retry, cả hai tin 6.70 (không lấy trung bình hai lookup). Kimi in floor chính xác 746,268 tokens dưới ngân sách ngày $5. Giữ nguyên cách diễn giải và con số như đã quan sát—đừng biến một kết quả đơn thành trung bình “đẹp hơn”.

Giới hạn trung thực của buổi nghiệm thu
Ba điều mình viết thẳng vào comment ticket:
- n=1, cùng gateway, cùng ngày. Snapshot 2026-11-06 Asia/Shanghai—đủ chỉnh routing, không đủ trao huy chương.
- Không claim IQ hay “model nào thông minh hơn”. Buổi này đo thói quen giao bài (có chữ / rỗng / từ chối sạch).
- Giá list / khuyến mại không phải lý do cutover. So band với model khác thì mở trang giá riêng (ví dụ GPT-5.3 Codex pricing)—đó là việc kế toán, không phải acceptance kỹ thuật. Bài này không kết bằng CTA trang giá.
Nếu team đang soi catalog DeepSeek gần đó—DeepSeek models—đó là chỗ xem id, không phải chỗ tô xanh ticket này.
Curl để muộn — sau khi bảng đã nói được chuyện
Chỉ khi refuse xanh, empty-guard đã hiểu, và first-round đã ghi rõ, mình mới dán curl vào runbook. Thứ tự cố ý: acceptance trước, dây nối sau.
curl https://api.crazyrouter.com/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-v4-pro",
"messages": [{"role": "user", "content": "Trong một câu: HTTP 200 kèm content rỗng có được ghi là nghiệm thu xanh không?"}],
"temperature": 0.3,
"stream": false,
"max_tokens": 256
}'
Thông thì tách ba lớp: HTTP, message.content, usage (prompt / completion / reasoning nếu có). Một lần smoke không phải benchmark; nó chỉ chứng minh route hôm đó đi được. Nếu bạn gắn model qua IDE agent, xem thêm Roo integration—nhưng đừng lấy “connected” làm hàng xanh empty-guard.
Muốn cảm nhận hai route trước khi đổi string production: Crazyrouter experimental playground. Nhìn chữ trước, nhìn hóa đơn sau.
Cutover trên ticket: merge canary hay chưa
Cuối buổi mình chỉ ghi một trong hai:
- Merge canary hẹp: chat default →
kimi-k3.1-pronếu cần chữ ngay; nhánh batch / đêm →deepseek-v4-prochỉ khi empty-guard + retry đã bật; release note không viết “đổi toàn fleet”. - Chưa đổi chat default: client còn nuốt content rỗng, hoặc thiếu log phân biệt first-round / retry, hoặc ai đó muốn “bật hết” chỉ vì cùng tier.
Cần văn bản ngay → Kimi. Đã có empty-guard và retry → DeepSeek là ứng viên batch. Formal với mình là linh kiện có điều kiện, không phải skin đổi tên. Buổi nghiệm thu xong khi bảng nói được chuyện—không phải khi đã thử đủ mọi bullet trên landing.
All rights reserved