Nếu bạn đang vận hành hệ thống AI production với hàng triệu request mỗi ngày, bạn sẽ hiểu rằng việc thay đổi model hoặc cập nhật prompt mà không có chiến lược triển khai an toàn có thể gây ra thảm họa. Cách đây 3 tháng, team của mình đã mất 2 ngày để khôi phục sau một lần deploy trực tiếp lên production khiến latency tăng 300%. Từ đó, mình bắt đầu nghiêm túc áp dụng Gray Release (Triển khai dần)A/B Testing API. Trong bài viết này, mình sẽ chia sẻ toàn bộ kiến thức thực chiến, kèm theo code mẫu và chi phí thực tế năm 2026.

1. Tại Sao Cần Gray Release và A/B Testing?

Trước khi đi vào code, hãy cùng mình tính toán chi phí khi không có chiến lược triển khai an toàn:

Bảng So Sánh Chi Phí API Năm 2026 (Output Tokens)

ModelGiá/MTok10M Tokens/thángTiết kiệm vs Claude
Claude Sonnet 4.5$15.00$150.00
GPT-4.1$8.00$80.0047%
Gemini 2.5 Flash$2.50$25.0083%
DeepSeek V3.2$0.42$4.2097%

Như bạn thấy, chuyển từ Claude Sonnet 4.5 sang DeepSeek V3.2 tiết kiệm $145.80/tháng cho 10 triệu tokens. Nhưng nếu bạn deploy trực tiếp mà không test, rủi ro crash hệ thống có thể gây thiệt hại gấp nhiều lần. Với HolySheep AI, bạn nhận được tỷ giá ¥1=$1, thanh toán qua WeChat/Alipay, độ trễ <50ms, và tín dụng miễn phí khi đăng ký.

2. Kiến Trúc Gray Release Với HolySheep AI

Dưới đây là kiến trúc mà mình đã implement thành công cho 3 dự án production:

┌─────────────────────────────────────────────────────────────────┐
│                    GRAY RELEASE ARCHITECTURE                     │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│   Client Request                                                 │
│        │                                                         │
│        ▼                                                         │
│   ┌─────────────┐                                               │
│   │  Router     │ ◄── Traffic Splitter (10% → New, 90% → Old)  │
│   └──────┬──────┘                                               │
│          │                                                       │
│    ┌─────┴─────┐                                                │
│    ▼           ▼                                                │
│ ┌──────┐   ┌──────┐                                            │
│ │ Old  │   │ New  │                                            │
│ │ 90%  │   │ 10%  │                                            │
│ └──┬───┘   └──┬───┘                                            │
│    │          │                                                 │
│    ▼          ▼                                                 │
│ ┌─────────────────────────┐                                     │
│ │     HolySheep API       │                                     │
│ │  https://api.holysheep.ai/v1  │                              │
│ └─────────────────────────┘                                     │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

3. Triển Khai Chi Tiết Với Python

3.1. Cấu Hình API Client Cho Nhiều Model

"""
Gray Release & A/B Testing API Client
Sử dụng HolySheep AI cho tất cả các model
"""

import json
import hashlib
import time
import requests
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass, field
from enum import Enum

class ModelType(Enum):
    """Các model được hỗ trợ với giá 2026"""
    DEEPSEEK_V3_2 = {
        "name": "DeepSeek V3.2",
        "price_per_mtok": 0.42,
        "context_window": 128000,
        "provider": "holysheep"
    }
    GEMINI_FLASH_2_5 = {
        "name": "Gemini 2.5 Flash",
        "price_per_mtok": 2.50,
        "context_window": 1000000,
        "provider": "holysheep"
    }
    GPT_4_1 = {
        "name": "GPT-4.1",
        "price_per_mtok": 8.00,
        "context_window": 128000,
        "provider": "holysheep"
    }
    CLAUDE_SONNET_4_5 = {
        "name": "Claude Sonnet 4.5",
        "price_per_mtok": 15.00,
        "context_window": 200000,
        "provider": "holysheep"
    }

