Trong bài viết này, tôi sẽ chia sẻ kinh nghiệm thực chiến khi xây dựng MCP Server (Model Context Protocol) cho hệ thống AI Agent production. Đây là những bài học tôi đã đúc kết từ hơn 2 năm triển khai hệ thống multi-agent cho các doanh nghiệp, với lưu lượng xử lý hàng triệu request mỗi ngày.

MCP Server là gì và Tại sao cần thiết?

Model Context Protocol (MCP) là một giao thức chuẩn hóa cho phép AI Agent giao tiếp với các công cụ và dịch vụ bên ngoài một cách nhất quán. Thay vì mỗi Agent phải tự implement cách gọi API, MCP cung cấp một abstraction layer giúp:

Kiến trúc MCP Server tổng quan

Kiến trúc MCP Server production cần đáp ứng các yêu cầu nghiêm ngặt về hiệu suất, độ tin cậy và khả năng mở rộng. Dưới đây là sơ đồ kiến trúc mà tôi đã áp dụng thành công cho nhiều dự án enterprise:

┌─────────────────────────────────────────────────────────────────┐
│                        AI Agent Layer                           │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐        │
│  │ Agent 1  │  │ Agent 2  │  │ Agent 3  │  │ Agent N  │        │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘  └────┬─────┘        │
└───────┼─────────────┼─────────────┼─────────────┼───────────────┘
        │             │             │             │
        └─────────────┴──────┬──────┴─────────────┘
                              │
                    ┌─────────▼─────────┐
                    │   MCP Protocol    │
                    │   Transport Layer │
                    │   (STDIO/SSE)     │
                    └─────────┬─────────┘
                              │
┌─────────────────────────────┼───────────────────────────────────┐
│                   MCP Server Core                               │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │ Tool Registry│  │ Auth Manager │  │ Rate Limiter │          │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │   Cache      │  │   Pool       │  │   Metrics    │          │
│  │   Manager    │  │   Manager    │  │   Collector  │          │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
└─────────────────────────────────────────────────────────────────┘
                              │
                    ┌─────────▼─────────┐
                    │   External APIs   │
                    │   HolySheep AI    │
                    │   (base_url)      │
                    └───────────────────┘

Khởi tạo MCP Server với HolySheep AI

Để bắt đầu, chúng ta sẽ xây dựng một MCP Server hoàn chỉnh kết nối với HolySheep AI - nền tảng AI API với chi phí tiết kiệm đến 85% so với các provider khác (¥1=$1, hỗ trợ WeChat/Alipay, độ trễ dưới 50ms). Giá 2026 chỉ từ $0.42/MTok với DeepSeek V3.2.

# requirements.txt
fastapi==0.109.2
uvicorn==0.27.1
pydantic==2.6.1
httpx==0.26.0
redis==5.0.1
asyncio==3.4.3
structlog==24.1.0
python-dotenv==1.0.1
pytest==8.0.0
pytest-asyncio==0.23.4
locust==2.22.0

mcp-server-sdk (official)

mcp-server==1.2.0
# config.py - Cấu hình production với HolySheep AI
import os
from dataclasses import dataclass, field
from typing import Optional
import httpx

@dataclass
class HolySheepConfig:
    """Cấu hình kết nối HolySheep AI - Tỷ giá ¥1=$1, tiết kiệm 85%+"""
    base_url: str = "https://api.holysheep.ai/v1"  # KHÔNG dùng api.openai.com
    api_key: str = os.getenv("HOLYSHEEP_API_KEY", "YOUR_HOLYSHEEP_API_KEY")
    timeout: float = 30.0
    max_retries: int = 3
    max_connections: int = 100
    max_keepalive_connections: int = 20
    
    # Model configuration với giá 2026/MTok
    default_model: str = "deepseek-v3.2"  # $0.42/MTok - tiết kiệm nhất
    models: dict = field(default_factory=lambda: {
        "gpt-4.1": {"price": 8.0, "max_tokens": 128000},
        "claude-sonnet-4.5": {"price": 15.0, "max_tokens": 200000},
        "gemini-2.5-flash": {"price": 2.50, "max_tokens": 1000000},
        "deepseek-v3.2": {"price": 0.42, "max_tokens": 64000},
    })
    
    @property
    def client(self) -> httpx.AsyncClient:
        """Tạo HTTP client với connection pooling"""
        return httpx.AsyncClient(
            base_url=self.base_url,
            headers={
                "Authorization": f"Bearer {self.api_key}",
                "Content-Type": "application/json",
            },
            timeout=self.timeout,
            limits=httpx.Limits(
                max_connections=self.max_connections,
                max_keepalive_connections=self.max_keepalive_connections,
            ),
        )


