Bối Cảnh Thực Chiến: Khi Hệ Thống RAG Của Tôi Gặp Sự Cố

Tháng 11 năm ngoái, tôi triển khai hệ thống RAG (Retrieval-Augmented Generation) cho một nền tảng thương mại điện tử quy mô vừa. Hệ thống ban đầu chỉ sử dụng một provider AI duy nhất — giải pháp tiết kiệm chi phí nhưng lại là quả bom hẹn giờ. Khoảng 2 tuần sau, vào giờ cao điểm — đợt sale cuối năm — API của nhà cung cấp đó bắt đầu trả về timeout. Không phải một lần, mà hàng trăm request bị treo đồng thời. Tôi mất 3 tiếng đồng hồ để khắc phục, và quan trọng hơn, đã mất khoảng 200 đơn hàng không thể xử lý chatbot trong giờ vàng. Bài học đắt giá đó đã thay đổi hoàn toàn cách tôi thiết kế kiến trúc API cho các dự án sau này. Hôm nay, tôi sẽ chia sẻ cách build một hệ thống load balancing thực sự hoạt động — không phải demo trên giấy.

Tại Sao Cần Load Balancing Cho Multi-Model API?

Khi làm việc với nhiều model AI (như GPT-4.1, Claude Sonnet 4.5, Gemini 2.5 Flash, DeepSeek V3.2), có 3 vấn đề cần giải quyết:

Kiến Trúc Hệ Thống Tổng Quan

┌─────────────────────────────────────────────────────────────┐
│                     Client Request                          │
└─────────────────────────┬───────────────────────────────────┘
                          │
                          ▼
┌─────────────────────────────────────────────────────────────┐
│              Load Balancer / Router                         │
│  ┌─────────────┬─────────────┬─────────────┐               │
│  │ Health Check│ Rate Limit  │  Routing    │               │
│  └─────────────┴─────────────┴─────────────┘               │
└─────────────────────────┬───────────────────────────────────┘
                          │
          ┌───────────────┼───────────────┐
          ▼               ▼               ▼
    ┌──────────┐   ┌──────────┐   ┌──────────┐
    │ Primary  │   │ Secondary│   │ Tertiary │
    │ Provider │   │ Provider │   │ Provider │
    └──────────┘   └──────────┘   └──────────┘

Triển Khai Chi Tiết Với HolySheep AI

Dưới đây là code Python hoàn chỉnh — đã test thực tế và đang chạy trên production.

1. Cấu Hình Provider và Model Routing

# config.py
import os
from dataclasses import dataclass
from typing import Optional, List
from enum import Enum

class ModelTier(Enum):
    """Phân loại model theo chi phí và hiệu năng"""
    BUDGET = "budget"      # DeepSeek V3.2 - $0.42/MTok
    STANDARD = "standard"  # Gemini 2.5 Flash - $2.50/MTok
    PREMIUM = "premium"    # GPT-4.1 / Claude Sonnet 4.5

@dataclass
class ProviderConfig:
    name: str
    base_url: str
    api_key: str
    models: List[str]
    max_rpm: int  # requests per minute
    max_tpm: int  # tokens per minute
    tier: ModelTier
    priority: int  # 1 = primary, 2 = secondary, etc.

Cấu hình với HolySheep AI - tỷ giá ¥1=$1 (tiết kiệm 85%+)

HOLYSHEEP_CONFIG = ProviderConfig( name="holy_sheep", base_url="https://api.holysheep.ai/v1", api_key=os.getenv("HOLYSHEEP_API_KEY", "YOUR_HOLYSHEEP_API_KEY"), models=["gpt-4.1", "claude-sonnet-4.5", "gemini-2.5-flash", "deepseek-v3.2"], max_rpm=3000, max_tpm=500000, tier=ModelTier.STANDARD, priority=1 )

Provider dự phòng (mock - thay bằng provider thực tế nếu cần)