@dataclass
class TrafficConfig:
    """Cấu hình phân chia traffic cho A/B Testing"""
    model_a: ModelType
    model_b: ModelType
    percentage_a: float  # 0.0 - 1.0
    experiment_name: str
    min_latency_threshold_ms: float = 5000
    error_rate_threshold: float = 0.05

@dataclass
class RequestMetrics:
    """Metrics cho mỗi request"""
    request_id: str
    model: str
    latency_ms: float
    input_tokens: int
    output_tokens: int
    cost_usd: float
    success: bool
    error_message: Optional[str] = None

class GrayReleaseClient:
    """
    Client hỗ trợ Gray Release và A/B Testing
    Tích hợp HolySheep AI với base_url: https://api.holysheep.ai/v1
    """
    
    BASE_URL = "https://api.holysheep.ai/v1"
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.metrics: List[RequestMetrics] = []
        self.experiments: Dict[str, TrafficConfig] = {}
        self._validate_api_key()
    
    def _validate_api_key(self):
        """Validate API key với HolySheep"""
        # Thay vì gọi trực tiếp, chúng ta kiểm tra format
        if not self.api_key or self.api_key == "YOUR_HOLYSHEEP_API_KEY":
            raise ValueError(
                "Vui lòng cung cấp API key hợp lệ từ HolySheep AI. "
                "Đăng ký tại: https://www.holysheep.ai/register"
            )
        print(f"✅ API Key validated for HolySheep AI")
        print(f"📊 Base URL: {self.BASE_URL}")
    
    def _get_model_id(self, model_type: ModelType) -> str:
        """Map model type sang model ID của provider"""
        model_mapping = {
            ModelType.DEEPSEEK_V3_2: "deepseek-v3.2",
            ModelType.GEMINI_FLASH_2_5: "gemini-2.5-flash",
            ModelType.GPT_4_1: "gpt-4.1",
            ModelType.CLAUDE_SONNET_4_5: "claude-sonnet-4.5"
        }
        return model_mapping.get(model_type, "deepseek-v3.2")
    
    def _hash_user_id(self, user_id: str, experiment_name: str) -> float:
        """Hash user_id để đảm bảo consistency cho cùng user"""
        hash_input = f"{experiment_name}:{user_id}"
        hash_value = hashlib.md5(hash_input.encode()).hexdigest()
        return int(hash_value, 16) / (16 ** 32)
    
    def _should_use_model_a(
        self, 
        user_id: str, 
        config: TrafficConfig
    ) -> bool:
        """Quyết định user nhận model nào dựa trên hash"""
        hash_value = self._hash_user_id(user_id, config.experiment_name)
        return hash_value < config.percentage_a
    
    def _calculate_cost(
        self, 
        input_tokens: int, 
        output_tokens: int, 
        model: ModelType
    ) -> float:
        """Tính chi phí theo giá 2026"""
        return (output_tokens / 1_000_000) * model.value["price_per_mtok"]
    
    def call_chat_completion(
        self,
        messages: List[Dict],
        user_id: str,
        experiment_name: str,
        **kwargs
    ) -> Tuple[Dict, RequestMetrics]:
        """
        Gọi API với A/B Testing routing
        Returns: (response, metrics)
        """
        start_time = time.time()
        
        # Lấy experiment config
        if experiment_name not in self.experiments:
            # Default: 50/50 DeepSeek V3.2 vs Gemini 2.5 Flash
            self.experiments[experiment_name] = TrafficConfig(
                model_a=ModelType.DEEPSEEK_V3_2,
                model_b=ModelType.GEMINI_FLASH_2_5,
                percentage_a=0.5,
                experiment_name=experiment_name
            )
        
        config = self.experiments[experiment_name]
        
        # Routing decision
        if self._should_use_model_a(user_id, config):
            selected_model = config.model_a
        else:
            selected_model = config.model_b
        
        model_id = self._get_model_id(selected_model)
        request_id = f"req_{int(time.time() * 1000)}"
        
        # Gọi HolySheep API
        try:
            response = self._make_request(
                model_id=model_id,
                messages=messages,
                request_id=request_id,
                **kwargs
            )
            
            latency_ms = (time.time() - start_time) * 1000
            input_tokens = response.get("usage", {}).get("prompt_tokens", 0)
            output_tokens = response.get("usage", {}).get("completion_tokens", 0)
            cost = self._calculate_cost(input_tokens, output_tokens, selected_model)
            
            metrics = RequestMetrics(
                request_id=request_id,
                model=model_id,
                latency_ms=latency_ms,
                input_tokens=input_tokens,
                output_tokens=output_tokens,
                cost_usd=cost,
                success=True
            )
            
            self.metrics.append(metrics)
            return response, metrics
            
        except Exception as e:
            latency_ms = (time.time() - start_time) * 1000
            metrics = RequestMetrics(
                request_id=request_id,
                model=model_id,
                latency_ms=latency_ms,
                input_tokens=0,
                output_tokens=0,
                cost_usd=0,
                success=False,
                error_message=str(e)
            )
            self.metrics.append(metrics)
            raise
    
    def _make_request(
        self, 
        model_id: str, 
        messages: List[Dict],
        request_id: str,
        **kwargs
    ) -> Dict:
        """Thực hiện request đến HolySheep API"""
        url = f"{self.BASE_URL}/chat/completions"
        
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json",
            "X-Request-ID": request_id
        }
        
        payload = {
            "model": model_id,
            "messages": messages,
            **kwargs
        }
        
        # Sử dụng requests thay vì OpenAI client
        response = requests.post(
            url,
            headers=headers,
            json=payload,
            timeout=30
        )
        
        if response.status_code != 200:
            raise Exception(
                f"API Error {response.status_code}: {response.text}"
            )
        
        return response.json()
    
    def get_experiment_stats(self, experiment_name: str) -> Dict:
        """Lấy thống kê experiment"""
        relevant_metrics = [
            m for m in self.metrics 
            if experiment_name in m.request_id
        ]
        
        if not relevant_metrics:
            return {"error": "No data for this experiment"}
        
        successful = [m for m in relevant_metrics if m.success]
        failed = [m for m in relevant_metrics if not m.success]
        
        return {
            "total_requests": len(relevant_metrics),
            "successful": len(successful),
            "failed": len(failed),
            "error_rate": len(failed) / len(relevant_metrics),
            "avg_latency_ms": sum(m.latency_ms for m in successful) / len(successful) if successful else 0,
            "total_cost_usd": sum(m.cost_usd for m in relevant_metrics),
            "by_model": self._group_by_model(relevant_metrics)
        }
    
    def _group_by_model(self, metrics: List[RequestMetrics]) -> Dict:
        """Group metrics theo model"""
        grouped = {}
        for m in metrics:
            if m.model not in grouped:
                grouped[m.model] = {
                    "count": 0,
                    "avg_latency_ms": 0,
                    "total_cost": 0,
                    "errors": 0
                }
            grouped[m.model]["count"] += 1
            grouped[m.model]["total_cost"] += m.cost_usd
            if not m.success:
                grouped[m.model]["errors"] += 1
        
        for model_data in grouped.values():
            if model_data["count"] > 0:
                model_data["avg_latency_ms"] = (
                    sum(m.latency_ms for m in metrics if m.model == model_data) 
                    / model_data["count"]
                )
        
        return grouped