@dataclass
class MCPServerConfig:
    """Cấu hình MCP Server"""
    host: str = "0.0.0.0"
    port: int = 8080
    workers: int = 4
    max_concurrent_requests: int = 1000
    request_timeout: float = 60.0
    
    # Rate limiting
    rate_limit_requests: int = 100
    rate_limit_window: int = 60  # seconds
    
    # Cache configuration
    cache_ttl: int = 3600  # 1 hour
    cache_max_size: int = 10000


Global configuration instance

config = MCPServerConfig() holy_sheep = HolySheepConfig()

Xây dựng MCP Server Core với Concurrency Control

Đây là phần quan trọng nhất - tôi sẽ chia sẻ cách implement semaphore-based concurrency control và circuit breaker pattern đã giúp hệ thống của tôi xử lý 10,000+ concurrent connections mà không bị overload.

# mcp_server.py - MCP Server Core Implementation
import asyncio
import time
import structlog
from typing import Any, Dict, List, Optional
from dataclasses import dataclass, field
from contextlib import asynccontextmanager
from enum import Enum
import json

logger = structlog.get_logger()

class CircuitState(Enum):
    CLOSED = "closed"      # Normal operation
    OPEN = "open"          # Failing, reject requests
    HALF_OPEN = "half_open"  # Testing if service recovered

@dataclass
class CircuitBreaker:
    """Circuit breaker pattern để ngăn chặn cascade failures"""
    failure_threshold: int = 5
    recovery_timeout: float = 30.0
    half_open_max_calls: int = 3
    
    _state: CircuitState = field(default=CircuitState.CLOSED, init=False)
    _failure_count: int = field(default=0, init=False)
    _last_failure_time: float = field(default=0.0, init=False)
    _half_open_calls: int = field(default=0, init=False)
    
    async def call(self, func, *args, **kwargs):
        """Execute function với circuit breaker protection"""
        if self._state == CircuitState.OPEN:
            if time.time() - self._last_failure_time > self.recovery_timeout:
                self._state = CircuitState.HALF_OPEN
                self._half_open_calls = 0
                logger.info("circuit_breaker", state="half_open")
            else:
                raise CircuitBreakerOpenError("Circuit breaker is OPEN")
        
        try:
            result = await func(*args, **kwargs)
            self._on_success()
            return result
        except Exception as e:
            self._on_failure()
            raise
    
    def _on_success(self):
        self._failure_count = 0
        if self._state == CircuitState.HALF_OPEN:
            self._half_open_calls += 1
            if self._half_open_calls >= self.half_open_max_calls:
                self._state = CircuitState.CLOSED
                logger.info("circuit_breaker", state="closed")
    
    def _on_failure(self):
        self._failure_count += 1
        self._last_failure_time = time.time()
        if self._failure_count >= self.failure_threshold:
            self._state = CircuitState.OPEN
            logger.warning("circuit_breaker", state="open")


class CircuitBreakerOpenError(Exception):
    pass


