Trong thực chiến triển khai hệ thống xử lý hàng loạt với AI API, tôi đã gặp rất nhiều thách thức về hiệu năng và chi phí. Bài viết này sẽ chia sẻ những kỹ thuật tối ưu hóa mà tôi đã đúc kết qua hơn 2 năm làm việc với các API AI, đặc biệt là cách xử lý concurrent calls và rate limits một cách hiệu quả.

Bảng so sánh: HolySheep vs API chính thức vs Dịch vụ Relay khác

Tiêu chí HolySheep AI API chính thức Dịch vụ Relay khác
Tỷ giá ¥1 = $1 (85%+ tiết kiệm) $7.5 - $15/MTok $5 - $12/MTok
Thanh toán WeChat/Alipay, Visa Thẻ quốc tế Hạn chế
Độ trễ trung bình <50ms 100-300ms 80-200ms
Tín dụng miễn phí Có khi đăng ký Không Ít khi có
Rate limit Lin hoạt, có thể đàm phán Cố định theo tier Trung bình
GPT-4.1 $8/MTok $60/MTok $15-25/MTok
Claude Sonnet 4.5 $15/MTok $18/MTok $15-20/MTok
DeepSeek V3.2 $0.42/MTok Không hỗ trợ $0.5-1/MTok

Như bạn thấy, HolySheep AI nổi bật với tỷ giá ưu đãi chỉ ¥1 = $1, giúp tiết kiệm đến 85% chi phí so với API chính thức. Đặc biệt với các model như DeepSeek V3.2 chỉ $0.42/MTok, đây là lựa chọn lý tưởng cho batch processing.

Tại sao Batch Processing quan trọng?

Khi tôi xây dựng hệ thống phân tích sentiment cho 10,000 bài viết mỗi ngày, việc gọi API tuần tự mất đến 4 giờ. Sau khi tối ưu với concurrent calls và rate limit handling thông minh, thời gian giảm xuống còn 15 phút. Đó là cải thiện 93%!

1. Triển khai Concurrent Calls với Python asyncio

Đây là code xử lý concurrent mà tôi sử dụng trong production với HolySheep API:

import asyncio
import aiohttp
import time
from typing import List, Dict, Any
import json

class HolySheepBatchProcessor:
    """Xử lý batch với concurrent calls - HolySheep AI"""
    
    def __init__(
        self, 
        api_key: str,
        base_url: str = "https://api.holysheep.ai/v1",
        max_concurrent: int = 20,
        requests_per_minute: int = 500
    ):
        self.api_key = api_key
        self.base_url = base_url
        self.max_concurrent = max_concurrent
        self.requests_per_minute = requests_per_minute
        self.semaphore = asyncio.Semaphore(max_concurrent)
        self.request_times = []
        self.rate_limit_delay = 60 / requests_per_minute
        
    async def _check_rate_limit(self):
        """Kiểm tra và duy trì rate limit"""
        current_time = time.time()
        self.request_times = [
            t for t in self.request_times 
            if current_time - t < 60
        ]
        
        if len(self.request_times) >= self.requests_per_minute:
            oldest_request = self.request_times[0]
            sleep_time = 60 - (current_time - oldest_request) + 0.1
            if sleep_time > 0:
                await asyncio.sleep(sleep_time)
        
        self.request_times.append(time.time())
    
    async def _call_chat_completion(
        self,
        session: aiohttp.ClientSession,
        messages: List[Dict],
        model: str = "gpt-4.1"
    ) -> Dict[str, Any]:
        """Gọi API cho một request"""
        async with self.semaphore:
            await self._check_rate_limit()
            
            headers = {
                "Authorization": f"Bearer {self.api_key}",
                "Content-Type": "application/json"
            }
            
            payload = {
                "model": model,
                "messages": messages,
                "temperature": 0.7,
                "max_tokens": 1000
            }
            
            start_time = time.time()
            
            try:
                async with session.post(
                    f"{self.base_url}/chat/completions",
                    headers=headers,
                    json=payload,
                    timeout=aiohttp.ClientTimeout(total=30)
                ) as response:
                    result = await response.json()
                    latency = (time.time() - start_time) * 1000
                    
                    if response.status == 429:
                        # Xử lý rate limit response
                        retry_after = int(response.headers.get("Retry-After", 1))
                        await asyncio.sleep(retry_after)
                        return await self._call_chat_completion(
                            session, messages, model
                        )
                    
                    return {
                        "status": response.status,
                        "data": result,
                        "latency_ms": round(latency, 2),
                        "success": response.status == 200
                    }
                    
            except aiohttp.ClientError as e:
                return {
                    "status": 0,
                    "error": str(e),
                    "latency_ms": round((time.time() - start_time) * 1000, 2),
                    "success": False
                }
    
    async def process_batch(
        self,
        batch_requests: List[List[Dict]],
        model: str = "gpt-4.1"
    ) -> List[Dict[str, Any]]:
        """Xử lý batch với tất cả requests"""
        connector = aiohttp.TCPConnector(
            limit=self.max_concurrent,
            limit_per_host=self.max_concurrent
        )
        
        async with aiohttp.ClientSession(connector=connector) as session:
            tasks = [
                self._call_chat_completion(session, req, model)
                for req in batch_requests
            ]
            
            results = await asyncio.gather(*tasks, return_exceptions=True)
            
            # Xử lý exceptions
            processed_results = []
            for i, result in enumerate(results):
                if isinstance(result, Exception):
                    processed_results.append({
                        "index": i,
                        "success": False,
                        "error": str(result)
                    })
                else:
                    result["index"] = i
                    processed_results.append(result)
            
            return processed_results