Ví dụ sử dụng

if __name__ == "__main__": # Khởi tạo client với API key từ HolySheep AI client = GrayReleaseClient(api_key="YOUR_HOLYSHEEP_API_KEY") # Cấu hình experiment: 20% DeepSeek V3.2, 80% Gemini 2.5 Flash client.experiments["model_comparison"] = TrafficConfig( model_a=ModelType.DEEPSEEK_V3_2, model_b=ModelType.GEMINI_FLASH_2_5, percentage_a=0.20, experiment_name="model_comparison" ) # Gọi API với user cố định để test consistency messages = [ {"role": "user", "content": "Giải thích sự khác biệt giữa REST và GraphQL"} ] response, metrics = client.call_chat_completion( messages=messages, user_id="user_12345", experiment_name="model_comparison", temperature=0.7, max_tokens=500 ) print(f"Model sử dụng: {metrics.model}") print(f"Latency: {metrics.latency_ms:.2f}ms") print(f"Cost: ${metrics.cost_usd:.4f}") print(f"Response: {response['choices'][0]['message']['content'][:100]}...")

3.2. Progressive Rollout Manager

"""
Progressive Rollout Manager - Tăng traffic dần theo thời gian
Triển khai an toàn từ 1% → 100%
"""

import time
import threading
from datetime import datetime, timedelta
from typing import Dict, Callable, Optional
from dataclasses import dataclass
from enum import Enum