class RateLimiter:
    """Token bucket rate limiter với sliding window"""
    def __init__(self, max_requests: int, window_seconds: int):
        self.max_requests = max_requests
        self.window_seconds = window_seconds
        self.requests: List[float] = []
        self._lock = asyncio.Lock()
    
    async def acquire(self) -> bool:
        """Acquire permission for request, returns True if allowed"""
        async with self._lock:
            now = time.time()
            # Remove expired requests
            self.requests = [t for t in self.requests if now - t < self.window_seconds]
            
            if len(self.requests) < self.max_requests:
                self.requests.append(now)
                return True
            return False
    
    @asynccontextmanager
    async def limited(self):
        """Context manager for rate-limited operations"""
        if not await self.acquire():
            raise RateLimitExceededError(
                f"Rate limit exceeded: {self.max_requests}/{self.window_seconds}s"
            )
        yield


class MCPResourcePool:
    """Connection pool với resource management"""
    def __init__(self, factory, max_size: int = 100):
        self.factory = factory
        self.max_size = max_size
        self._pool: asyncio.Queue = asyncio.Queue(maxsize=max_size)
        self._size = 0
        self._lock = asyncio.Lock()
    
    async def get(self):
        """Get resource from pool"""
        try:
            return self._pool.get_nowait()
        except asyncio.QueueEmpty:
            async with self._lock:
                if self._size < self.max_size:
                    self._size += 1
                    return await self.factory()
            # Wait for available resource
            return await asyncio.wait_for(self._pool.get(), timeout=30.0)
    
    async def put(self, resource):
        """Return resource to pool"""
        try:
            self._pool.put_nowait(resource)
        except asyncio.QueueFull:
            # Pool full, discard resource
            pass
    
    @asynccontextmanager
    async def connection(self):
        """Context manager for pooled connection"""
        conn = await self.get()
        try:
            yield conn
        finally:
            await self.put(conn)

Tool Registry và Handler Implementation

Tiếp theo, tôi sẽ hướng dẫn cách implement tool registry với dynamic loading và hot-reload capability - một tính năng cực kỳ hữu ích khi bạn cần thêm tools mà không muốn restart server.

# tools/tool_registry.py - Tool Registry với Dynamic Loading
import asyncio
import hashlib
import json
import time
from typing import Any, Callable, Dict, Optional, List
from dataclasses import dataclass, field
from enum import Enum
import structlog

logger = structlog.get_logger()

class ToolScope(Enum):
    READ = "read"       # Read-only tools (query, search)
    WRITE = "write"     # Write tools (create, update, delete)
    ADMIN = "admin"     # Admin tools (system management)

@dataclass
class ToolDefinition:
    """Tool definition theo MCP specification"""
    name: str
    description: str
    input_schema: Dict[str, Any]
    scope: ToolScope = ToolScope.READ
    handler: Optional[Callable] = None
    cacheable: bool = True
    ttl: int = 300  # Cache TTL in seconds
    rate_limit: int = 100  # Requests per minute
    
    def to_mcp_format(self) -> Dict[str, Any]:
        return {
            "name": self.name,
            "description": self.description,
            "inputSchema": self.input_schema,
        }


@dataclass
class ToolCall:
    """Tool call request/response"""
    tool_name: str
    arguments: Dict[str, Any]
    request_id: str
    timestamp: float = field(default_factory=time.time)
    timeout: float = 30.0


@dataclass
class ToolResult:
    """Tool call result"""
    tool_name: str
    success: bool
    data: Any = None
    error: Optional[str] = None
    execution_time_ms: float = 0.0
    cached: bool = False
    tokens_used: int = 0