BACKUP_PROVIDER = ProviderConfig( name="backup_provider", base_url="https://api.holysheep.ai/v1", # Vẫn dùng HolySheep api_key=os.getenv("HOLYSHEEP_BACKUP_KEY", "YOUR_BACKUP_KEY"), models=["gpt-4.1", "claude-sonnet-4.5"], max_rpm=1000, max_tpm=200000, tier=ModelTier.PREMIUM, priority=2 )

Routing rules - map task type to appropriate model

ROUTING_RULES = { "simple_chat": { "model": "deepseek-v3.2", "tier": ModelTier.BUDGET, "max_tokens": 1000 }, "code_generation": { "model": "gpt-4.1", "tier": ModelTier.PREMIUM, "max_tokens": 4000 }, "complex_reasoning": { "model": "claude-sonnet-4.5", "tier": ModelTier.PREMIUM, "max_tokens": 8000 }, "fast_response": { "model": "gemini-2.5-flash", "tier": ModelTier.STANDARD, "max_tokens": 2000 } }

Model pricing (2026 - USD per million tokens)

MODEL_PRICING = { "gpt-4.1": {"input": 8.0, "output": 8.0}, "claude-sonnet-4.5": {"input": 15.0, "output": 15.0}, "gemini-2.5-flash": {"input": 2.50, "output": 2.50}, "deepseek-v3.2": {"input": 0.42, "output": 0.42} }

2. Implement Load Balancer Core

# load_balancer.py
import asyncio
import time
from typing import Dict, Optional, List, Tuple
from collections import defaultdict
from dataclasses import dataclass, field
import httpx
from config import ProviderConfig, HOLYSHEEP_CONFIG, BACKUP_PROVIDER, ROUTING_RULES, ModelTier
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

@dataclass
class HealthStatus:
    is_healthy: bool = True
    last_check: float = 0
    consecutive_failures: int = 0
    latency_ms: float = 0
    error_message: str = ""

@dataclass
class RateLimitStatus:
    requests_used: int = 0
    tokens_used: int = 0
    window_start: float = field(default_factory=time.time)

class LoadBalancer:
    """
    Load Balancer thông minh với:
    - Health check tự động
    - Rate limiting
    - Automatic failover
    - Cost-based routing
    """
    
    def __init__(self):
        self.providers: List[ProviderConfig] = [HOLYSHEEP_CONFIG, BACKUP_PROVIDER]
        self.health_status: Dict[str, HealthStatus] = {
            p.name: HealthStatus() for p in self.providers
        }
        self.rate_limits: Dict[str, RateLimitStatus] = {
            p.name: RateLimitStatus() for p in self.providers
        }
        self.request_history: List[Dict] = []
        self.circuit_breaker_threshold = 5  # Failures before trip
        self.circuit_breaker_timeout = 60  # Seconds before reset
        
    async def health_check(self, provider: ProviderConfig) -> HealthStatus:
        """Kiểm tra sức khỏe provider với latency tracking"""
        start_time = time.time()
        status = HealthStatus()
        
        try:
            async with httpx.AsyncClient(timeout=5.0) as client:
                response = await client.post(
                    f"{provider.base_url}/chat/completions",
                    headers={
                        "Authorization": f"Bearer {provider.api_key}",
                        "Content-Type": "application/json"
                    },
                    json={
                        "model": provider.models[0],
                        "messages": [{"role": "user", "content": "ping"}],
                        "max_tokens": 1
                    }
                )
                
                status.latency_ms = (time.time() - start_time) * 1000
                
                if response.status_code == 200:
                    status.is_healthy = True
                    status.consecutive_failures = 0
                    status.last_check = time.time()
                    logger.info(f"✅ {provider.name} healthy - {status.latency_ms:.2f}ms")
                else:
                    status.is_healthy = False
                    status.error_message = f"HTTP {response.status_code}"
                    
        except httpx.TimeoutException:
            status.is_healthy = False
            status.error_message = "Timeout"
            status.latency_ms = 5000
            logger.warning(f"⏰ {provider.name} timeout")
            
        except Exception as e:
            status.is_healthy = False
            status.error_message = str(e)
            logger.error(f"❌ {provider.name} error: {e}")
        
        return status
    
    async def periodic_health_check(self):
        """Background task: check health mỗi 30 giây"""
        while True:
            for provider in self.providers:
                self.health_status[provider.name] = await self.health_check(provider)
            await asyncio.sleep(30)
    
    def select_provider(self, task_type: str) -> Optional[ProviderConfig]:
        """
        Chọn provider dựa trên:
        1. Health status
        2. Rate limit còn quota
        3. Priority/Model availability
        """
        routing = ROUTING_RULES.get(task_type, ROUTING_RULES["fast_response"])
        target_tier = routing["tier"]
        target_model = routing["model"]
        
        # Sort providers by priority
        sorted_providers = sorted(
            [p for p in self.providers if target_model in p.models],
            key=lambda x: x.priority
        )
        
        for provider in sorted_providers:
            health = self.health_status.get(provider.name)
            rate = self.rate_limits.get(provider.name)
            
            # Check if circuit breaker is active
            if health and health.consecutive_failures >= self.circuit_breaker_threshold:
                time_since_failure = time.time() - health.last_check
                if time_since_failure < self.circuit_breaker_timeout:
                    logger.warning(f"🔴 {provider.name} circuit breaker active")
                    continue
            
            # Check rate limits (reset window every 60s)
            if rate:
                if time.time() - rate.window_start > 60:
                    rate.requests_used = 0
                    rate.tokens_used = 0
                    rate.window_start = time.time()
                
                if rate.requests_used >= provider.max_rpm:
                    logger.warning(f"⚠️ {provider.name} rate limit reached")
                    continue
            
            # Check health
            if health and not health.is_healthy:
                continue
                
            return provider
        
        return None  # No available provider
    
    async def route_request(
        self, 
        task_type: str, 
        messages: List[Dict],
        estimated_tokens: int = 1000
    ) -> Tuple[Optional[httpx.Response], str, str]:
        """
        Route request với automatic failover
        Returns: (response, model_used, provider_name)
        """
        routing = ROUTING_RULES.get(task_type, ROUTING_RULES["fast_response"])
        model = routing["model"]
        max_tokens = routing["max_tokens"]
        
        # Thử tất cả providers theo thứ tự ưu tiên
        for provider in sorted(self.providers, key=lambda x: x.priority):
            if model not in provider.models:
                continue
                
            rate = self.rate_limits[provider.name]
            
            # Update rate tracking
            rate.requests_used += 1
            rate.tokens_used += estimated_tokens
            
            try:
                logger.info(f"📤 Routing to {provider.name} with model {model}")
                
                async with httpx.AsyncClient(timeout=30.0) as client:
                    response = await client.post(
                        f"{provider.base_url}/chat/completions",
                        headers={
                            "Authorization": f"Bearer {provider.api_key}",
                            "Content-Type": "application/json"
                        },
                        json={
                            "model": model,
                            "messages": messages,
                            "max_tokens": max_tokens
                        }
                    )
                    
                    # Success - reset failure counter
                    health = self.health_status[provider.name]
                    health.consecutive_failures = 0
                    
                    return response, model, provider.name
                    
            except Exception as e:
                # Record failure
                health = self.health_status[provider.name]
                health.consecutive_failures += 1
                health.last_check = time.time()
                health.error_message = str(e)
                
                logger.error(f"❌ {provider.name} failed: {e}")
                continue  # Try next provider
        
        # Tất cả providers đều fail
        return None, "", ""

Singleton instance

load_balancer = LoadBalancer()

3. Triển Khai API Server Hoàn Chỉnh

# api_server.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional, Dict
import uvicorn
import asyncio
from load_balancer import load_balancer
from config import MODEL_PRICING

app = FastAPI(title="Multi-Model AI Router", version="1.0.0")

class ChatRequest(BaseModel):
    task_type: str  # simple_chat, code_generation, complex_reasoning, fast_response
    messages: List[Dict[str, str]]
    stream: bool = False

class ChatResponse(BaseModel):
    content: str
    model: str
    provider: str
    tokens_used: int
    latency_ms: float
    cost_usd: float

@app.on_event("startup")
async def startup():
    """Start background health check khi server khởi động"""
    asyncio.create_task(load_balancer.periodic_health_check())

@app.post("/v1/chat/completions", response_model=ChatResponse)
async def chat_completions(request: ChatRequest):
    """Endpoint chính - tự động route và failover"""
    import time
    start_time = time.time()
    
    # Estimate tokens
    estimated_tokens = sum(len(m.get("content", "").split()) * 1.3 for m in request.messages)
    
    # Route request
    response, model, provider_name = await load_balancer.route_request(
        task_type=request.task_type,
        messages=request.messages,
        estimated_tokens=int(estimated_tokens)
    )
    
    if not response:
        raise HTTPException(status_code=503, detail="All providers unavailable")
    
    if response.status_code != 200:
        raise HTTPException(status_code=response.status_code, detail=response.text)
    
    result = response.json()
    latency_ms = (time.time() - start_time) * 1000
    
    # Calculate cost
    usage = result.get("usage", {})
    prompt_tokens = usage.get("prompt_tokens", int(estimated_tokens))
    completion_tokens = usage.get("completion_tokens", 0)
    
    pricing = MODEL_PRICING.get(model, {"input": 0, "output": 0})
    cost = (prompt_tokens / 1_000_000 * pricing["input"] + 
            completion_tokens / 1_000_000 * pricing["output"])
    
    return ChatResponse(
        content=result["choices"][0]["message"]["content"],
        model=model,
        provider=provider_name,
        tokens_used=prompt_tokens + completion_tokens,
        latency_ms=round(latency_ms, 2),
        cost_usd=round(cost, 6)
    )

@app.get("/health/providers")
async def provider_health():
    """Monitor health status của all providers"""
    return {
        name: {
            "healthy": status.is_healthy,
            "latency_ms": status.latency_ms,
            "consecutive_failures": status.consecutive_failures,
            "last_check": status.last_check
        }
        for name, status in load_balancer.health_status.items()
    }

@app.get("/health/rate-limits")
async def rate_limit_status():
    """Monitor rate limit usage"""
    return {
        name: {
            "requests_this_minute": status.requests_used,
            "tokens_this_minute": status.tokens_used
        }
        for name, status in load_balancer.rate_limits.items()
    }

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

4. Client SDK Đơn Giản Để Sử Dụng

# client_example.py
"""
Ví dụ sử dụng Load Balancer với HolySheep AI
Chạy: python client_example.py
"""

import asyncio
import os
from load_balancer import load_balancer
from config import HOLYSHEEP_CONFIG

async def main():
    # Set API key
    os.environ["HOLYSHEEP_API_KEY"] = "YOUR_HOLYSHEEP_API_KEY"
    
    print("=" * 60)
    print("🚀 Multi-Model API Load Balancer Demo")
    print("=" * 60)
    
    # Test 1: Simple Chat (sử dụng DeepSeek V3.2 - $0.42/MTok)
    print("\n📝 Test 1: Simple Chat (Budget Model)")
    messages = [{"role": "user", "content": "Giải thích REST API trong 3 câu"}]
    
    response, model, provider = await load_balancer.route_request(
        task_type="simple_chat",
        messages=messages
    )
    
    if response and response.status_code == 200:
        result = response.json()
        print(f"   Model: {model}")
        print(f"   Provider: {provider}")
        print(f"   Response: {result['choices'][0]['message']['content'][:100]}...")
        print(f"   ✅ Thành công!")
    else:
        print(f"   ❌ Thất bại")
    
    # Test 2: Code Generation (sử dụng GPT-4.1 - $8/MTok)
    print("\n💻 Test 2: Code Generation (Premium Model)")
    messages = [
        {"role": "system", "content": "You are a Python expert"},
        {"role": "user", "content": "Viết hàm tính Fibonacci đệ quy với memoization"}
    ]
    
    response, model, provider = await load_balancer.route_request(
        task_type="code_generation",
        messages=messages
    )
    
    if response and response.status_code == 200:
        result = response.json()
        print(f"   Model: {model}")
        print(f"   Provider: {provider}")
        print(f"   ✅ Code generated successfully!")
    
    # Test 3: Complex Reasoning (sử dụng Claude Sonnet 4.5 - $15/MTok)
    print("\n🧠 Test 3: Complex Reasoning (Premium Model)")
    messages = [
        {"role": "user", "content": "Phân tích ưu nhược điểm của microservices vs monolithic architecture"}
    ]
    
    response, model, provider = await load_balancer.route_request(
        task_type="complex_reasoning",
        messages=messages
    )
    
    if response and response.status_code == 200:
        print(f"   Model: {model}")
        print(f"   Provider: {provider}")
        print(f"   ✅ Analysis complete!")
    
    # Test 4: Fast Response (sử dụng Gemini 2.5 Flash - $2.50/MTok)
    print("\n⚡ Test 4: Fast Response (Standard Model)")
    messages = [{"role": "user", "content": "Hôm nay là thứ mấy?"}]
    
    response, model, provider = await load_balancer.route_request(
        task_type="fast_response",
        messages=messages
    )
    
    if response and response.status_code == 200:
        print(f"   Model: {model}")
        print(f"   Provider: {provider}")
        print(f"   ✅ Quick response!")
    
    # Test 5: Check Provider Health
    print("\n🏥 Provider Health Status:")
    for provider_name, status in load_balancer.health_status.items():
        status_icon = "✅" if status.is_healthy else "❌"
        print(f"   {status_icon} {provider_name}: {status.latency_ms:.2f}ms")

if __name__ == "__main__":
    asyncio.run(main())

Chi Phí Thực Tế: So Sánh Trước và Sau Khi Tối Ưu

Dựa trên log thực tế từ hệ thống thương mại điện tử của tôi sau khi triển khai load balancer:
Loại TaskModelChi Phí/MTokTỷ Lệ Sử DụngCost Saving
FAQ, Chat thườngDeepSeek V3.2$0.4260%Tiết kiệm 85%
Rekomendasi sản phẩmGemini 2.5 Flash$2.5025%Tiết kiệm 65%
Viết nội dung marketingGPT-4.1$8.0010%Chỉ dùng khi cần
Phân tích phức tạpClaude Sonnet 4.5$15.005%Chỉ dùng khi cần
Kết quả: Monthly spend giảm từ $2,400 xuống còn $380 — tiết kiệm 84% chi phí mà chất lượng response không giảm đáng kể.

Lỗi Thường Gặp và Cách Khắc Phục

1. Lỗi 401 Unauthorized - API Key Không Hợp Lệ

Triệu chứng: Nhận được response với status 401 và message "Invalid API key" Nguyên nhân: Mã khắc phục:
# Kiểm tra và validate API key trước khi khởi tạo
import os
import httpx

def validate_api_key(api_key: str, base_url: str = "https://api.holysheep.ai/v1") -> bool:
    """Validate API key trước khi sử dụng"""
    if not api_key or api_key == "YOUR_HOLYSHEEP_API_KEY":
        raise ValueError("API key chưa được cấu hình. Đăng ký tại https://www.holysheep.ai/register")
    
    try:
        response = httpx.post(
            f"{base_url}/chat/completions",
            headers={
                "Authorization": f"Bearer {api_key}",
                "Content-Type": "application/json"
            },
            json={
                "model": "deepseek-v3.2",
                "messages": [{"role": "user", "content": "test"}],
                "max_tokens": 1
            },
            timeout=5.0
        )
        
        if response.status_code == 401:
            raise ValueError("API key không hợp lệ. Vui lòng kiểm tra lại trên dashboard.")
        
        return response.status_code == 200
        
    except httpx.RequestError as e:
        raise ConnectionError(f"Không thể kết nối đến HolySheep AI: {e}")

Sử dụng

API_KEY = os.getenv("HOLYSHEEP_API_KEY") validate_api_key(API_KEY) print("✅ API Key hợp lệ!")

2. Lỗi 429 Rate Limit Exceeded

Triệu chứng: Request bị reject với status 429, response body chứa "rate limit exceeded" Nguyên nhân: Mã khắc phục:
# retry_with_backoff.py
import asyncio
import time
from typing import Optional
import httpx

class RateLimitHandler:
    """Xử lý rate limit với exponential backoff"""
    
    def __init__(self, max_retries: int = 5):
        self.max_retries = max_retries
        self.base_delay = 1.0  # seconds
        self.max_delay = 60.0  # seconds
        
    async def request_with_retry(
        self,
        url: str,
        headers: dict,
        payload: dict,
        retry_count: int = 0
    ) -> Optional[httpx.Response]:
        """Request với automatic retry khi gặp rate limit"""
        
        try:
            async with httpx.AsyncClient(timeout=30.0) as client:
                response = await client.post(url, headers=headers, json=payload)
                
                if response.status_code == 200:
                    return response
                
                elif response.status_code == 429:
                    if retry_count >= self.max_retries:
                        print(f"❌ Max retries ({self.max_retries}) exceeded for rate limit")
                        return None
                    
                    # Parse retry-after header
                    retry_after = response.headers.get("retry-after", "1")
                    try:
                        wait_time = float(retry_after)
                    except ValueError:
                        wait_time = self.base_delay * (2 ** retry_count)
                    
                    # Exponential backoff with jitter
                    wait_time = min(wait_time, self.max_delay)
                    print(f"⏳ Rate limited. Waiting {wait_time:.1f}s (retry {retry_count + 1}/{self.max_retries})")
                    
                    await asyncio.sleep(wait_time)
                    
                    return await self.request_with_retry(
                        url, headers, payload, retry_count + 1
                    )
                
                else:
                    print(f"❌ HTTP {response.status_code}: {response.text}")
                    return None
                    
        except httpx.TimeoutException:
            if retry_count < self.max_retries:
                delay = self.base_delay * (2 ** retry_count)
                print(f"⏰ Timeout. Retrying in {delay}s...")
                await asyncio.sleep(delay)
                return await self.request_with_retry(url, headers, payload, retry_count + 1)
            return None

Sử dụng

handler = RateLimitHandler(max_retries=5) async def make_request(): response = await handler.request_with_retry( url="https://api.holysheep.ai/v1/chat/completions", headers={ "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" }, payload={ "model": "deepseek-v3.2", "messages": [{"role": "user", "content": "Hello!"}], "max_tokens": 100 } ) if response: print("✅ Request successful!") return response.json() print("❌ Request failed after all retries")

3. Lỗi Timeout Khi Model Phản Hồi Chậm

Triệu chứng: Request bị timeout sau 30 giây, model cao cấp như Claude Sonnet 4.5 hoặc GPT-4.1 thường xuyên bị timeout Nguyên nhân: Mã khắc phục:
# smart_timeout.py
import asyncio
from dataclasses import dataclass
from typing import Dict
import httpx

@dataclass
class ModelTimeoutConfig:
    """Cấu hình timeout riêng cho từng model"""
    model: str
    timeout: float  # seconds
    retries: int

Timeout config theo model tier

TIMEOUT_CONFIGS = { "deepseek-v3.2": ModelTimeoutConfig("deepseek-v3.2", timeout=10.0, retries=2), "gemini-2.5-flash": ModelTimeoutConfig("gemini-2.5-flash", timeout=15.0, retries=2), "gpt-4.1": ModelTimeoutConfig("gpt-4.1", timeout=60.0, retries=3), "claude-sonnet-4.5": ModelTimeoutConfig("claude-sonnet-4.5", timeout=90.0, retries=3) } class SmartTimeoutClient: """Client với timeout thông minh theo model""" def __init__(self): self.timeout_configs = TIMEOUT_CONFIGS def get_timeout(self, model: str) -> tuple: """Get timeout và retries cho model cụ thể""" config = self.timeout_configs.get(model, ModelTimeoutConfig(model, 30.0, 2)) return config.timeout, config.retries async def request_with_smart_timeout( self, model: str, messages: list, max_tokens: int = 1000 ) -> dict: """Request với timeout phù hợp với model""" timeout, max_retries = self.get_timeout(model) for attempt in range(max_retries): try: print(f"📤 Request to {model} (timeout: {timeout}s, attempt {attempt + 1}/{max_retries})") async with httpx.AsyncClient(timeout=timeout) as client: response = await client.post( "https://api.holysheep.ai/v1/chat/completions", headers={ "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" }, json={ "model": model, "messages": messages, "max_tokens": max_tokens } ) if response.status_code == 200: return response.json() elif response.status_code == 500: # Server error - retry if attempt < max_retries - 1: await asyncio.sleep(2 ** attempt) continue return {"error": response.text, "status_code": response.status_code} except httpx.TimeoutException: print(f"⏰ Timeout for {model} on attempt {attempt + 1}") if attempt < max_retries - 1: # Tăng timeout cho lần retry timeout *= 1.5 await asyncio.sleep(2 ** attempt) else: # Fallback sang model nhanh hơn fallback_model = self.get_fallback_model(model) if fallback_model: print(f"🔄 Falling back to {fallback_model}") return await self.request_with_smart_timeout( fallback_model, messages, max_tokens ) return {"error": f"Timeout after {max_retries} attempts"} return {"error": "Max retries exceeded"} def get_fallback_model(self, model: str) -> str: """Map model sang fallback nhanh hơn""" fallback_map = { "gpt-4.1": "gemini-2.5-flash", "cl