class RolloutStage(Enum):
    """Các giai đoạn rollout"""
    STAGE_0_INITIAL = 0.01      # 1% - Internal testing
    STAGE_1_CANARY = 0.05       # 5% - Canary release
    STAGE_2_EARLY_ADOPTERS = 0.10  # 10% - Early adopters
    STAGE_3_25_PERCENT = 0.25   # 25% - Quarter rollout
    STAGE_4_HALF = 0.50         # 50% - Half rollout
    STAGE_5_MAJORITY = 0.75     # 75% - Majority
    STAGE_6_FULL = 1.00         # 100% - Full rollout

@dataclass
class RolloutConfig:
    """Cấu hình rollout"""
    name: str
    target_percentage: float
    stage_duration_hours: int
    health_check_fn: Optional[Callable] = None
    auto_rollback_threshold: float = 0.02  # 2% error rate

@dataclass
class RolloutStatus:
    """Trạng thái rollout hiện tại"""
    config_name: str
    current_stage: RolloutStage
    current_percentage: float
    started_at: datetime
    health_score: float
    error_rate: float
    avg_latency_ms: float
    total_requests: int
    is_healthy: bool
    auto_rollback_triggered: bool = False

class ProgressiveRolloutManager:
    """
    Quản lý Progressive Rollout với auto-rollback
    """
    
    def __init__(self, gray_client):
        self.client = gray_client
        self.rollouts: Dict[str, RolloutStatus] = {}
        self.configs: Dict[str, RolloutConfig] = {}
        self._monitor_thread: Optional[threading.Thread] = None
        self._stop_monitoring = threading.Event()
    
    def register_rollout(self, config: RolloutConfig):
        """Đăng ký một rollout mới"""
        self.configs[config.name] = config
        
        initial_stage = RolloutStage.STAGE_0_INITIAL
        
        self.rollouts[config.name] = RolloutStatus(
            config_name=config.name,
            current_stage=initial_stage,
            current_percentage=initial_stage.value,
            started_at=datetime.now(),
            health_score=1.0,
            error_rate=0.0,
            avg_latency_ms=0.0,
            total_requests=0,
            is_healthy=True
        )
        
        print(f"🚀 Rollout '{config.name}' registered at {initial_stage.value*100}%")
    
    def update_traffic_percentage(self, config_name: str, percentage: float):
        """Cập nhật traffic percentage cho experiment"""
        if config_name not in self.configs:
            raise ValueError(f"Rollout '{config_name}' not found")
        
        # Tạo experiment mới với percentage
        traffic_config = TrafficConfig(
            model_a=ModelType.DEEPSEEK_V3_2,
            model_b=ModelType.GEMINI_FLASH_2_5,
            percentage_a=percentage,
            experiment_name=config_name
        )
        
        self.client.experiments[config_name] = traffic_config
        
        if config_name in self.rollouts:
            self.rollouts[config_name].current_percentage = percentage
        
        print(f"📊 Traffic updated: {percentage*100}% for '{config_name}'")
    
    def check_health_and_progress(self, config_name: str) -> bool:
        """
        Kiểm tra health và tự động tiến lên stage tiếp theo
        Returns: True nếu healthy, False nếu cần rollback
        """
        if config_name not in self.rollouts:
            return False
        
        status = self.rollouts[config_name]
        config = self.configs[config_name]
        
        # Lấy stats từ client
        stats = self.client.get_experiment_stats(config_name)
        
        if "error" in stats:
            return True
        
        status.error_rate = stats.get("error_rate", 0)
        status.avg_latency_ms = stats.get("avg_latency_ms", 0)
        status.total_requests = stats.get("total_requests", 0)
        
        # Tính health score dựa trên error rate và latency
        error_penalty = status.error_rate * 100  # Max 100% penalty
        latency_penalty = min(status.avg_latency_ms / 5000, 1.0) * 50  # Max 50 penalty if > 5s
        
        status.health_score = max(0, 100 - error_penalty - latency_penalty) / 100
        status.is_healthy = status.health_score > 0.8
        
        print(f"📈 Health check for '{config_name}':")
        print(f"   - Error rate: {status.error_rate*100:.2f}%")
        print(f"   - Avg latency: {status.avg_latency_ms:.2f}ms")
        print(f"   - Health score: {status.health_score*100:.1f}%")
        print(f"   - Total requests: {status.total_requests}")
        
        # Auto rollback nếu error rate vượt ngưỡng
        if status.error_rate > config.auto_rollback_threshold:
            print(f"🚨 AUTO ROLLBACK TRIGGERED for '{config_name}'")
            print(f"   Error rate {status.error_rate*100:.2f}% > threshold {config.auto_rollback_threshold*100}%")
            status.auto_rollback_triggered = True
            status.is_healthy = False
            return False
        
        # Kiểm tra xem đã đủ thời gian để chuyển stage chưa
        stage_duration = timedelta(hours=config.stage_duration_hours)
        time_in_stage = datetime.now() - status.started_at
        
        if time_in_stage >= stage_duration and status.is_healthy:
            self._progress_to_next_stage(config_name)
            return True
        
        return True
    
    def _progress_to_next_stage(self, config_name: str):
        """Chuyển sang stage tiếp theo"""
        status = self.rollouts[config_name]
        
        # Tìm stage tiếp theo
        stages = list(RolloutStage)
        current_index = stages.index(status.current_stage)
        
        if current_index < len(stages) - 1:
            next_stage = stages[current_index + 1]
            status.current_stage = next_stage
            status.started_at = datetime.now()
            
            self.update_traffic_percentage(config_name, next_stage.value)
            
            print(f"🎉 Progressive rollout: {next_stage.name} ({next_stage.value*100}%)")
        else:
            print(f"✅ Rollout '{config_name}' completed - 100% traffic")
    
    def rollback(self, config_name: str):
        """Rollback về stage trước hoặc 0%"""
        if config_name not in self.rollouts:
            return
        
        status = self.rollouts[config_name]
        stages = list(RolloutStage)
        current_index = stages.index(status.current_stage)
        
        if current_index > 0:
            prev_stage = stages[current_index - 1]
            status.current_stage = prev_stage
            status.started_at = datetime.now()
            status.auto_rollback_triggered = False
            
            self.update_traffic_percentage(config_name, prev_stage.value)
            
            print(f"↩️ Rollback to: {prev_stage.name} ({prev_stage.value*100}%)")
        else:
            # Rollback hoàn toàn
            self.update_traffic_percentage(config_name, 0)
            print(f"🚫 Full rollback for '{config_name}' - 0% traffic")
    
    def get_rollout_status(self, config_name: str) -> Optional[RolloutStatus]:
        """Lấy trạng thái rollout"""
        return self.rollouts.get(config_name)
    
    def start_monitoring(self, interval_seconds: int = 60):
        """Bắt đầu monitoring tự động"""
        self._stop_monitoring.clear()
        
        def monitor_loop():
            while not self._stop_monitoring.is_set():
                for config_name in self.configs:
                    try:
                        self.check_health_and_progress(config_name)
                    except Exception as e:
                        print(f"Monitor error for '{config_name}': {e}")
                
                time.sleep(interval_seconds)
        
        self._monitor_thread = threading.Thread(target=monitor_loop, daemon=True)
        self._monitor_thread.start()
        print("🔄 Monitoring started")
    
    def stop_monitoring(self):
        """Dừng monitoring"""
        self._stop_monitoring.set()
        if self._monitor_thread:
            self._monitor_thread.join(timeout=5)
        print("⏹️ Monitoring stopped")