class ToolRegistry:
    """Centralized tool registry với caching và rate limiting"""
    def __init__(self, cache_backend=None):
        self._tools: Dict[str, ToolDefinition] = {}
        self._cache: Dict[str, tuple[Any, float]] = {}  # key -> (value, expiry)
        self._locks: Dict[str, asyncio.Lock] = {}
        self._rate_limiters: Dict[str, asyncio.Semaphore] = {}
        self._metrics: Dict[str, Dict[str, Any]] = {}
        self._cache_backend = cache_backend
        self._lock = asyncio.Lock()
    
    def register(self, tool: ToolDefinition):
        """Register a new tool"""
        self._tools[tool.name] = tool
        self._locks[tool.name] = asyncio.Lock()
        self._rate_limiters[tool.name] = asyncio.Semaphore(tool.rate_limit)
        self._metrics[tool.name] = {
            "total_calls": 0,
            "success_count": 0,
            "failure_count": 0,
            "total_latency_ms": 0.0,
            "cache_hits": 0,
            "cache_misses": 0,
        }
        logger.info("tool_registered", tool=tool.name, scope=tool.scope.value)
    
    def get_tool(self, name: str) -> Optional[ToolDefinition]:
        return self._tools.get(name)
    
    def list_tools(self, scope: Optional[ToolScope] = None) -> List[ToolDefinition]:
        """List all registered tools, optionally filtered by scope"""
        tools = list(self._tools.values())
        if scope:
            tools = [t for t in tools if t.scope == scope]
        return tools
    
    def _get_cache_key(self, tool_name: str, arguments: Dict) -> str:
        """Generate cache key từ tool name và arguments"""
        content = json.dumps({"tool": tool_name, "args": arguments}, sort_keys=True)
        return hashlib.sha256(content.encode()).hexdigest()
    
    def _is_cache_valid(self, key: str) -> bool:
        """Check if cache entry is still valid"""
        if key not in self._cache:
            return False
        _, expiry = self._cache[key]
        return time.time() < expiry
    
    async def execute_tool(self, call: ToolCall) -> ToolResult:
        """Execute a tool call với full lifecycle management"""
        tool = self._tools.get(call.tool_name)
        if not tool:
            return ToolResult(
                tool_name=call.tool_name,
                success=False,
                error=f"Tool '{call.tool_name}' not found",
            )
        
        start_time = time.time()
        cache_key = self._get_cache_key(call.tool_name, call.arguments)
        
        # Check cache first
        if tool.cacheable and self._is_cache_valid(cache_key):
            cached_value, _ = self._cache[cache_key]
            self._metrics[call.tool_name]["cache_hits"] += 1
            return ToolResult(
                tool_name=call.tool_name,
                success=True,
                data=cached_value,
                execution_time_ms=(time.time() - start_time) * 1000,
                cached=True,
            )
        
        self._metrics[call.tool_name]["cache_misses"] += 1
        
        # Rate limiting
        async with self._locks[call.tool_name]:
            semaphore = self._rate_limiters[call.tool_name]
            async with semaphore:
                try:
                    result = await asyncio.wait_for(
                        tool.handler(call.arguments),
                        timeout=call.timeout,
                    )
                    
                    # Update cache
                    if tool.cacheable:
                        expiry = time.time() + tool.ttl
                        self._cache[cache_key] = (result, expiry)
                    
                    execution_time = (time.time() - start_time) * 1000
                    self._metrics[call.tool_name]["total_calls"] += 1
                    self._metrics[call.tool_name]["success_count"] += 1
                    self._metrics[call.tool_name]["total_latency_ms"] += execution_time
                    
                    return ToolResult(
                        tool_name=call.tool_name,
                        success=True,
                        data=result,
                        execution_time_ms=execution_time,
                    )
                    
                except asyncio.TimeoutError:
                    self._metrics[call.tool_name]["failure_count"] += 1
                    return ToolResult(
                        tool_name=call.tool_name,
                        success=False,
                        error=f"Timeout after {call.timeout}s",
                        execution_time_ms=(time.time() - start_time) * 1000,
                    )
                except Exception as e:
                    self._metrics[call.tool_name]["failure_count"] += 1
                    logger.error("tool_execution_error", 
                                tool=call.tool_name, 
                                error=str(e))
                    return ToolResult(
                        tool_name=call.tool_name,
                        success=False,
                        error=str(e),
                        execution_time_ms=(time.time() - start_time) * 1000,
                    )
    
    def get_metrics(self) -> Dict[str, Any]:
        """Get aggregated metrics"""
        return {
            name: {
                "avg_latency_ms": (
                    m["total_latency_ms"] / m["total_calls"] 
                    if m["total_calls"] > 0 else 0
                ),
                "success_rate": (
                    m["success_count"] / m["total_calls"]
                    if m["total_calls"] > 0 else 0
                ),
                "cache_hit_rate": (
                    m["cache_hits"] / (m["cache_hits"] + m["cache_misses"])
                    if (m["cache_hits"] + m["cache_misses"]) > 0 else 0
                ),
                **m,
            }
            for name, m in self._metrics.items()
        }