async def main():
    """Ví dụ sử dụng"""
    processor = HolySheepBatchProcessor(
        api_key="YOUR_HOLYSHEEP_API_KEY",
        max_concurrent=20,
        requests_per_minute=500
    )
    
    # Tạo batch requests mẫu
    batch_requests = [
        [{"role": "user", "content": f"Phân tích sentiment: Sản phẩm #{i}"}]
        for i in range(100)
    ]
    
    print("Bắt đầu xử lý batch...")
    start = time.time()
    
    results = await processor.process_batch(batch_requests)
    
    elapsed = time.time() - start
    
    # Thống kê
    success_count = sum(1 for r in results if r.get("success"))
    avg_latency = sum(r.get("latency_ms", 0) for r in results) / len(results)
    
    print(f"Hoàn thành: {success_count}/{len(results)} requests")
    print(f"Thời gian: {elapsed:.2f}s")
    print(f"Latency TB: {avg_latency:.2f}ms")
    print(f"Tốc độ: {len(results)/elapsed:.2f} requests/s")


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

2. Retry Logic với Exponential Backoff

Đây là module retry thông minh giúp xử lý các lỗi tạm thời và rate limits:

import asyncio
import random
import time
from typing import Callable, Any, Optional
from dataclasses import dataclass
from enum import Enum

class RetryStrategy(Enum):
    EXPONENTIAL = "exponential"
    LINEAR = "linear"
    FIBONACCI = "fibonacci"

@dataclass
class RetryConfig:
    max_retries: int = 5
    base_delay: float = 1.0
    max_delay: float = 60.0
    multiplier: float = 2.0
    jitter: bool = True
    strategy: RetryStrategy = RetryStrategy.EXPONENTIAL
    
    def get_delay(self, attempt: int) -> float:
        """Tính toán delay với strategy đã chọn"""
        if self.strategy == RetryStrategy.EXPONENTIAL:
            delay = self.base_delay * (self.multiplier ** attempt)
        elif self.strategy == RetryStrategy.LINEAR:
            delay = self.base_delay * (attempt + 1)
        elif self.strategy == RetryStrategy.FIBONACCI:
            a, b = 1, 1
            for _ in range(attempt):
                a, b = b, a + b
            delay = self.base_delay * a
        else:
            delay = self.base_delay
        
        delay = min(delay, self.max_delay)
        
        if self.jitter:
            delay = delay * (0.5 + random.random() * 0.5)
        
        return delay