Ví dụ sử dụng Progressive Rollout

if __name__ == "__main__": # Khởi tạo client = GrayReleaseClient(api_key="YOUR_HOLYSHEEP_API_KEY") rollout_manager = ProgressiveRolloutManager(client) # Đăng ký rollout với cấu hình rollout_config = RolloutConfig( name="deepseek-v32-rollout", target_percentage=1.0, # Target 100% stage_duration_hours=4, # Mỗi stage 4 tiếng auto_rollback_threshold=0.02 # 2% error rate ) rollout_manager.register_rollout(rollout_config) # Bắt đầu monitoring rollout_manager.start_monitoring(interval_seconds=30) # Simulate một số request để test for i in range(100): try: response, metrics = client.call_chat_completion( messages=[{"role": "user", "content": f"Test request {i}"}], user_id=f"user_{i % 1000}", experiment_name="deepseek-v32-rollout" ) print(f"Request {i}: {metrics.model} - {metrics.latency_ms:.2f}ms") except Exception as e: print(f"Request {i} failed: {e}") time.sleep(0.1) # Kiểm tra health rollout_manager.check_health_and_progress("deepseek-v32-rollout") # Dừng khi xong rollout_manager.stop_monitoring()

4. A/B Testing Dashboard và Analytics

"""
A/B Testing Dashboard - Real-time Analytics
Theo dõi performance của các model trong experiment
"""