Initialize global registry

tool_registry = ToolRegistry()

Kết nối HolySheep AI qua MCP Server

Đây là phần core - kết nối MCP Server với HolySheep AI để tận dụng chi phí thấp nhất ($0.42/MTok với DeepSeek V3.2) và độ trễ dưới 50ms. Tôi đã benchmark nhiều model và DeepSeek V3.2 thực sự là lựa chọn tối ưu về cost-efficiency.

# integration/holy_sheep_client.py - HolySheep AI Integration
import asyncio
import time
import httpx
from typing import AsyncIterator, Dict, List, Optional, Any
from dataclasses import dataclass, field
import structlog
import json

from config import holy_sheep, config
from tools.tool_registry import tool_registry, ToolDefinition, ToolScope

logger = structlog.get_logger()

@dataclass
class TokenUsage:
    """Track token usage cho cost optimization"""
    prompt_tokens: int = 0
    completion_tokens: int = 0
    total_tokens: int = 0
    cost_usd: float = 0.0
    
    def calculate_cost(self, model: str):
        """Tính chi phí dựa trên model price"""
        price_per_mtok = holy_sheep.models.get(model, {}).get("price", 0.42)
        self.cost_usd = (self.total_tokens / 1_000_000) * price_per_mtok
        return self.cost_usd


@dataclass
class ChatMessage:
    role: str
    content: str
    name: Optional[str] = None


@dataclass
class ChatCompletionRequest:
    model: str
    messages: List[ChatMessage]
    temperature: float = 0.7
    max_tokens: int = 4096
    stream: bool = False
    tools: Optional[List[Dict]] = None
    tool_choice: Optional[str] = None


class HolySheepClient:
    """Production-ready client cho HolySheep AI API"""
    
    def __init__(self):
        self._client: Optional[httpx.AsyncClient] = None
        self._semaphore = asyncio.Semaphore(config.max_concurrent_requests)
        self._request_count = 0
        self._total_cost = 0.0
        self._total_latency_ms = 0.0
    
    @property
    def client(self) -> httpx.AsyncClient:
        if self._client is None:
            self._client = holy_sheep.client
        return self._client
    
    async def chat_completions(
        self, 
        request: ChatCompletionRequest
    ) -> Dict[str, Any]:
        """Gửi chat completion request đến HolySheep AI"""
        async with self._semaphore:
            start_time = time.time()
            self._request_count += 1
            
            payload = {
                "model": request.model,
                "messages": [
                    {"role": m.role, "content": m.content, "name": m.name}
                    for m in request.messages
                ],
                "temperature": request.temperature,
                "max_tokens": request.max_tokens,
                "stream": request.stream,
            }
            
            if request.tools:
                payload["tools"] = request.tools
                payload["tool_choice"] = request.tool_choice or "auto"
            
            try:
                response = await self.client.post(
                    "/chat/completions",
                    json=payload,
                )
                response.raise_for_status()
                result = response.json()
                
                latency_ms = (time.time() - start_time) * 1000
                self._total_latency_ms += latency_ms
                
                # Calculate cost
                usage = TokenUsage(
                    prompt_tokens=result.get("usage", {}).get("prompt_tokens", 0),
                    completion_tokens=result.get("usage", {}).get("completion_tokens", 0),
                    total_tokens=result.get("usage", {}).get("total_tokens", 0),
                )
                cost = usage.calculate_cost(request.model)
                self._total_cost += cost
                
                logger.info(
                    "holy_sheep_request",
                    model=request.model,
                    latency_ms=latency_ms,
                    cost_usd=cost,
                    total_tokens=usage.total_tokens,
                )
                
                return {
                    "id": result.get("id"),
                    "model": result.get("model"),
                    "choices": result.get("choices"),
                    "usage": usage,
                    "latency_ms": latency_ms,
                }
                
            except httpx.HTTPStatusError as e:
                logger.error(
                    "holy_sheep_http_error",
                    status=e.response.status_code,
                    response=e.response.text,
                )
                raise
            except Exception as e:
                logger.error("holy_sheep_request_error", error=str(e))
                raise
    
    async def chat_completions_stream(
        self, 
        request: ChatCompletionRequest
    ) -> AsyncIterator[Dict[str, Any]]:
        """Stream response từ HolySheep AI"""
        payload = {
            "model": request.model,
            "messages": [
                {"role": m.role, "content": m.content}
                for m in request.messages
            ],
            "temperature": request.temperature,
            "max_tokens": request.max_tokens,
            "stream": True,
        }
        
        async with self.client.stream("POST", "/chat/completions", json=payload) as response:
            response.raise_for_status()
            async for line in response.aiter_lines():
                if line.startswith("data: "):
                    data = line[6:]
                    if data == "[DONE]":
                        break
                    yield json.loads(data)
    
    def get_stats(self) -> Dict[str, Any]:
        """Lấy statistics về API usage"""
        avg_latency = (
            self._total_latency_ms / self._request_count 
            if self._request_count > 0 else 0
        )
        return {
            "total_requests": self._request_count,
            "total_cost_usd": round(self._total_cost, 6),
            "avg_latency_ms": round(avg_latency, 2),
        }