class RetryHandler:
    """Handler retry với exponential backoff cho HolySheep API"""
    
    def __init__(self, config: Optional[RetryConfig] = None):
        self.config = config or RetryConfig()
        self.stats = {
            "total_attempts": 0,
            "successful_retries": 0,
            "failed_retries": 0
        }
    
    def _should_retry(self, error: Exception, attempt: int) -> bool:
        """Quyết định có nên retry không"""
        if attempt >= self.config.max_retries:
            return False
        
        # Các lỗi có thể retry
        retryable_errors = {
            429,    # Too Many Requests
            500,    # Internal Server Error
            502,    # Bad Gateway
            503,    # Service Unavailable
            504,    # Gateway Timeout
        }
        
        if hasattr(error, "status"):
            return error.status in retryable_errors
        
        if hasattr(error, "response") and hasattr(error.response, "status"):
            return error.response.status in retryable_errors
        
        # Network errors
        return isinstance(error, (ConnectionError, TimeoutError))
    
    async def execute_with_retry(
        self,
        func: Callable,
        *args,
        **kwargs
    ) -> Any:
        """Execute function với retry logic"""
        last_error = None
        
        for attempt in range(self.config.max_retries + 1):
            self.stats["total_attempts"] += 1
            
            try:
                if asyncio.iscoroutinefunction(func):
                    result = await func(*args, **kwargs)
                else:
                    result = func(*args, **kwargs)
                
                if attempt > 0:
                    self.stats["successful_retries"] += 1
                    print(f"✓ Retry thành công ở lần {attempt + 1}")
                
                return result
                
            except Exception as e:
                last_error = e
                
                if not self._should_retry(e, attempt):
                    self.stats["failed_retries"] += 1
                    print(f"✗ Không retry được: {e}")
                    raise
                
                delay = self.config.get_delay(attempt)
                
                # Parse rate limit specific info
                error_msg = str(e)
                if "429" in error_msg or "rate" in error_msg.lower():
                    print(f"⚠ Rate limit hit, chờ {delay:.1f}s...")
                else:
                    print(f"⚠ Lỗi: {e}, retry sau {delay:.1f}s...")
                
                await asyncio.sleep(delay)
        
        self.stats["failed_retries"] += 1
        raise last_error
    
    def get_stats(self) -> dict:
        """Lấy thống kê retry"""
        return self.stats.copy()


Ví dụ sử dụng với HolySheep API

async def call_holysheep_api(session, prompt: str, api_key: str): """Gọi HolySheep API với retry""" base_url = "https://api.holysheep.ai/v1" async def _make_request(): async with session.post( f"{base_url}/chat/completions", headers={ "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" }, json={ "model": "gpt-4.1", "messages": [{"role": "user", "content": prompt}], "temperature": 0.7 } ) as resp: if resp.status != 200: raise aiohttp.ClientResponseError( resp.request_info, resp.history, status=resp.status ) return await resp.json() # Sử dụng retry handler config = RetryConfig( max_retries=5, base_delay=1.0, max_delay=30.0, multiplier=2.0, jitter=True ) handler = RetryHandler(config) result = await handler.execute_with_retry(_make_request) print(f"Stats: {handler.get_stats()}") return result if __name__ == "__main__": # Test retry handler config = RetryConfig(max_retries=3, strategy=RetryStrategy.EXPONENTIAL) handler = RetryHandler(config) print("Testing delay calculation:") for i in range(5): delay = config.get_delay(i) print(f" Attempt {i}: {delay:.2f}s")

3. Token Bucket Algorithm cho Rate Limiting

Đây là implementation Token Bucket chính xác mà tôi sử dụng để kiểm soát rate limit hiệu quả:

import time
import threading
from typing import Optional
from dataclasses import dataclass, field

@dataclass
class TokenBucket:
    """
    Token Bucket Algorithm cho rate limiting
    Đảm bảo không vượt quá rate limit của HolySheep API
    """
    capacity: int          # Số token tối đa
    refill_rate: float     # Token refill mỗi giây
    tokens: float = field(init=False)
    last_refill: float = field(init=False)
    lock: threading.Lock = field(default_factory=threading.Lock)
    
    def __post_init__(self):
        self.tokens = float(self.capacity)
        self.last_refill = time.time()
    
    def _refill(self):
        """Tự động refill tokens dựa trên thời gian"""
        now = time.time()
        elapsed = now - self.last_refill
        
        # Tính tokens cần refill
        new_tokens = elapsed * self.refill_rate
        self.tokens = min(self.capacity, self.tokens + new_tokens)
        self.last_refill = now
    
    def consume(self, tokens: int = 1, blocking: bool = False, timeout: Optional[float] = None) -> bool:
        """
        Lấy tokens từ bucket
        
        Args:
            tokens: Số tokens cần lấy
            blocking: Có chờ nếu không đủ tokens
            timeout: Thời gian chờ tối đa (giây)
            
        Returns:
            True nếu lấy được tokens, False nếu không
        """
        start_time = time.time()
        
        while True:
            with self.lock:
                self._refill()
                
                if self.tokens >= tokens:
                    self.tokens -= tokens
                    return True
                
                if not blocking:
                    return False
                
                # Tính thời gian chờ
                wait_time = (tokens - self.tokens) / self.refill_rate
                
                if timeout is not None:
                    elapsed = time.time() - start_time
                    if elapsed + wait_time > timeout:
                        return False
                    wait_time = min(wait_time, timeout - elapsed)
            
            # Chờ trước khi thử lại
            time.sleep(min(wait_time, 0.1))
    
    def get_available_tokens(self) -> float:
        """Lấy số tokens hiện có"""
        with self.lock:
            self._refill()
            return self.tokens


