LLM API Fallback Routing: Sổ tay failover cho môi trường production
Fallback routing cho LLM APIs nghe có vẻ đơn giản cho đến khi sự cố thực tế đầu tiên xảy ra: bắt lỗi, chuyển model và thử lại. Trong production, quy tắc đó có thể biến một vấn đề của một provider thành các lệnh gọi tool bị trùng lặp, JSON bị lỗi, đầu ra streaming bị lẫn, lưu lượng retry bùng nổ, hoặc một phản hồi về mặt kỹ thuật là thành công nhưng không còn đáp ứng được hợp đồng của sản phẩm.
Một thiết kế an toàn hơn xem fallback như một bounded state machine, chứ không phải danh sách các tên model dự phòng. Mỗi request đi qua một tập quyết định nhỏ:
- Lỗi này có thể retry được không?
- Có an toàn để lặp lại request này không?
- Lần thử tiếp theo nên dùng cùng target hay một target khác?
- Fallback có thể giữ nguyên hợp đồng yêu cầu không?
- Request này đã tạo ra đầu ra hoặc side effects chưa?
- Độ trễ end-to-end và ngân sách số lần thử đã bị dùng hết chưa?
Sổ tay này biến những câu hỏi đó thành một error matrix, chính sách routing, controller TypeScript, kế hoạch kiểm thử và checklist rollout cho các ứng dụng LLM đa provider.
Bốn hành động đứng sau fallback routing đáng tin cậy cho LLM API
Đừng đưa mọi lỗi vào cùng một retry loop. Một router trong production cần bốn hành động riêng biệt.
| Hành động | Dùng khi | Ví dụ điển hình |
|---|---|---|
| Retry cùng target | Lỗi có vẻ chỉ là tạm thời và deployment hiện tại có thể hồi phục trong thời hạn của request | Connection reset trước headers, timeout cô lập, chờ rate limit ngắn |
| Fail over sang target tương đương | Provider, region, deployment hoặc account đang không ổn định nhưng cùng model contract vẫn có sẵn ở nơi khác | Sự cố vùng, quota deployment đã cạn, phản hồi 5xx lặp lại |
| Fallback sang model khác | Một model thay thế đã được đánh giá có thể giữ được năng lực tối thiểu của ứng dụng và output contract | Model chính không khả dụng và model phụ đã được kiểm thử hỗ trợ cùng tool và schema |
| Dừng và hiển thị lỗi | Lặp lại request sẽ không khắc phục được, có thể tạo side effects, hoặc không thể giữ nguyên contract | Xác thực không hợp lệ, request sai định dạng, parameter không được hỗ trợ, policy block, stream bị ngắt giữa chừng |
Sự khác biệt giữa failover và fallback là quan trọng. Failover giữ nguyên logical model contract và thay đổi hạ tầng. Fallback thay đổi model hoặc cấp năng lực. Failover thường là lựa chọn ít rủi ro hơn.
Nếu bạn cần thiết kế đường đi của request rộng hơn xung quanh aliases, health scoring, billing và observability, hãy bắt đầu với AI API gateway architecture guide. Bài viết này tập trung vào controller chạy sau khi một target đã được chọn.
Xây dựng error-to-action matrix trước khi viết retry code
Các Provider SDKs có những exception class và response body khác nhau, nhưng router nên chuẩn hóa chúng thành một taxonomy nội bộ nhỏ gọn.
| Lỗi chuẩn hóa | Thử lại cùng đích? | Failover tương đương? | Fallback sang model khác? | Ghi chú |
|---|---|---|---|---|
| Lỗi kết nối trước khi yêu cầu được chấp nhận | Có, một lần | Có | Có thể | Giữ trong một deadline end-to-end duy nhất |
| Timeout trước khi có header phản hồi | Có thể | Có | Có thể | Chỉ lặp lại các yêu cầu an toàn để phát lại |
Giới hạn tốc độ 429 |
Sau một độ trễ giới hạn | Có | Có thể | Tôn trọng hướng dẫn từ server khi có; không tạo ra cơn bão retry |
5xx hoặc quá tải từ nhà cung cấp |
Nhiều nhất một lần | Có | Có thể | Mở circuit sau khi vượt ngưỡng lỗi đã định |
| Lỗi xác thực hoặc quyền truy cập | Không | Không | Không | Sửa thông tin xác thực hoặc policy; chuyển model không giúp được |
| Yêu cầu sai định dạng hoặc tham số không được hỗ trợ | Không | Không | Không | Chỉnh lại hợp đồng của client |
| Vượt quá độ dài ngữ cảnh | Không thử lại mù quáng | Không | Chỉ khi có điều chỉnh rõ ràng | Cắt bớt, tóm tắt, hoặc route ngữ cảnh lớn hơn sẽ thay đổi yêu cầu |
| Từ chối vì an toàn hoặc policy | Không thử lại mù quáng | Không | Thường là không | Chuyển provider để né quyết định policy không phải là chiến lược độ tin cậy |
| Lỗi xác thực schema đầu ra | Có thể với sửa lỗi | Không | Chỉ khi đã được đánh giá | Giữ sửa schema tách biệt với retry ở tầng truyền tải |
| Stream lỗi trước token đầu tiên | Có thể | Có | Có thể | Chưa có output nào nhìn thấy bởi người dùng |
| Stream lỗi sau khi output bắt đầu | Không tự động chuyển | Không | Không tự động chuyển | Không ghép hai phản hồi model với nhau |
| Lệnh gọi tool có thể đã thực thi | Không thử lại mù quáng | Không | Không thử lại mù quáng | Yêu cầu idempotency key hoặc cơ chế khử trùng lặp ở cấp tool |
Tài liệu chính thức của nhà cung cấp củng cố lý do vì sao chuẩn hóa là cần thiết. Anthropic mô tả các lỗi rate-limit, API và overload khác nhau, đồng thời lưu ý rằng một yêu cầu streaming vẫn có thể thất bại sau khi đã nhận được phản hồi ban đầu thành công. OpenAI cũng phân tách lỗi yêu cầu không hợp lệ, giới hạn tốc độ và lỗi phía server. Ứng dụng của bạn nên chuyển các tín hiệu đặc thù của từng nhà cung cấp thành các quyết định nội bộ ổn định thay vì nhúng tên nhà cung cấp xuyên suốt logic nghiệp vụ.
Đặt một ngân sách retry duy nhất bao quanh toàn bộ yêu cầu
Các retry thường tồn tại ở nhiều nơi cùng lúc: HTTP client, provider SDK, gateway, background job và application service. Nếu mỗi lớp thực hiện ba lần thử, một hành động duy nhất của người dùng có thể nhân lên thành nhiều lời gọi upstream hơn rất nhiều so với dự định của đội ngũ.
Mẫu an toàn hơn là:
- Chọn một lớp để chịu trách nhiệm retry và fallback cho LLM.
- Đặt một deadline end-to-end cho request hoặc job của người dùng.
- Đặt số lần thử upstream tối đa.
- Dành một phần của deadline cho target fallback.
- Sử dụng exponential backoff với jitter cho các lỗi tạm thời.
- Dừng lại khi thời gian còn lại không thể hỗ trợ thêm một lần thử có ý nghĩa nào nữa.
Hướng dẫn của AWS về timeouts, retries, backoff và jitter mô tả cách retries có thể khuếch đại tình trạng quá tải và khuyến nghị hành vi có giới hạn thay vì lặp lại ngay lập tức liên tục. Nguyên tắc tương tự áp dụng cho model API, nơi một provider đang quá tải là nơi kém có khả năng nhất để hấp thụ lưu lượng retry đồng bộ.
Một budget tương tác thực tế có thể được biểu diễn dưới dạng policy thay vì hard-code thời gian ngủ:
type RetryBudget = {
deadlineMs: number;
maxAttempts: number;
maxSameTargetAttempts: number;
reserveForFallbackMs: number;
};
Các giá trị cụ thể phụ thuộc vào sản phẩm. Giao diện chat, coding agent, batch evaluator và quy trình video bất đồng bộ không nên dùng chung một budget.
Use circuit breakers to stop routing into known failures
Circuit breaker ngăn mọi request mới tự mình gặp lại cùng một sự cố.
Các trạng thái chuẩn là:
- Closed: request đi qua bình thường trong khi router đo lường lỗi và độ trễ.
- Open: target tạm thời không đủ điều kiện vì hành vi gần đây của nó đã vượt ngưỡng.
- Half-open: một số lượng nhỏ request thăm dò kiểm tra xem target đã phục hồi hay chưa.
Mẫu circuit-breaker của Azure mô tả vòng đời closed/open/half-open này. Với routing cho LLM, key của breaker nên đủ cụ thể để cô lập bề mặt bị lỗi. Các chiều hữu ích bao gồm provider, model, region, deployment, account và capability. Một deployment text-completion có thể vẫn khỏe mạnh trong khi một route tool-calling hoặc endpoint theo vùng đang bị lỗi.
Tránh mở circuit trên mọi client error. Xác thực không hợp lệ, request sai định dạng, vượt quá context và từ chối do policy thường nói nhiều hơn về request hơn là về sức khỏe của provider. Breaker nên phản ứng chủ yếu với các tín hiệu hạ tầng tạm thời như lỗi kết nối, timeout, quá tải và lỗi server.
Preserve a capability contract across models
Một fallback model không an toàn chỉ vì nó chấp nhận request tương thích với OpenAI. Hãy định nghĩa hợp đồng tối thiểu cho từng route alias.
route: support-agent-v3
requires:
modalities: [text]
streaming: true
tools: true
parallel_tool_calls: false
structured_output: json_schema
context_window_min: 64000
max_output_tokens_min: 4000
quality_gates:
task_success_rate_min: 0.94
schema_valid_rate_min: 0.995
policy:
same_model_failover_first: true
cross_model_fallback_allowed: true
Trước khi thêm một target vào tập fallback, hãy kiểm tra ít nhất:
- Các tham số yêu cầu được hỗ trợ
- Định nghĩa công cụ và hành vi gọi công cụ
- Tính hợp lệ của đầu ra có cấu trúc
- Hình dạng sự kiện streaming
- Giới hạn ngữ cảnh và đầu ra
- Hành vi an toàn phù hợp với ứng dụng
- Các trường kế toán token được dùng cho kiểm soát chi phí
- Độ trễ và chất lượng trên các prompt đại diện
Cách tiếp cận ưu tiên hợp đồng này đặc biệt quan trọng đối với các workflow đi qua nhiều modality. Hướng dẫn định tuyến agent đa phương thức bao gồm các kiểm tra bổ sung cho các tuyến text, image, audio và video.
Một bộ điều khiển fallback bằng TypeScript
Ví dụ sau đây được cố tình thiết kế trung lập với nhà cung cấp. Nó giả định các adapter ở upstream chuẩn hóa lỗi và phản hồi trước khi lớp định tuyến nhìn thấy chúng.
type FailureKind =
| "connect"
| "timeout"
| "rate_limit"
| "overloaded"
| "server_error"
| "invalid_request"
| "auth"
| "policy"
| "context_overflow"
| "partial_stream"
| "unknown";
type Target = {
id: string;
contractId: string;
healthy: boolean;
circuit: "closed" | "open" | "half_open";
};
type RequestState = {
attempt: number;
sameTargetAttempts: number;
deadlineAt: number;
outputStarted: boolean;
sideEffectsPossible: boolean;
};
function canReplay(state: RequestState): boolean {
return !state.outputStarted && !state.sideEffectsPossible;
}
function isTransient(kind: FailureKind): boolean {
return [
"connect",
"timeout",
"rate_limit",
"overloaded",
"server_error",
].includes(kind);
}
function chooseNextAction(
kind: FailureKind,
state: RequestState,
current: Target,
equivalent: Target | undefined,
fallback: Target | undefined,
) {
if (!canReplay(state) || kind === "partial_stream") return { type: "stop" };
if (!isTransient(kind)) return { type: "stop" };
if (state.attempt >= 3 || Date.now() >= state.deadlineAt) {
return { type: "stop" };
}
if (
state.sameTargetAttempts < 1 &&
current.circuit === "closed" &&
current.healthy
) {
return { type: "retry", target: current };
}
if (equivalent?.healthy && equivalent.circuit !== "open") {
return { type: "failover", target: equivalent };
}
if (
fallback?.healthy &&
fallback.circuit !== "open" &&
fallback.contractId === current.contractId
) {
return { type: "fallback", target: fallback };
}
return { type: "stop" };
}
Mã sản xuất cũng cần các độ trễ có jitter, truyền tiếp việc hủy, request ID, cập nhật circuit breaker, telemetry, và phân tích lỗi đặc thù của adapter. Thuộc tính quan trọng là tính an toàn khi replay và khả năng tương thích hợp đồng phải được kiểm tra trước khi chọn target khác.
Xử lý streaming fallback như một giao thức riêng biệt
Streaming tạo ra một ranh giới rõ ràng: một khi nội dung đã đến client, gateway không thể giả vờ rằng lần thử đó chưa từng xảy ra.
Nếu upstream thất bại trước khi event đầu tiên được chuyển tiếp, retry hoặc fallback vẫn có thể diễn ra một cách trong suốt. Sau khi token đầu tiên, tool delta, event ảnh hoặc audio chunk được gửi đi, việc tự động chuyển model có nguy cơ ghép hai phản hồi không tương thích với nhau.
Hãy dùng một trong các chiến lược rõ ràng sau:
- Fail luồng một cách rõ ràng. Trả về một event lỗi ổn định kèm request ID và để client đề xuất retry.
- Buffer trước khi phát hành. Với các phản hồi có cấu trúc ngắn, hãy xác thực kết quả hoàn chỉnh trước khi gửi xuống downstream. Cách này đánh đổi time-to-first-token.
- Triển khai resume ở cấp ứng dụng. Bắt đầu một lượt mới với ngữ cảnh rõ ràng rằng phản hồi trước đó đã bị gián đoạn. Hãy coi đó là một lần sinh model mới, không phải sự tiếp nối của cùng một byte stream.
Đừng âm thầm nối output từ hai model.
Tách riêng độ tin cậy của tool-call khỏi độ tin cậy của model-call
Một request tới LLM có thể replay được trong khi tool mà nó chọn thì không. Một thanh toán, email, deployment, ghi vào database, hoặc tạo ticket có thể thành công ngay cả khi kết nối model thất bại trước khi ứng dụng ghi nhận kết quả.
Bảo vệ các tool ghi dữ liệu bằng:
- Một idempotency key được suy ra từ thao tác của người dùng, không phải từ lần thử của provider
- Một bản ghi thực thi tool bền vững
- Deduplication ở ranh giới của tool
- Phân biệt rõ giữa
planned,started,succeeded, vàunknown - Đánh giá của con người đối với các side effect có tác động cao nhưng không chắc chắn
Nếu có thể phát sinh side effect và kết quả của nó không rõ, hãy dừng fallback tự động. Trước hết, cần đối soát trạng thái của tool.
Theo dõi fallback như một kết quả sản phẩm
Tỷ lệ lỗi thấp từ provider không chứng minh rằng fallback đang hoạt động. Hãy theo dõi kết quả route đầy đủ.
| Metric | Nó cho thấy điều gì |
|---|---|
| Tỷ lệ thành công ở target chính | Sức khỏe cơ bản của provider hoặc deployment |
| Tỷ lệ phục hồi sau retry | Việc retry trên cùng target có hữu ích hay không |
| Tỷ lệ phục hồi failover tương đương | Giá trị của các deployment hoặc region dự phòng |
| Tỷ lệ phục hồi fallback giữa các model | Giá trị của bộ model thay thế |
| Tỷ lệ từ chối theo hợp đồng | Tần suất các target ứng viên không vượt qua kiểm tra điều kiện |
| Tính hợp lệ của schema sau fallback | Liệu các phản hồi “thành công” có còn dùng được hay không |
| Thành công của tác vụ sau fallback | Liệu người dùng vẫn hoàn thành được công việc dự định hay không |
| Độ trễ fallback tăng thêm | Chi phí độ tin cậy mà người dùng phải trả |
| Chênh lệch chi phí fallback | Tác động đến hóa đơn của đường phục hồi |
| Thời gian circuit mở và tỷ lệ probe thành công | Ngưỡng breaker và thời điểm phục hồi có hợp lý hay không |
Ghi log lý do route cho mỗi lần thử: target được chọn, lỗi đã chuẩn hóa, độ trễ retry, trạng thái circuit, lý do fallback, thời gian còn lại trước deadline của request, và kết quả cuối cùng. Tránh ghi log prompt hoặc output nhạy cảm trừ khi chính sách dữ liệu của sản phẩm cho phép rõ ràng.
Kiểm thử các đường lỗi trước khi bật fallback tự động
Chạy failure injection trong môi trường staging rồi triển khai canary chính sách này trong production.
Kiểm thử transport và provider
- Ngắt kết nối trước khi có header phản hồi.
- Trả về các giới hạn tần suất lặp lại cả khi có và không có hướng dẫn thử lại.
- Mô phỏng tình trạng quá tải và lỗi máy chủ.
- Trì hoãn primary cho đến khi gần cạn thời hạn của yêu cầu.
- Mở một circuit của target và xác minh lưu lượng chuyển sang một route đủ điều kiện.
- Khôi phục target và xác minh các probe half-open không khôi phục toàn bộ lưu lượng quá sớm.
Contract tests
- Loại bỏ một tool bắt buộc khỏi fallback adapter.
- Trả về structured output không hợp lệ.
- Thay đổi định dạng của một streaming event.
- Vượt quá giới hạn context hoặc output.
- So sánh chất lượng fallback trên một bộ evaluation cố định.
Replay-safety tests
- Thất bại trước và sau event được stream đầu tiên.
- Thất bại sau khi một tool phía ghi bắt đầu.
- Lặp lại cùng một idempotency key.
- Hủy request của client trong khi lần thử fallback đang chờ xử lý.
Bài kiểm thử chỉ đạt khi router chọn đúng hành động và ghi lại lý do.
Flatkey phù hợp ở đâu
Flatkey cung cấp một API key và một base URL tương thích OpenAI cho các model được hỗ trợ, cùng với việc quản lý usage và billing tập trung. Điều đó tạo ra một ranh giới tích hợp ổn định cho việc truy cập và định tuyến đa model.
Các nhóm ứng dụng vẫn nên tự chịu trách nhiệm cho route contract được mô tả trong playbook này: lỗi nào được phép retry, target nào được xem là tương đương, có cho phép fallback giữa các model hay không, cách khử trùng lặp tool như thế nào, và ngưỡng chất lượng nào mà một phản hồi được khôi phục phải đạt.
Để có đường tích hợp ngắn nhất, hãy dùng Flatkey integration starter. Nếu bạn đang di chuyển một client hiện có, OpenAI-compatible API gateway checklist bao gồm base URL, tham số, streaming, và xác minh lỗi theo đúng định dạng.
Checklist triển khai production
- Chuẩn hóa lỗi của nhà cung cấp thành một taxonomy nội bộ ổn định.
- Định nghĩa retry, failover tương đương, fallback giữa các model, và các hành động dừng.
- Chỉ định một thành phần chịu trách nhiệm cho retry budget.
- Áp đặt một deadline end-to-end và số lần thử tối đa duy nhất.
- Thêm exponential backoff với jitter cho các lỗi tạm thời.
- Gán circuit breaker theo miền lỗi nhỏ nhất hữu ích.
- Định nghĩa một capability contract có phiên bản cho mỗi route alias.
- Chặn chuyển đổi tự động sau khi output một phần đã bắt đầu.
- Thêm idempotency và reconciliation cho các tool phía ghi.
- Ghi lại lý do chọn route và kết quả cuối cùng của tác vụ.
- Chèn các lỗi transport, overload, contract, streaming, và side-effect.
- Canary failover tương đương trước khi bật fallback giữa các model.
- Thêm kill switch cho từng target và chính sách fallback.
FAQ
Fallback routing cho LLM API là gì?
Fallback routing cho LLM API là một chính sách độ tin cậy, chọn một model hoặc nhà cung cấp đủ điều kiện khác khi route ưu tiên không thể hoàn tất một yêu cầu. Fallback an toàn kiểm tra replay safety, khả năng tương thích về năng lực, tình trạng circuit, ngân sách độ trễ, và trạng thái output trước khi chuyển đổi.
Sự khác nhau giữa LLM retry và fallback là gì?
Retry là lặp lại yêu cầu đối với cùng một mục tiêu. Failover chuyển sang hạ tầng tương đương trong khi vẫn giữ nguyên hợp đồng mô hình logic. Fallback giữa các mô hình sẽ thay đổi mô hình và vì vậy đòi hỏi kiểm thử khả năng tương thích và chất lượng chặt chẽ hơn.
LLM API có nên retry mọi lỗi 429 hoặc 5xx không?
Không. Việc retry nên được giới hạn bởi deadline end-to-end, số lần thử tối đa, chính sách backoff, trạng thái circuit, và kiểm tra replay-safety. Failover sang một mục tiêu tương đương có thể tốt hơn là gọi lặp đi lặp lại một mục tiêu đang không khỏe.
LLM router có thể chuyển mô hình trong lúc đang stream không?
Không một cách minh bạch sau khi đầu ra đã đến được client. Mặc định an toàn là kết thúc stream rõ ràng hoặc bắt đầu một lượt ứng dụng mới. Nối các đầu ra một phần từ các mô hình khác nhau có thể làm hỏng hợp đồng phản hồi.
Khi nào nên vô hiệu hóa fallback giữa các mô hình?
Vô hiệu hóa khi mô hình thay thế không thể giữ nguyên các tools bắt buộc, đầu ra có cấu trúc, giới hạn ngữ cảnh, hành vi an toàn, ngưỡng chất lượng, hoặc các đảm bảo về side effect. Cũng nên vô hiệu hóa replay tự động sau khi đã có đầu ra một phần hoặc khi việc thực thi tool chưa chắc chắn.
Một yêu cầu của LLM nên có bao nhiêu lần fallback?
Không có một con số सार्व quát. Hãy dùng số lần thử giới hạn nhỏ nhất phù hợp với ngân sách độ trễ của sản phẩm và bằng chứng kiểm thử. Router nên dừng lại khi deadline còn lại không đủ để thực hiện thêm một lần thử có ích.
Fallback đáng tin cậy không có nghĩa là “thử mọi thứ.” Nó có nghĩa là làm cho hành động tiếp theo trở nên rõ ràng, tương thích, an toàn khi replay, có thể quan sát, và dễ dừng lại.