Global client instance

holy_sheep_client = HolySheepClient()

============================================================

MCP Tools - AI Agent Integration

============================================================

async def analyze_document_tool(arguments: Dict) -> Dict[str, Any]: """Tool để phân tích document với AI""" content = arguments.get("content", "") analysis_type = arguments.get("type", "summary") request = ChatCompletionRequest( model="deepseek-v3.2", # $0.42/MTok - tiết kiệm nhất messages=[ ChatMessage( role="system", content=f"Bạn là một chuyên gia phân tích tài liệu. Phân tích theo yêu cầu: {analysis_type}" ), ChatMessage(role="user", content=content), ], temperature=0.3, max_tokens=2048, ) result = await holy_sheep_client.chat_completions(request) return { "analysis": result["choices"][0]["message"]["content"], "tokens_used": result["usage"].total_tokens, "cost_usd": result["usage"].cost_usd, "latency_ms": result["latency_ms"], } async def search_knowledge_base_tool(arguments: Dict) -> Dict[str, Any]: """Tool để search knowledge base""" query = arguments.get("query", "") limit = arguments.get("limit", 5) # Trong thực tế, đây sẽ là search query đến database/vector store # Ở đây demo với AI-powered search request = ChatCompletionRequest( model="gemini-2.5-flash", # $2.50/MTok - nhanh cho search messages=[ ChatMessage( role="system", content="Bạn là một trợ lý tìm kiếm thông minh. Trả lời dựa trên query." ), ChatMessage(role="user", content=f"Tìm kiếm: {query}"), ], temperature=0.2, max_tokens=1024, ) result = await holy_sheep_client.chat_completions(request) return { "query": query, "results": result["choices"][0]["message"]["content"], "count": 1, }

Register tools

tool_registry.register(ToolDefinition( name="analyze_document", description="Phân tích và tóm tắt tài liệu với AI", input_schema={ "type": "object", "properties": { "content": {"type": "string", "description": "Nội dung tài liệu"}, "type": {"type": "string", "enum": ["summary", "key_points", "sentiment"], "default": "summary"}, }, "required": ["content"], }, scope=ToolScope.READ, handler=analyze_document_tool, cacheable=True, ttl=1800, # 30 minutes )) tool_registry.register(ToolDefinition( name="search_knowledge_base", description="Tìm kiếm trong cơ sở tri thức", input_schema={ "type": "object", "properties": { "query": {"type": "string", "description": "Câu truy vấn tìm kiếm"}, "limit": {"type": "integer", "default": 5, "minimum": 1, "maximum": 20}, }, "required": ["query"], }, scope=ToolScope.READ, handler=search_knowledge_base_tool, cacheable=True, ttl=600, # 10 minutes ))

Performance Benchmark và Cost Optimization

Từ kinh nghiệm thực chiến, tôi đã benchmark nhiều cấu hình và đây là kết quả chi tiết:

# benchmark/mcp_benchmark.py - Performance Benchmark Script
import asyncio
import time
import statistics
from typing import List, Dict, Any
import structlog

from config import holy_sheep, MCPServerConfig
from integration.holy_sheep_client import holy_sheep_client, ChatCompletionRequest, ChatMessage
from tools.tool_registry import tool_registry, ToolCall

logger = structlog.get_logger()

@dataclass
class BenchmarkResult:
    name: str
    total_requests: int
    success_count: int
    failure_count: int
    latencies_ms: List[float]
    tokens_per_request: List[int]
    costs_usd: List[float]
    
    @property
    def avg_latency_ms(self) -> float:
        return statistics.mean(self.latencies_ms) if self.latencies_ms else 0
    
    @property
    def p95_latency_ms(self) -> float:
        sorted_latencies = sorted(self.latencies_ms)
        idx = int(len(sorted_latencies) * 0.95)
        return sorted_latencies[idx] if sorted_latencies else 0
    
    @property
    def p99_latency_ms(self) -> float:
        sorted_latencies = sorted(self.latencies_ms)
        idx = int(len(sorted_latencies) * 0.99)
        return sorted_latencies[idx] if sorted_latencies else 0
    
    @property
    def total_cost_usd(self) -> float:
        return sum(self.costs_usd)
    
    @property
    def success_rate(self) -> float:
        return self.success_count / self.total_requests if self.total_requests > 0 else 0
    
    def to_dict(self) -> Dict[str, Any]:
        return {
            "name": self.name,
            "total_requests": self.total_requests,
            "success_count": self.success_count,
            "failure_count": self.failure_count,
            "success_rate": f"{self.success_rate:.2%}",
            "avg_latency_ms": round(self.avg_latency_ms, 2),
            "p95_latency_ms": round(self.p95_latency_ms, 2),
            "p99_latency_ms": round(self.p99_latency_ms, 2),
            "total_cost_usd": round(self.total_cost_usd, 6),
            "avg_cost_per_request": round(
                self.total_cost_usd / self.total_requests, 6
            ) if self.total_requests > 0 else 0,
        }


async def benchmark_concurrent_requests(
    num_requests: int = 100,
    concurrency: int = 10,
) -> BenchmarkResult:
    """Benchmark với concurrent requests"""
    latencies = []
    tokens = []
    costs = []
    success = 0
    failure = 0
    
    test_messages = [
        ChatMessage(role="user", content="Phân tích xu hướng AI 2026 và dự đoán các breakthrough tiếp theo. Include specific examples và technical details."),
        ChatMessage(role="user", content="Viết code Python cho một REST API với FastAPI, include authentication và rate limiting."),
        ChatMessage(role="user", content="So sánh chi phí và hiệu suất của các cloud providers: AWS, GCP, Azure."),
    ]
    
    async def single_request(idx: int):
        nonlocal success, failure
        start = time.time()
        try:
            request = ChatCompletionRequest(
                model="deepseek-v3.2",
                messages=[test_messages[idx % len(test_messages)]],
                max_tokens=512,
            )
            result = await holy_sheep_client.chat_completions(request)
            
            latencies.append((time.time() - start) * 1000)
            tokens.append(result["usage"].total_tokens)
            costs.append(result["usage"].cost_usd)
            success += 1
        except Exception as e:
            failure += 1
            logger.error("benchmark_request_failed", error=str(e))
    
    # Create batches for controlled concurrency
    batches = [
        single_request(i) 
        for i in range(num_requests)
    ]