Đặt một lớp trừu tượng model ở server: một hàm generate(messages, options) nội bộ, bên trong chọn provider theo thứ tự ưu tiên.
Thêm circuit breaker để khi provider chính hỏng liên tục thì bỏ qua luôn trong vài phút, không phải request nào cũng chờ hết timeout rồi mới chuyển.
const CHAIN = ['primary', 'secondary'] as const
for (const name of CHAIN) {
if (breaker.isOpen(name)) continue
try {
return await providers[name].generate(input)
} catch (err) {
if (!isRetryable(err)) throw err // bad prompt fails on every provider
breaker.record(name)
}
}
throw new AllProvidersFailedError()Cạm bẫy thực tế:
- Prompt không chuyển thẳng được. Mỗi nhà cung cấp có định dạng system prompt, tool schema và cách trả structured output khác nhau. Chuẩn hoá ở tầng trừu tượng, đừng ném nguyên payload sang.
- Chất lượng tụt âm thầm. Model dự phòng thường yếu hơn. Ghi rõ model đã dùng vào log của mỗi request, nếu không bạn sẽ điều tra chất lượng giảm mà không biết hôm đó chạy bằng model nào.
- Chỉ fallback lỗi hạ tầng. Prompt sai định dạng, vi phạm chính sách nội dung, vượt context — provider nào cũng hỏng, chuyển sang chỉ tốn thêm tiền và thêm độ trễ.
- Chi phí khác nhau. Hạch toán token theo đúng bảng giá của provider thực sự đã phục vụ request.
Fallback tự động chỉ đáng làm nếu chất lượng model dự phòng vẫn ở mức chấp nhận được. Nếu không, báo lỗi rõ ràng và cho thử lại thường tốt hơn là im lặng trả về câu trả lời kém.