class RateLimitedClient:
    """
    HTTP Client với rate limiting
    Tối ưu cho HolySheep API
    """
    
    def __init__(
        self,
        requests_per_minute: int = 500,
        tokens_per_minute: int = 150000,
        max_concurrent: int = 20
    ):
        # Rate limits
        self.request_bucket = TokenBucket(
            capacity=max_concurrent,
            refill_rate=requests_per_minute / 60.0
        )
        self.token_bucket = TokenBucket(
            capacity=tokens_per_minute,
            refill_rate=tokens_per_minute / 60.0
        )
        
        self.stats = {
            "total_requests": 0,
            "successful_requests": 0,
            "rate_limited": 0,
            "total_tokens_used": 0
        }
    
    def estimate_tokens(self, text: str) -> int:
        """Ước tính tokens (rough estimate: ~4 chars per token)"""
        return max(1, len(text) // 4)
    
    async def make_request(
        self,
        session,
        url: str,
        headers: dict,
        json_data: dict,
        estimated_response_tokens: int = 500
    ) -> dict:
        """
        Thực hiện request với rate limiting
        
        Args:
            session: aiohttp session
            url: API endpoint
            headers: Request headers
            json_data: Request body
            estimated_response_tokens: Ước tính tokens trong response
            
        Returns:
            Response dict
        """
        # Ước tính tokens trong request
        request_tokens = sum(
            self.estimate_tokens(str(msg)) 
            for msg in json_data.get("messages", [])
        )
        total_tokens = request_tokens + estimated_response_tokens
        
        # Kiểm tra và chờ nếu cần
        can_proceed = self.request_bucket.consume(tokens=1, blocking=False)
        if not can_proceed:
            self.stats["rate_limited"] += 1
            self.request_bucket.consume(tokens=1, blocking=True, timeout=60)
        
        tokens_acquired = self.token_bucket.consume(
            tokens=total_tokens, 
            blocking=True, 
            timeout=120
        )
        
        if not tokens_acquired:
            raise Exception("Không thể acquire tokens trong timeout")
        
        self.stats["total_requests"] += 1
        self.stats["total_tokens_used"] += total_tokens
        
        # Thực hiện request
        start_time = time.time()
        
        try:
            async with session.post(url, headers=headers, json=json_data) as resp:
                response = await resp.json()
                latency = (time.time() - start_time) * 1000
                
                if resp.status == 200:
                    self.stats["successful_requests"] += 1
                elif resp.status == 429:
                    self.stats["rate_limited"] += 1
                
                return {
                    "status": resp.status,
                    "response": response,
                    "latency_ms": round(latency, 2),
                    "tokens_used": total_tokens
                }
                
        except Exception as e:
            return {
                "status": 0,
                "error": str(e),
                "latency_ms": round((time.time() - start_time) * 1000, 2)
            }
    
    def get_stats(self) -> dict:
        """Lấy thống kê"""
        return self.stats.copy()
    
    def print_stats(self):
        """In thống kê đẹp"""
        print("\n=== Rate Limited Client Stats ===")
        print(f"Total Requests: {self.stats['total_requests']}")
        print(f"Successful: {self.stats['successful_requests']}")
        print(f"Rate Limited: {self.stats['rate_limited']}")
        print(f"Total Tokens: {self.stats['total_tokens_used']:,}")
        print(f"Request Bucket Available: {self.request_bucket.get_available_tokens():.1f}")
        print(f"Token Bucket Available: {self.token_bucket.get_available_tokens():.1f}")


Ví dụ sử dụng

if __name__ == "__main__": client = RateLimitedClient( requests_per_minute=500, tokens_per_minute=150000, max_concurrent=20 ) # Test token bucket print("Testing Token Bucket Algorithm:") bucket = TokenBucket(capacity=10, refill_rate=2.0) for i in range(15): # Consume 1 token mỗi lần acquired = bucket.consume(1, blocking=False) available = bucket.get_available_tokens() print(f" Request {i+1}: {'✓' if acquired else '✗'} | Available: {available:.1f}") if not acquired: bucket.consume(1, blocking=True) print(f" → Blocked và chờ refill")

4. Batch Processing với Chunking Thông Minh

Để tối ưu hóa chi phí và throughput, tôi sử dụng kỹ thuật batching thông minh:

import json
import tiktoken
from typing import List, Dict, Any, Tuple
from dataclasses import dataclass

@dataclass
class BatchConfig:
    max_tokens_per_batch: int = 100000      # Limit tokens per batch
    max_requests_per_batch: int = 100       # Max requests trong 1 batch
    model: str = "gpt-4.1"

class IntelligentBatcher:
    """
    Batch processor thông minh với token-aware chunking
    Tối ưu chi phí với HolySheep API pricing
    """
    
    # Pricing theo model (2026) - HolySheep
    PRICING = {
        "gpt-4.1": {"input": 8.0, "output": 8.0},      # $/MTok
        "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}
    }
    
    def __init__(self, config: BatchConfig):
        self.config = config
        try:
            self.enc = tiktoken.get_encoding("cl100k_base")
        except:
            self.enc = None
    
    def count_tokens(self, text: str) -> int:
        """Đếm tokens trong text"""
        if self.enc:
            return len(self.enc.encode(text))
        return len(text) // 4  # Fallback estimate
    
    def estimate_cost(self, input_tokens: int, output_tokens: int, model: str) -> float:
        """Ước tính chi phí cho 1 request"""
        pricing = self.PRICING.get(model, {"input": 8.0, "output": 8.0})
        
        input_cost = (input_tokens / 1_000_000) * pricing["input"]
        output_cost = (output_tokens / 1_000_000) * pricing["output"]
        
        return input_cost + output_cost
    
    def create_batches(self, requests: List[Dict[str, Any]]) -> List[List[Dict]]:
        """
        Tạo batches tối ưu dựa trên token limit
        
        Returns:
            List of batches, mỗi batch chứa requests
        """
        batches = []
        current_batch = []
        current_tokens = 0
        
        for req in requests:
            # Tính tokens cho request này
            request_tokens = sum(
                self.count_tokens(str(msg.get("content", "")))
                for msg in req.get("messages", [])
            )
            request_tokens += 100  # Buffer cho overhead
            
            # Kiểm tra nếu thêm request sẽ vượt limit
            if (
                current_tokens + request_tokens > self.config.max_tokens_per_batch
                or len(current_batch) >= self.config.max_requests_per_batch
            ) and current_batch:
                # Lưu batch hiện tại và bắt đầu batch mới
                batches.append(current_batch)
                current_batch = []
                current_tokens = 0
            
            current_batch.append(req)
            current_tokens += request_tokens
        
        # Thêm batch cuối cùng
        if current_batch:
            batches.append(current_batch)
        
        return batches
    
    def calculate_batch_cost(
        self, 
        batches: List[List[Dict]], 
        avg_output_tokens: int = 500
    ) -> Dict[str, Any]:
        """Tính tổng chi phí cho tất cả batches"""
        model = self.config.model
        total_input_tokens = 0
        total_output_tokens = 0
        batch_costs = []
        
        for i, batch in enumerate(batches):
            batch_input = sum(
                sum(
                    self.count_tokens(str(msg.get("content", "")))
                    for msg in req.get("messages", [])
                )
                for req in batch
            )
            batch_output = len(batch) * avg_output_tokens
            
            batch_cost = self.estimate_cost(batch_input, batch_output, model)
            
            total_input_tokens += batch_input
            total_output_tokens += batch_output
            
            batch_costs.append({
                "batch_id": i,
                "requests": len(batch),
                "input_tokens": batch_input,
                "output_tokens": batch_output,
                "cost_usd": round(batch_cost, 6)
            })
        
        return {
            "total_batches": len(batches),
            "total_requests": sum(len(b) for b in batches),
            "total_input_tokens": total_input_tokens,
            "total_output_tokens": total_output_tokens,
            "total_cost_usd": round(
                self.estimate_cost(total_input_tokens, total_output_tokens, model),
                4
            ),
            "batches": batch_costs
        }
    
    def optimize_batch_order(self, requests: List[Dict]) -> List[Dict]:
        """
        Tối ưu thứ tự requests để giảm overhead
        Requests ngắn hơn đặt trước để fill gaps
        """
        # Đánh score dựa trên độ dài
        scored = []
        for req in requests:
            tokens = sum(
                self.count_tokens(str(msg.get("content", "")))
                for msg in req.get("messages", [])
            )
            scored.append((tokens, req))
        
        # Sort theo token count (ngắn -> dài)
        scored.sort(key=lambda x: x[0])
        
        return [req for _, req in scored]


Ví dụ sử dụng

if __name__ == "__main__": # Tạo sample requests requests = [ {"messages": [{"role": "user", "content": f"Nội dung test {i} " * (i * 10)}]} for i in range(1, 51) ] config = BatchConfig( max_tokens_per_batch=50000, max_requests_per_batch=20 ) batcher = IntelligentBatcher(config) # Tạo batches batches = batcher.create_batches(requests) # Tính chi phí cost_analysis = batcher.calculate_batch_cost(batches) print("=== Batch Processing Optimization ===") print(f"Tổng batches: {cost_analysis['total_batches']}") print(f"Tổng requests: {cost_analysis['total_requests']}") print(f"Tổng input tokens: {cost_analysis['total_input_tokens']:,}") print(f"Tổng output tokens: {cost_analysis['total_output_tokens']:,}") print(f"Tổng chi phí: ${cost_analysis['total_cost_usd']}") print("\nChi tiết từng batch:") for bc in cost_analysis['batches'][:5]: print(f" Batch {bc['batch_id']}: {bc['requests']} requests, " f"{bc['input_tokens']:,} tokens, ${bc['cost_usd']}")

5. Monitoring và Metrics Dashboard

Để theo dõi hiệu suất batch processing, tôi sử dụng module monitoring này:

import time
import threading
from collections import defaultdict
from dataclasses import dataclass, field
from typing import Dict, List, Optional
from datetime import datetime, timedelta
import statistics

@dataclass
class RequestMetrics:
    timestamp: float
    latency_ms: float
    tokens: int
    success: bool
    error_type: Optional[str] = None

class BatchMonitor:
    """
    Real-time monitoring cho batch processing
    Theo dõi latency, throughput, và chi phí
    """
    
    def __init__(self):
        self.metrics: List[RequestMetrics] = []
        self.lock = threading.Lock()
        self.start_time = time.time()
        
        # Pricing HolySheep 2026 ($/MTok)
        self.pricing = {
            "gpt-4.1": 8.0,
            "claude-sonnet-4.5": 15.0,
            "gemini-2.5-flash": 2.50,
            "deepseek-v3.2": 0.42
        }
    
    def record(
        self,
        latency_ms: float,
        tokens: int,
        success: bool,
        error_type: Optional[str] = None
    ):
        """Ghi nhận metrics cho 1 request"""
        with self.lock:
            self.metrics.append(RequestMetrics(
                timestamp=time.time(),
                latency_ms=latency_ms,
                tokens=tokens,
                success=success,
                error_type=error_type
            ))
    
    def get_stats(self, window_seconds: Optional[int] = None) -> Dict:
        """Lấy thống kê trong khoảng thời gian"""
        with self.lock:
            if window_seconds:
                cutoff = time.time() - window_seconds
                filtered = [m for m in self.metrics if m.timestamp >= cutoff]
            else:
                filtered = self.metrics
            
            if not filtered:
                return self._empty_stats()
            
            successful = [m for m in filtered if m.success]
            failed = [m for m in filtered if not m.success]
            
            latencies = [m.latency_ms for m in filtered]
            all_tokens = sum(m.tokens for m in filtered)
            
            elapsed = time.time() - self.start_time
            
            return {
                "total_requests": len(filtered),
                "successful": len(successful),
                "failed": len(failed),
                "success_rate": len(successful) / len(filtered) * 100,
                "latency": {
                    "min_ms": min(latencies),
                    "max_ms": max(latencies),
                    "avg_ms": statistics.mean(latencies),
                    "p50_ms": statistics.median(latencies),
                    "p95_ms": self._percentile(latencies, 95),
                    "p99_ms": self._percentile(latencies, 99)
                },
                "throughput": {
                    "requests_per_second": len(filtered) / elapsed,
                    "tokens_per_second": all_tokens / elapsed
                },
                "uptime_seconds": elapsed,
                "window_seconds": window_seconds
            }
    
    def estimate_cost(self, model: str = "gpt-4.1") -> float:
        """Ước tính chi phí"""
        with self.lock:
            total_tokens = sum(m.tokens for m in self.metrics)
            price_per_m