Nếu bạn đang bắt đầu hành trình lập trình với AI API, chắc hẳn bạn đã từng gặp những lần gọi API thất bại vì mạng chậm, server quá tải, hoặc đơn giản là kết nối bị gián đoạn. Trong bài viết này, mình sẽ chia sẻ cách mình xây dựng hệ thống xử lý lỗi thông minh với retry hookscircuit breaker — hai kỹ thuật cứu cánh giúp ứng dụng của bạn hoạt động ổn định ngay cả khi API gặp sự cố.

Tại sao cần Retry và Circuit Breaker?

Khi mới tìm hiểu về API, mình từng nghĩ đơn giản: gọi API, nhận kết quả, xong. Nhưng thực tế hoàn toàn khác. Mạng internet có thể chập chờn, server AI có lúc quá tải (đặc biệt vào giờ cao điểm), và nếu bạn cứ gọi đi gọi lại liên tục khi server đang down, bạn không những tốn tiền mà còn có thể bị chặn IP.

Retry (thử lại) giúp tự động gửi lại yêu cầu khi gặp lỗi tạm thời. Circuit Breaker (cầu dao) giúp "ngắt điện" khi API liên tục thất bại, tránh làm quá tải hệ thống. Hai kỹ thuật này kết hợp với nhau tạo thành một bộ đôi hoàn hảo cho bất kỳ ứng dụng nào sử dụng AI API.

Chuẩn bị môi trường

Trước tiên, bạn cần đăng ký tài khoản HolyShehe AI — nền tảng API AI với chi phí cực kỳ cạnh tranh, chỉ từ $0.42/MTok với DeepSeek V3.2, tiết kiệm đến 85% so với các nhà cung cấp phương Tây. Ngoài ra, HolySheep hỗ trợ thanh toán qua WeChat Pay và Alipay, độ trễ dưới 50ms, và tặng tín dụng miễn phí khi đăng ký. Đăng ký tại đây để nhận ngay $5 credit.

Cài đặt thư viện cần thiết

pip install requests tenacity httpx

tenacity: thư viện retry mạnh mẽ

httpx: HTTP client hỗ trợ async

requests: thư viện HTTP cơ bản

Retry Hooks — Tự động thử lại khi gặp lỗi

Mình sẽ hướng dẫn bạn cách cài đặt retry thông minh với thư viện tenacity. Điều đặc biệt là bạn có thể hook vào các giai đoạn khác nhau của quá trình retry: trước khi thử, sau mỗi lần thất bại, hoặc khi thành công.

import requests
from tenacity import (
    retry, stop_after_attempt, wait_exponential,
    retry_if_exception_type, before_sleep_log
)
import logging
import time

Cấu hình logging để theo dõi quá trình retry

logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) class HolySheepAIClient: def __init__(self, api_key: str): self.api_key = api_key self.base_url = "https://api.holysheep.ai/v1" def _make_request(self, endpoint: str, payload: dict) -> dict: """Gửi yêu cầu đến HolySheep AI API""" headers = { "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json" } response = requests.post( f"{self.base_url}/{endpoint}", headers=headers, json=payload, timeout=30 ) response.raise_for_status() return response.json() @retry( stop=stop_after_attempt(5), # Thử tối đa 5 lần wait=wait_exponential(multiplier=1, min=2, max=30), # Đợi 2-30 giây, tăng theo cấp số nhân retry=retry_if_exception_type((requests.exceptions.Timeout, requests.exceptions.ConnectionError, requests.exceptions.HTTPError)), before_sleep=before_sleep_log(logger, logging.WARNING), reraise=True ) def chat_completion(self, messages: list, model: str = "deepseek-chat") -> dict: """Gọi API chat completion với retry tự động""" try: payload = { "model": model, "messages": messages, "temperature": 0.7, "max_tokens": 1000 } return self._make_request("chat/completions", payload) except requests.exceptions.HTTPError as e: # Không retry nếu là lỗi 4xx (lỗi client) if 400 <= e.response.status_code < 500: raise # Retry nếu là lỗi 5xx (lỗi server) raise

Cách sử dụng

client = HolySheepAIClient(api_key="YOUR_HOLYSHEEP_API_KEY") messages = [{"role": "user", "content": "Xin chào, hãy giới thiệu về HolySheep AI"}] try: response = client.chat_completion(messages, model="deepseek-chat") print(f"Kết quả: {response['choices'][0]['message']['content']}") except Exception as e: print(f"Lỗi sau khi retry 5 lần: {e}")

Custom Retry Hook — Ghi log và theo dõi chi phí

Điều mình thích nhất ở tenacity là khả năng tùy chỉnh hooks. Bạn có thể gắn hành động vào bất kỳ giai đoạn nào: trước khi retry, sau khi thất bại, hoặc khi thành công. Mình thường dùng tính năng này để theo dõi chi phí API — mỗi lần gọi thành công, mình sẽ log số tokens đã sử dụng để tính toán chi phí thực tế.

from tenacity import (
    retry, stop_after_attempt, wait_exponential,
    retry_if_exception_type, after
)
from dataclasses import dataclass
from typing import Optional
import logging

logger = logging.getLogger(__name__)

Định nghĩa chi phí cho từng model (USD per 1M tokens)

MODEL_COSTS = { "gpt-4.1": 8.0, "claude-sonnet-4.5": 15.0, "gemini-2.5-flash": 2.50, "deepseek-chat": 0.42, # Siêu rẻ với HolySheep } @dataclass class UsageTracker: """Theo dõi sử dụng và chi phí API""" total_input_tokens: int = 0 total_output_tokens: int = 0 total_cost_usd: float = 0.0 retry_count: int = 0 last_error: Optional[str] = None class SmartRetryClient: def __init__(self, api_key: str): self.api_key = api_key self.base_url = "https://api.holysheep.ai/v1" self.usage = UsageTracker() def _calculate_cost(self, model: str, usage: dict) -> float: """Tính chi phí dựa trên số tokens""" input_cost = (usage.get('prompt_tokens', 0) / 1_000_000) * MODEL_COSTS.get(model, 1) output_cost = (usage.get('completion_tokens', 0) / 1_000_000) * MODEL_COSTS.get(model, 1) return input_cost + output_cost def _on_retry(self, attempt_state): """Hook được gọi mỗi khi retry xảy ra""" self.usage.retry_count += 1 self.usage.last_error = str(attempt_state.outcome.exception()) logger.warning( f"🔄 Retry lần {self.usage.retry_count}: " f"Lỗi: {self.usage.last_error}" ) def _on_success(self, attempt_state): """Hook được gọi khi request thành công""" logger.info(f"✅ Request thành công sau {self.usage.retry_count} lần retry") # Log chi phí if hasattr(attempt_state.result, 'usage'): usage = attempt_state.result.usage cost = self._calculate_cost(attempt_state.kwargs.get('model', 'deepseek-chat'), usage) self.usage.total_input_tokens += usage.get('prompt_tokens', 0) self.usage.total_output_tokens += usage.get('completion_tokens', 0) self.usage.total_cost_usd += cost logger.info( f"💰 Chi phí lần này: ${cost:.4f} | " f"Tổng cộng: ${self.usage.total_cost_usd:.2f}" ) @retry( stop=stop_after_attempt(5), wait=wait_exponential(multiplier=1, min=2, max=30), retry=retry_if_exception_type((requests.exceptions.Timeout, requests.exceptions.ConnectionError)), after=_on_retry, after=_on_success ) def call_api(self, model: str, messages: list) -> dict: """Gọi API với tracking chi phí""" headers = { "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json" } payload = { "model": model, "messages": messages, "temperature": 0.7 } response = requests.post( f"{self.base_url}/chat/completions", headers=headers, json=payload, timeout=30 ) response.raise_for_status() return response.json()

Sử dụng với tracking chi phí

client = SmartRetryClient(api_key="YOUR_HOLYSHEEP_API_KEY")

DeepSeek V3.2 chỉ $0.42/MTok - tiết kiệm 85%+

response = client.call_api("deepseek-chat", [ {"role": "user", "content": "Giải thích retry mechanism"} ]) print(f"Tổng chi phí: ${client.usage.total_cost_usd:.4f}") print(f"Tổng tokens: {client.usage.total_input_tokens + client.usage.total_output_tokens:,}")

Circuit Breaker — Ngăn chặn thảm họa

Retry rất tốt, nhưng nếu API server bị down hoàn toàn trong 30 phút? Nếu bạn cứ retry liên tục, bạn sẽ tiêu tốn hàng triệu tokens và có thể bị banned. Đó là lý do cần Circuit Breaker — một "cầu dao" sẽ tự động ngắt khi API thất bại quá nhiều lần liên tiếp, cho server "nghỉ ngơi" và tránh tốn chi phí không cần thiết.

import time
from enum import Enum
from threading import Lock
from typing import Callable, Any
import requests

class CircuitState(Enum):
    CLOSED = "closed"      # Bình thường, cho phép request
    OPEN = "open"          # Đang bảo trì, chặn request
    HALF_OPEN = "half_open"  # Thử lại một lần

class CircuitBreaker:
    """
    Circuit Breaker đơn giản với 3 trạng thái:
    - CLOSED: Hoạt động bình thường
    - OPEN: Quá nhiều lỗi, chặn request tạm thời
    - HALF_OPEN: Thử cho 1 request để kiểm tra
    """
    
    def __init__(
        self,
        failure_threshold: int = 5,      # Mở cầu dao sau 5 lỗi liên tiếp
        recovery_timeout: int = 60,      # Chờ 60 giây trước khi thử lại
        expected_exception: type = Exception
    ):
        self.failure_threshold = failure_threshold
        self.recovery_timeout = recovery_timeout
        self.expected_exception = expected_exception
        
        self.failure_count = 0
        self.last_failure_time = None
        self.state = CircuitState.CLOSED
        self._lock = Lock()
    
    def call(self, func: Callable, *args, **kwargs) -> Any:
        """Thực thi hàm với circuit breaker protection"""
        with self._lock:
            if self.state == CircuitState.OPEN:
                # Kiểm tra đã đủ thời gian chưa
                if time.time() - self.last_failure_time >= self.recovery_timeout:
                    self.state = CircuitState.HALF_OPEN
                    print("🔔 Circuit: OPEN → HALF_OPEN (thử nghiệm)")
                else:
                    raise Exception(
                        f"Circuit Breaker đang OPEN. "
                        f"Thử lại sau {self.recovery_timeout - (time.time() - self.last_failure_time):.0f}s"
                    )
        
        try:
            result = func(*args, **kwargs)
            self._on_success()
            return result
        except self.expected_exception as e:
            self._on_failure()
            raise
    
    def _on_success(self):
        """Xử lý khi request thành công"""
        with self._lock:
            if self.state == CircuitState.HALF_OPEN:
                print("✅ Circuit: HALF_OPEN → CLOSED (khôi phục)")
            self.failure_count = 0
            self.state = CircuitState.CLOSED
    
    def _on_failure(self):
        """Xử lý khi request thất bại"""
        with self._lock:
            self.failure_count += 1
            self.last_failure_time = time.time()
            
            if self.failure_count >= self.failure_threshold:
                self.state = CircuitState.OPEN
                print(f"⚠️ Circuit: CLOSED → OPEN (quá nhiều lỗi)")

class HolySheepCircuitBreakerClient:
    """Client kết hợp Retry + Circuit Breaker"""
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.holysheep.ai/v1"
        
        # Khởi tạo circuit breaker với ngưỡng 3 lỗi, chờ 30 giây
        self.circuit_breaker = CircuitBreaker(
            failure_threshold=3,
            recovery_timeout=30
        )
    
    def _do_request(self, messages: list, model: str) -> dict:
        """Thực hiện request thực tế"""
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        payload = {
            "model": model,
            "messages": messages,
            "temperature": 0.7
        }
        
        # Thử 3 lần với exponential backoff
        for attempt in range(3):
            try:
                response = requests.post(
                    f"{self.base_url}/chat/completions",
                    headers=headers,
                    json=payload,
                    timeout=30
                )
                
                # Retry nếu server error (5xx)
                if 500 <= response.status_code < 600:
                    wait_time = 2 ** attempt
                    print(f"🔄 Server error {response.status_code}, đợi {wait_time}s...")
                    time.sleep(wait_time)
                    continue
                
                response.raise_for_status()
                return response.json()
                
            except (requests.exceptions.Timeout, 
                    requests.exceptions.ConnectionError,
                    requests.exceptions.HTTPError) as e:
                if attempt == 2:
                    raise
                wait_time = 2 ** attempt
                print(f"🔄 Lỗi kết nối, đợi {wait_time}s...")
                time.sleep(wait_time)
        
        raise Exception("Request thất bại sau 3 lần thử")
    
    def chat(self, messages: list, model: str = "deepseek-chat") -> dict:
        """Gọi API an toàn với circuit breaker protection"""
        try:
            return self.circuit_breaker.call(self._do_request, messages, model)
        except Exception as e:
            print(f"❌ Yêu cầu bị chặn bởi Circuit Breaker: {e}")
            raise

Demo sử dụng

client = HolySheepCircuitBreakerClient(api_key="YOUR_HOLYSHEEP_API_KEY")

Khi server ổn định

try: response = client.chat([ {"role": "user", "content": "So sánh chi phí HolySheep vs OpenAI"} ]) print(f"Kết quả: {response['choices'][0]['message']['content']}") except Exception as e: print(f"Lỗi: {e}")

Kết hợp Retry + Circuit Breaker hoàn chỉnh

Sau nhiều lần đau đớn vì API không ổn định, mình đã xây dựng một class kết hợp cả hai kỹ thuật. Mình cũng thêm vào tính năng fallback — nếu model chính thất bại, tự động chuyển sang model dự phòng rẻ hơn như DeepSeek V3.2 với chi phí chỉ $0.42/MTok.

import time
import logging
from threading import Lock
from typing import Optional, List, Callable
import requests

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

class CircuitState:
    CLOSED = "closed"
    OPEN = "open"
    HALF_OPEN = "half_open"

class ResilientAIClient:
    """
    Client AI API với:
    - Retry thông minh (exponential backoff)
    - Circuit Breaker (ngăn chặn cascading failures)
    - Fallback model (tự động chuyển model khi lỗi)
    - Rate limiting (giới hạn request/giây)
    """
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.holysheep.ai/v1"
        
        # Circuit Breaker settings
        self.circuit_state = CircuitState.CLOSED
        self.failure_count = 0
        self.failure_threshold = 5
        self.recovery_timeout = 60
        self.last_failure_time = 0
        self._lock = Lock()
        
        # Models theo thứ tự ưu tiên (rẻ nhất đến đắt nhất)
        self.models = ["deepseek-chat", "gemini-2.5-flash", "claude-sonnet-4.5"]
        self.current_model_index = 0
    
    @property
    def current_model(self) -> str:
        return self.models[self.current_model_index]
    
    def _check_circuit(self):
        """Kiểm tra trạng thái circuit breaker"""
        with self._lock:
            if self.circuit_state == CircuitState.OPEN:
                if time.time() - self.last_failure_time >= self.recovery_timeout:
                    self.circuit_state = CircuitState.HALF_OPEN
                    logger.info("Circuit: OPEN → HALF_OPEN")
                else:
                    remaining = self.recovery_timeout - (time.time() - self.last_failure_time)
                    raise Exception(f"Circuit breaker OPEN. Thử lại sau {remaining:.0f}s")
    
    def _record_success(self):
        """Ghi nhận thành công"""
        with self._lock:
            self.failure_count = 0
            if self.circuit_state == CircuitState.HALF_OPEN:
                logger.info("Circuit: HALF_OPEN → CLOSED")
            self.circuit_state = CircuitState.CLOSED
            self.current_model_index = 0  # Reset về model rẻ nhất
    
    def _record_failure(self):
        """Ghi nhận thất bại"""
        with self._lock:
            self.failure_count += 1
            self.last_failure_time = time.time()
            
            if self.failure_count >= self.failure_threshold:
                self.circuit_state = CircuitState.OPEN
                logger.warning(f"Circuit: CLOSED → OPEN (sau {self.failure_count} lỗi)")
                
                # Fallback sang model rẻ hơn
                if self.current_model_index < len(self.models) - 1:
                    self.current_model_index += 1
                    logger.info(f"Fallback sang model: {self.current_model}")
    
    def _execute_with_retry(self, payload: dict, max_retries: int = 3) -> dict:
        """Thực thi request với retry logic"""
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        last_error = None
        for attempt in range(max_retries):
            try:
                response = requests.post(
                    f"{self.base_url}/chat/completions",
                    headers=headers,
                    json=payload,
                    timeout=30
                )
                
                # Retry server errors
                if 500 <= response.status_code < 600:
                    wait_time = 2 ** attempt
                    logger.warning(f"Server error {response.status_code}, retry sau {wait_time}s...")
                    time.sleep(wait_time)
                    continue
                
                response.raise_for_status()
                return response.json()
                
            except (requests.exceptions.Timeout,
                    requests.exceptions.ConnectionError) as e:
                last_error = e
                wait_time = 2 ** attempt
                logger.warning(f"Kết nối lỗi (lần {attempt + 1}), đợi {wait_time}s...")
                time.sleep(wait_time)
        
        raise last_error or Exception("Request thất bại")
    
    def chat(self, messages: list, system_prompt: str = None) -> dict:
        """Gọi API với full resilience stack"""
        self._check_circuit()
        
        # Xây dựng payload với model hiện tại
        if system_prompt:
            full_messages = [{"role": "system", "content": system_prompt}] + messages
        else:
            full_messages = messages
        
        payload = {
            "model": self.current_model,
            "messages": full_messages,
            "temperature": 0.7,
            "max_tokens": 2000
        }
        
        try:
            result = self._execute_with_retry(payload)
            self._record_success()
            
            logger.info(
                f"✅ Thành công với model {self.current_model} | "
                f"Tokens: {result.get('usage', {}).get('total_tokens', 'N/A')}"
            )
            
            return result
            
        except Exception as e:
            self._record_failure()
            logger.error(f"❌ Thất bại với model {self.current_model}: {e}")
            
            # Thử model fallback nếu có
            if self.current_model_index < len(self.models) - 1:
                self.current_model_index += 1
                logger.info(f"Thử model fallback: {self.current_model}")
                return self.chat(messages, system_prompt)
            
            raise Exception(f"Tất cả models đều thất bại: {e}")

============== DEMO ==============

if __name__ == "__main__": client = ResilientAIClient(api_key="YOUR_HOLYSHEEP_API_KEY") # Test với fallback tự động try: response = client.chat( messages=[{"role": "user", "content": "Hello, AI API là gì?"}], system_prompt="Bạn là trợ lý AI thân thiện, trả lời ngắn gọn." ) content = response['choices'][0]['message']['content'] model = response.get('model', 'unknown') tokens = response.get('usage', {}).get('total_tokens', 0) print(f"\n📝 Model: {model}") print(f"📊 Tokens: {tokens}") print(f"💬 Response: {content}") except Exception as e: print(f"\n🚫 Lỗi nghiêm trọng: {e}")

Best practices từ kinh nghiệm thực chiến

Qua 2 năm làm việc với AI API, đây là những bài học mà mình "đổ máu" mới có được:

Lỗi thường gặp và cách khắc phục

1. Lỗi "Connection timeout" liên tục

Nguyên nhân: Server API quá tải hoặc network không ổn định.

# Cách khắc phục: Tăng timeout và thêm retry với exponential backoff
import requests
from tenacity import retry, stop_after_attempt, wait_exponential

@retry(
    stop=stop_after_attempt(5),
    wait=wait_exponential(multiplier=1, min=4, max=60)  # Đợi 4-60 giây
)
def call_api_with_longer_timeout():
    response = requests.post(
        "https://api.holysheep.ai/v1/chat/completions",
        headers={"Authorization": f"Bearer {api_key}"},
        json={"model": "deepseek-chat", "messages": messages},
        timeout=60  # Tăng timeout lên 60 giây
    )
    return response.json()

2. Lỗi "401 Unauthorized" hoặc "403 Forbidden"

Nguyên nhân: API key không đúng, hết credit, hoặc chưa kích hoạt API.

# Cách khắc phục: Kiểm tra API key và balance
import requests

def check_api_health(api_key: str):
    """Kiểm tra tài khoản trước khi gọi API"""
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }
    
    # Thử gọi endpoint kiểm tra credit
    try:
        response = requests.get(
            "https://api.holysheep.ai/v1/usage",
            headers=headers,
            timeout=10
        )
        
        if response.status_code == 200:
            data = response.json()
            print(f"Tài khoản: {data.get('balance', 'N/A')} credit còn lại")
            return True
        elif response.status_code == 401:
            print("❌ API key không hợp lệ")
            return False
        elif response.status_code == 403:
            print("❌ Hết credit - vui lòng nạp thêm")
            return False
            
    except Exception as e:
        print(f"Lỗi kiểm tra: {e}")
        return False

Kiểm tra trước khi gọi chính

if check_api_health("YOUR_HOLYSHEEP_API_KEY"): response = call_main_api() else: print("Không thể tiếp tục - vui lòng kiểm tra tài khoản")

3. Lỗi "429 Too Many Requests" (Rate Limit)

Nguyên nhân: Gọi API quá nhanh, vượt quá giới hạn request/giây cho phép.

# Cách khắc phục: Thêm rate limiting và backoff thông minh
import time
import threading
from collections import deque

class RateLimiter:
    """Giới hạn số request trên giây"""
    
    def __init__(self, max_requests: int = 10, time_window: int = 60):
        self.max_requests = max_requests
        self.time_window = time_window
        self.requests = deque()
        self._lock = threading.Lock()
    
    def wait_if_needed(self):
        """Chờ nếu vượt rate limit"""
        with self._lock:
            now = time.time()
            
            # Xóa request cũ khỏi window
            while self.requests and self.requests[0] < now - self.time_window:
                self.requests.popleft()
            
            if len(self.requests) >= self.max_requests:
                # Tính thời gian chờ
                wait_time = self.requests[0] - (now - self.time_window)
                print(f"⏳ Rate limit, chờ {wait_time:.1f}s...")
                time.sleep(wait_time)
            
            self.requests.append(now)

Sử dụng rate limiter

limiter = RateLimiter(max_requests=50, time_window=60) # 50 req/phút def call_api_rate_limited(payload): limiter.wait_if_needed() response = requests.post( "