import json
from datetime import datetime, timedelta
from typing import List, Dict, Any
from collections import defaultdict
import statistics

class ABTestingDashboard:
    """
    Dashboard để visualize kết quả A/B test
    """
    
    def __init__(self, gray_client: GrayReleaseClient):
        self.client = gray_client
        self.experiment_history: Dict[str, List[Dict]] = defaultdict(list)
    
    def record_decision(
        self, 
        experiment_name: str,
        user_id: str,
        selected_model: str,
        response_time_ms: float,
        success: bool,
        cost_usd: float
    ):
        """Ghi lại một quyết định routing"""
        decision = {
            "timestamp": datetime.now().isoformat(),
            "user_id": user_id,
            "model": selected_model,
            "response_time_ms": response_time_ms,
            "success": success,
            "cost_usd": cost_usd
        }
        self.experiment_history[experiment_name].append(decision)
    
    def generate_report(self, experiment_name: str, hours: int = 24) -> Dict:
        """Tạo báo cáo chi tiết cho experiment"""
        cutoff = datetime.now() - timedelta(hours=hours)
        
        decisions = [
            d for d in self.experiment_history[experiment_name]
            if datetime.fromisoformat(d["timestamp"]) >= cutoff
        ]
        
        if not decisions:
            return {"error": "No data in the specified time range"}
        
        # Group by model
        by_model = defaultdict(list)
        for d in decisions:
            by_model[d["model"]].append(d)
        
        report = {
            "experiment_name": experiment_name,
            "report_period_hours": hours,
            "total_requests": len(decisions),
            "generated_at": datetime.now().isoformat(),
            "models": {}
        }
        
        for model, data in by_model.items():
            successful = [d for d in data if d["success"]]
            failed = [d for d in data if not d["success"]]
            
            response_times = [d["response_time_ms"] for d in successful]
            
            report["models"][model] = {
                "request_count": len(data),
                "percentage": len(data) / len(decisions) * 100,
                "successful": len(successful),
                "failed": len(failed),
                "error_rate": len(failed) / len(data) * 100 if data else 0,
                "avg_response_time_ms": statistics.mean(response_times) if response_times else 0,
                "median_response_time_ms": statistics.median(response_times) if response_times else 0,
                "p95_response_time_ms": (
                    sorted(response_times)[int(len(response_times) * 0.95)]
                    if response_times else 0
                ),
                "p99_response_time_ms": (
                    sorted(response_times)[int(len(response_times) * 0.99)]
                    if response_times else 0
                ),
                "total_cost_usd": sum(d["cost_usd"] for d in data),
                "requests_per_minute": len(data) / (hours * 60) if hours > 0 else 0
            }
        
        # Calculate cost savings if comparing
        if len(report["models"]) >= 2:
            models = list(report["models"].keys())
            cost_a = report["models"][models[0]]["total_cost_usd"]
            cost_b = report["models"][models[1]]["total_cost_usd"]
            
            report["cost_comparison"] = {
                "model_a": models[0],
                "model_b": models[1],
                "cost_a_usd": cost_a,
                "cost_b_usd": cost_b,
                "savings_usd": abs(cost_a - cost_b),
                "savings_percentage": abs(cost_a - cost_b) / max(cost_a, cost_b) * 100 if max(cost_a, cost_b) > 0 else 0
            }
        
        return report
    
    def print_dashboard(self, experiment_name: str, hours: int = 24):
        """In dashboard ra console"""
        report = self.generate_report(experiment_name, hours)
        
        if "error" in report:
            print(f"❌ {report['error']}")
            return
        
        print("=" * 70)
        print(f"📊 A/B TESTING DASHBOARD: {experiment_name}")
        print(f"⏰ Report period: Last {report['report_period_hours']} hours")
        print(f"🕐 Generated at: {report['generated_at']}")
        print("=" * 70)
        print(f"\n📈 Total Requests: {report['total_requests']}")
        
        print("\n" + "-" * 70)
        print(f"{'Model':<25} {'Requests':<10} {'%':<8} {'Error%':<10} {'Avg(ms)':<12} {'Cost($)':<10}")
        print("-" * 70)
        
        for model, stats in report["models"].items():
            print(
                f"{model:<25} "
                f"{stats['request_count']:<10} "
                f"{stats['percentage']:<8.1f} "
                f"{stats['error_rate']:<10.2f} "
                f"{stats['avg_response_time_ms']:<12.2f} "
                f"{stats['total_cost_usd']:<10.4f}"
            )
        
        print("-" * 70)
        
        if "cost_comparison" in report:
            cc = report["cost_comparison"]
            print(f"\n💰 COST COMPARISON ({hours}h projection):")
            print(f"   {cc['model_a']}: ${cc['cost_a_usd']:.4f}")
            print(f"   {cc['model_b']}: ${cc['cost_b_usd']:.4f}")
            print(f"   Savings: ${cc['savings_usd']:.4f} ({cc['savings_percentage']:.1f}%)")
            
            # Projection for 10M tokens
            total_output_tokens = sum(
                m.get("total_cost_usd", 0) / (m.get("avg_cost_per_token", 0.000001) or 0.000001)
                for m in report["models"].values()
            )
            
            print(f"\n📊 COST PROJECTION FOR 10M TOKENS/MONTH:")
            for model, stats in report["models"].items():
                model_price = 0.42 if "deepseek" in model.lower() else (
                    2.50 if "gemini" in model.lower() else 8.00
                )
                monthly_cost = 10 * model_price
                print(f"   {model}: ${monthly_cost:.2f}/month")
        
        print("\n" + "=" * 70)
    
    def export_json(self, experiment_name: str, filename: str, hours: int =