Mở Đầu: Tại Sao Cần Hệ Thống AI Dự Đoán Cháy Thông Minh?

Trong bối cảnh IoT và AI phát triển mạnh mẽ năm 2026, hệ thống phòng cháy chữa cháy (PCCC) thông minh đã trở thành yêu cầu bắt buộc đối với các khu công nghiệp, tòa nhà cao tầng và khu đô thị đông đúc. Bài viết này sẽ hướng dẫn bạn xây dựng một HolySheep 智慧消防应急 Agent hoàn chỉnh, tích hợp GPT-5 cho phân tích火情 (tình huống cháy), Gemini cho trích xuất frame từ video camera, và cấu hình SLA限流重试 (rate limiting với retry) để đảm bảo độ tin cậy cao.

Bảng So Sánh: HolySheep AI vs API Chính Thức vs Dịch Vụ Relay

Tiêu chí HolySheep AI API Chính Thức (OpenAI/Anthropic/Google) Dịch Vụ Relay Khác
Tỷ giá ¥1 = $1 (tiết kiệm 85%+) $1 = ¥7.2 (quy đổi cao) Tùy nhà cung cấp, thường 10-30% premium
Thanh toán WeChat, Alipay, Visa Thẻ quốc tế (khó ở Việt Nam/Trung Quốc) Hạn chế phương thức
Độ trễ trung bình <50ms 100-300ms (do khoảng cách địa lý) 80-200ms
Tín dụng miễn phí ✓ Có khi đăng ký $5-18 cho thử nghiệm Ít khi có
GPT-4.1 $8/MTok $8/MTok $9-12/MTok
Claude Sonnet 4.5 $15/MTok $15/MTok $17-20/MTok
Gemini 2.5 Flash $2.50/MTok $2.50/MTok $3-5/MTok
DeepSeek V3.2 $0.42/MTok Không hỗ trợ $0.50-0.80/MTok
Rate Limit Tùy gói, linh hoạt Cố định theo tier Thường thấp

Kiến Trúc Hệ Thống HolySheep 智慧消防应急 Agent

Trước khi đi vào code chi tiết, chúng ta cần hiểu kiến trúc tổng thể của hệ thống:

┌─────────────────────────────────────────────────────────────────────┐
│                    HOLYSHEEP 智慧消防应急 AGENT                       │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌──────────┐    ┌──────────────┐    ┌─────────────────────────┐   │
│  │ Camera   │───▶│ Video Stream │───▶│ Gemini Video抽帧模块    │   │
│  │ (RTSP)   │    │ Processor    │    │ (Frame Extraction)      │   │
│  └──────────┘    └──────────────┘    └───────────┬─────────────┘   │
│                                                  │                  │
│                                                  ▼                  │
│  ┌──────────┐    ┌──────────────┐    ┌─────────────────────────┐   │
│  │ IoT      │───▶│ Sensor Data  │───▶│ Multi-Model Analysis    │   │
│  │ Sensors  │    │ Aggregator   │    │ - GPT-5 火情研判       │   │
│  └──────────┘    └──────────────┘    │ - Claude 火势预测       │   │
│                                       │ - DeepSeek 成本优化    │   │
│                                       └───────────┬─────────────┘   │
│                                                   │                  │
│                                                   ▼                  │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │              SLA Rate Limiter + Retry Manager                  │  │
│  │              - Token Bucket Algorithm                         │  │
│  │              - Exponential Backoff                           │  │
│  │              - Circuit Breaker Pattern                       │  │
│  └──────────────────────────────────────────────────────────────┘  │
│                                                   │                  │
│                                                   ▼                  │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────────────┐  │
│  │ Alert System │◀───│ Decision     │◀───│ Fire Assessment       │  │
│  │ (SMS/Email)  │    │ Engine       │    │ Report Generator      │  │
│  └──────────────┘    └──────────────┘    └──────────────────────┘  │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Phần 1: Cấu Hình API Client Với HolySheep

// holy_sheep_fire_agent.js
// HolySheep AI - Smart Fire Protection Emergency Agent
// base_url: https://api.holysheep.ai/v1

import axios from 'axios';
import { RateLimiter } from './sla_rate_limiter.js';
import { VideoFrameExtractor } from './gemini_video_processor.js';
import { FireAnalysisEngine } from './gpt5_fire_analyzer.js';

class HolySheepFireAgent {
    constructor(config) {
        this.baseURL = 'https://api.holysheep.ai/v1';
        this.apiKey = process.env.HOLYSHEEP_API_KEY; // YOUR_HOLYSHEEP_API_KEY
        
        // Initialize HTTP client với HolySheep endpoint
        this.client = axios.create({
            baseURL: this.baseURL,
            headers: {
                'Authorization': Bearer ${this.apiKey},
                'Content-Type': 'application/json'
            },
            timeout: 30000 // 30 seconds timeout
        });

        // SLA Rate Limiter Configuration
        this.rateLimiter = new RateLimiter({
            requestsPerSecond: 10,
            burstSize: 50,
            maxRetries: 5,
            baseDelay: 1000,    // 1 giây delay ban đầu
            maxDelay: 32000,    // Tối đa 32 giây
            circuitBreakerThreshold: 5, // Mở circuit sau 5 lỗi liên tiếp
            circuitBreakerTimeout: 60000 // Reset sau 60 giây
        });

        // Initialize model processors
        this.geminiProcessor = new VideoFrameExtractor(this.client);
        this.fireAnalyzer = new FireAnalysisEngine(this.client);
    }

    // Phương thức gọi API với retry và rate limiting
    async chatCompletion(model, messages, options = {}) {
        return this.rateLimiter.execute(async () => {
            try {
                const response = await this.client.post('/chat/completions', {
                    model: model,
                    messages: messages,
                    temperature: options.temperature || 0.3,
                    max_tokens: options.maxTokens || 2000
                });
                
                // Reset circuit breaker khi thành công
                this.rateLimiter.resetCircuitBreaker();
                
                return response.data;
            } catch (error) {
                // Xử lý lỗi rate limit (429)
                if (error.response?.status === 429) {
                    const retryAfter = error.response.headers['retry-after'] || 5;
                    throw new RateLimitError(Rate limited. Retry after ${retryAfter}s, retryAfter);
                }
                throw error;
            }
        });
    }

    // Gọi API Claude cho phân tích火势预测
    async claudeAnalysis(imageData, fireContext) {
        return this.chatCompletion('claude-sonnet-4.5', [
            {
                role: 'user',
                content: [
                    { type: 'text', text: '分析以下火情图像并预测火势蔓延趋势:' },
                    { type: 'image', source: { type: 'base64', media_type: 'image/jpeg', data: imageData } }
                ]
            }
        ], { maxTokens: 1500 });
    }

    // Gọi API Gemini cho视频抽帧
    async extractVideoFrames(videoUrl) {
        return this.geminiProcessor.extractKeyFrames(videoUrl, {
            maxFrames: 10,
            interval: 2, // Mỗi 2 giây
            quality: 'high'
        });
    }
}

module.exports = { HolySheepFireAgent };

Phần 2: SLA Rate Limiter và Retry Manager Chi Tiết

// sla_rate_limiter.js
// SLA限流重试配置 - Rate Limiting với Exponential Backoff

class RateLimitError extends Error {
    constructor(message, retryAfter) {
        super(message);
        this.name = 'RateLimitError';
        this.retryAfter = retryAfter;
    }
}

class CircuitBreakerError extends Error {
    constructor(message) {
        super(message);
        this.name = 'CircuitBreakerError';
    }
}

class RateLimiter {
    constructor(config) {
        // Token Bucket Configuration
        this.tokens = config.burstSize || 50;
        this.maxTokens = config.burstSize || 50;
        this.refillRate = config.requestsPerSecond || 10;
        this.lastRefill = Date.now();

        // Retry Configuration
        this.maxRetries = config.maxRetries || 5;
        this.baseDelay = config.baseDelay || 1000;
        this.maxDelay = config.maxDelay || 32000;

        // Circuit Breaker Configuration
        this.failureThreshold = config.circuitBreakerThreshold || 5;
        this.failureCount = 0;
        this.circuitOpen = false;
        this.circuitOpenTime = null;
        this.circuitTimeout = config.circuitBreakerTimeout || 60000;

        // Metrics
        this.totalRequests = 0;
        this.successfulRequests = 0;
        this.failedRequests = 0;
        this.totalLatency = 0;
    }

    // Refill tokens dựa trên thời gian đã trôi qua
    refillTokens() {
        const now = Date.now();
        const timePassed = (now - this.lastRefill) / 1000;
        const tokensToAdd = timePassed * this.refillRate;
        
        this.tokens = Math.min(this.maxTokens, this.tokens + tokensToAdd);
        this.lastRefill = now;
    }

    // Lấy token, chờ nếu cần
    async acquireToken() {
        this.refillTokens();

        if (this.tokens < 1) {
            const waitTime = (1 - this.tokens) / this.refillRate * 1000;
            await this.sleep(waitTime);
            this.refillTokens();
        }

        this.tokens -= 1;
    }

    // Kiểm tra circuit breaker
    checkCircuitBreaker() {
        if (!this.circuitOpen) return;

        const timeSinceOpen = Date.now() - this.circuitOpenTime;
        if (timeSinceOpen > this.circuitTimeout) {
            // Thử reset circuit breaker
            this.circuitOpen = false;
            this.failureCount = 0;
            console.log('🔄 Circuit Breaker reset - Allowing requests');
        } else {
            throw new CircuitBreakerError('Circuit breaker is OPEN. Too many failures.');
        }
    }

    // Ghi nhận lỗi
    recordFailure() {
        this.failureCount++;
        this.failedRequests++;

        if (this.failureCount >= this.failureThreshold) {
            this.circuitOpen = true;
            this.circuitOpenTime = Date.now();
            console.log('⚠️ Circuit Breaker OPENED - Too many failures');
        }
    }

    // Reset circuit breaker khi thành công
    resetCircuitBreaker() {
        this.failureCount = 0;
        if (this.circuitOpen) {
            this.circuitOpen = false;
            console.log('✅ Circuit Breaker CLOSED - Service recovered');
        }
    }

    // Tính toán exponential backoff delay
    calculateBackoff(attempt) {
        // Exponential: 1s, 2s, 4s, 8s, 16s, 32s...
        const exponentialDelay = this.baseDelay * Math.pow(2, attempt);
        
        // Thêm jitter ngẫu nhiên (±25%) để tránh thundering herd
        const jitter = exponentialDelay * 0.25 * (Math.random() * 2 - 1);
        
        return Math.min(exponentialDelay + jitter, this.maxDelay);
    }

    // Thực thi request với retry logic
    async execute(requestFn) {
        this.totalRequests++;
        let lastError;

        for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
            // Kiểm tra circuit breaker trước mỗi attempt
            this.checkCircuitBreaker();

            // Chờ lấy token
            await this.acquireToken();

            const startTime = Date.now();

            try {
                const result = await requestFn();
                
                // Ghi nhận metrics
                const latency = Date.now() - startTime;
                this.totalLatency += latency;
                this.successfulRequests++;
                
                console.log(✅ Request succeeded in ${latency}ms (attempt ${attempt + 1}));
                return result;

            } catch (error) {
                lastError = error;
                const latency = Date.now() - startTime;
                
                console.log(❌ Request failed (attempt ${attempt + 1}/${this.maxRetries + 1}): ${error.message});

                // Xử lý lỗi rate limit - không tính vào retry
                if (error instanceof RateLimitError) {
                    const waitTime = error.retryAfter * 1000;
                    console.log(⏳ Rate limited, waiting ${waitTime}ms...);
                    await this.sleep(waitTime);
                    continue;
                }

                // Nếu là lỗi không thể retry (4xx client errors)
                if (error.response?.status >= 400 && error.response?.status < 500) {
                    if (error.response?.status === 401 || error.response?.status === 403) {
                        throw new Error('Authentication failed. Check your API key.');
                    }
                    // Các lỗi 4xx khác không retry
                    throw error;
                }

                // Tính backoff delay
                if (attempt < this.maxRetries) {
                    const backoffDelay = this.calculateBackoff(attempt);
                    console.log(⏳ Retrying in ${Math.round(backoffDelay)}ms...);
                    await this.sleep(backoffDelay);
                }

                this.recordFailure();
            }
        }

        // Đã hết retries
        throw lastError;
    }

    // Lấy metrics hiện tại
    getMetrics() {
        return {
            totalRequests: this.totalRequests,
            successfulRequests: this.successfulRequests,
            failedRequests: this.failedRequests,
            successRate: this.totalRequests > 0 
                ? ((this.successfulRequests / this.totalRequests) * 100).toFixed(2) + '%' 
                : 'N/A',
            averageLatency: this.totalRequests > 0 
                ? (this.totalLatency / this.totalRequests).toFixed(2) + 'ms' 
                : 'N/A',
            circuitBreakerOpen: this.circuitOpen,
            currentTokens: this.tokens.toFixed(2)
        };
    }

    sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
}

module.exports = { RateLimiter, RateLimitError, CircuitBreakerError };

Phần 3: Gemini Video Frame Extraction Cho Phân Tích火情

// gemini_video_processor.js
// Gemini 视频抽帧模块 - Trích xuất frame từ video camera

const { spawn } = require('child_process');
const fs = require('fs').promises;
const path = require('path');

class VideoFrameExtractor {
    constructor(httpClient) {
        this.client = httpClient;
        this.tempDir = '/tmp/fire_analysis_frames';
    }

    // Khởi tạo thư mục tạm
    async initialize() {
        try {
            await fs.mkdir(this.tempDir, { recursive: true });
        } catch (e) {
            // Thư mục đã tồn tại
        }
    }

    // Trích xuất frames từ video stream (RTSP)
    async extractFramesFromRTSP(rtspUrl, options = {}) {
        const {
            maxFrames = 10,
            interval = 2, // seconds
            quality = 'high' // low, medium, high
        } = options;

        const outputPattern = path.join(this.tempDir, 'frame_%04d.jpg');
        const timestamp = Date.now();
        const outputDir = path.join(this.tempDir, session_${timestamp});
        
        await fs.mkdir(outputDir, { recursive: true });

        // Sử dụng FFmpeg để trích xuất frames
        const ffmpegArgs = [
            '-rtsp_transport', 'tcp',
            '-i', rtspUrl,
            '-vf', fps=1/${interval},
            '-frames:v', maxFrames.toString(),
            '-q:v', quality === 'high' ? '2' : quality === 'medium' ? '5' : '10',
            '-f', 'image2',
            path.join(outputDir, 'frame_%04d.jpg')
        ];

        return new Promise((resolve, reject) => {
            const ffmpeg = spawn('ffmpeg', ffmpegArgs);
            let stderr = '';

            ffmpeg.stderr.on('data', (data) => {
                stderr += data.toString();
            });

            ffmpeg.on('close', async (code) => {
                if (code !== 0) {
                    console.error('FFmpeg error:', stderr);
                    reject(new Error(FFmpeg exited with code ${code}));
                    return;
                }

                // Đọc tất cả frames đã trích xuất
                const files = await fs.readdir(outputDir);
                const frames = [];

                for (const file of files.sort()) {
                    if (file.endsWith('.jpg')) {
                        const framePath = path.join(outputDir, file);
                        const frameData = await fs.readFile(framePath);
                        frames.push({
                            filename: file,
                            timestamp: parseInt(file.match(/frame_(\d+)/)?.[1] || '0') * interval,
                            data: frameData.toString('base64'),
                            size: frameData.length
                        });
                    }
                }

                // Cleanup
                await fs.rm(outputDir, { recursive: true, force: true });

                resolve(frames);
            });

            ffmpeg.on('error', reject);
        });
    }

    // Phân tích video với Gemini 2.5 Flash qua HolySheep
    async analyzeVideoFrames(frames, fireContext) {
        // Chuẩn bị images cho Gemini
        const content = [
            { type: 'text', text: 分析以下视频帧,检测火情迹象:${fireContext} }
        ];

        // Thêm tối đa 10 frames (Giới hạn của Gemini)
        for (const frame of frames.slice(0, 10)) {
            content.push({
                type: 'image',
                source: {
                    type: 'base64',
                    media_type: 'image/jpeg',
                    data: frame.data
                }
            });
        }

        // Gọi Gemini qua HolySheep với model gemini-2.0-flash
        const response = await this.client.post('/chat/completions', {
            model: 'gemini-2.0-flash', // $2.50/MTok - Chi phí thấp nhất
            messages: [
                { role: 'user', content: content }
            ],
            temperature: 0.2,
            max_tokens: 2000
        });

        return {
            analysis: response.data.choices[0].message.content,
            framesAnalyzed: frames.length,
            model: 'gemini-2.0-flash',
            usage: response.data.usage
        };
    }

    // Phát hiện chuyển động và trích xuất frames quan trọng
    async extractKeyFramesIntelligent(rtspUrl, options = {}) {
        // Bước 1: Trích xuất frames với interval thưa
        const rawFrames = await this.extractFramesFromRTSP(rtspUrl, {
            maxFrames: 30,
            interval: 5 // Mỗi 5 giây
        });

        // Bước 2: Sử dụng AI để chọn frames quan trọng nhất
        const framesForAnalysis = await this.selectImportantFrames(rawFrames);

        // Bước 3: Phân tích với Gemini
        const analysis = await this.analyzeVideoFrames(framesForAnalysis, 
            '检测烟雾、火焰、温度异常');

        return {
            ...analysis,
            totalFramesExtracted: rawFrames.length,
            keyFramesSelected: framesForAnalysis.length,
            timestamp: new Date().toISOString()
        };
    }

    // Chọn frames quan trọng dựa trên kích thước file và metadata
    async selectImportantFrames(frames) {
        // Sắp xếp theo kích thước (frame lớn = có thể có nhiều chi tiết)
        const sorted = [...frames].sort((a, b) => b.size - a.size);
        
        // Lấy frames đầu, giữa, cuối để có cái nhìn tổng quan
        const selected = [];
        const step = Math.ceil(sorted.length / 5);
        
        for (let i = 0; i < sorted.length && selected.length < 5; i += step) {
            selected.push(sorted[i]);
        }

        return selected;
    }
}

module.exports = { VideoFrameExtractor };

Phần 4: GPT-5 火情研判 Engine

// gpt5_fire_analyzer.js
// GPT-5 火情研判模块 - Phân tích và đánh giá tình huống cháy

class FireAnalysisEngine {
    constructor(httpClient) {
        this.client = httpClient;
        
        // System prompt cho fire analysis agent
        this.systemPrompt = `Bạn là chuyên gia phân tích phòng cháy chữa cháy (PCCC) với 20 năm kinh nghiệm.
Nhiệm vụ của bạn là phân tích dữ liệu từ camera và cảm biến IoT để:
1. Xác định có cháy/nháy cháy/thỏa điều kiện cháy hay không
2. Đánh giá mức độ nguy hiểm (1-5 sao)
3. Dự đoán hướng và tốc độ lan cháy
4. Đề xuất phương án ứng cứu
5. Tính toán thời gian an toàn để sơ tán

Luôn trả lời bằng JSON format với cấu trúc sau:
{
    "fire_detected": boolean,
    "confidence": number (0-100),
    "danger_level": number (1-5),
    "fire_type": string,
    "spread_direction": string,
    "spread_speed": string,
    "evacuation_time_seconds": number,
    "recommendations": array,
    "severity": "LOW" | "MEDIUM" | "HIGH" | "CRITICAL"
}

Nếu không phát hiện cháy, vẫn phân tích các yếu tố cảnh báo sớm.`;
    }

    // Phân tích火情 với GPT-4.1 qua HolySheep
    async analyzeFireSituation(imageData, sensorData, historicalData = []) {
        const userPrompt = this.buildAnalysisPrompt(imageData, sensorData, historicalData);

        // Sử dụng GPT-4.1 cho phân tích火情 - $8/MTok
        const response = await this.client.post('/chat/completions', {
            model: 'gpt-4.1',
            messages: [
                { role: 'system', content: this.systemPrompt },
                { role: 'user', content: userPrompt }
            ],
            temperature: 0.1, // Low temperature cho kết quả nhất quán
            max_tokens: 2500,
            response_format: { type: 'json_object' }
        });

        const analysis = JSON.parse(response.data.choices[0].message.content);
        const usage = response.data.usage;

        // Tính toán chi phí
        const costEstimate = this.calculateCost(usage);

        return {
            ...analysis,
            model: 'gpt-4.1',
            usage: usage,
            costEstimate: costEstimate,
            timestamp: new Date().toISOString()
        };
    }

    // Phân tích火势预测 với Claude Sonnet 4.5
    async predictFireSpread(imageData, buildingLayout, windData) {
        const prompt = `Dựa trên hình ảnh hiện tại, layout tòa nhà và dữ liệu gió:
- Mô phỏng hướng lan cháy trong 5, 10, 30 phút tới
- Xác định các điểm nóng có thể bị ảnh hưởng
- Đề xuất vị trí thoát hiểm tối ưu
- Tính toán thời gian lan đến từng khu vực

Trả lời JSON format với cấu trúc:
{
    "predictions": [
        {
            "time_minutes": number,
            "affected_zones": array,
            "temperature_estimate": string,
            "recommended_actions": array
        }
    ],
    "safe_evacuation_routes": array,
    "risk_zones": array
}`;

        // Claude Sonnet 4.5 - $15/MTok cho dự đoán phức tạp
        const response = await this.client.post('/chat/completions', {
            model: 'claude-sonnet-4.5',
            messages: [
                { 
                    role: 'user', 
                    content: [
                        { type: 'text', text: prompt },
                        { type: 'image', source: { type: 'base64', media_type: 'image/jpeg', data: imageData } }
                    ]
                }
            ],
            temperature: 0.3,
            max_tokens: 3000,
            response_format: { type: 'json_object' }
        });

        return JSON.parse(response.data.choices[0].message.content);
    }

    // Tạo báo cáo tổng hợp với DeepSeek V3.2 (chi phí thấp nhất - $0.42/MTok)
    async generateSummaryReport(fullAnalysis, predictions, sensorLogs) {
        const summaryPrompt = `Tạo báo cáo tổng hợp ngắn gọn (dưới 500 từ) từ:
1. Kết quả phân tích火情: ${JSON.stringify(fullAnalysis)}
2. Dự đoán lan cháy: ${JSON.stringify(predictions)}
3. Log cảm biến: ${JSON.stringify(sensorLogs)}

Báo cáo cần có:
- Tóm tắt tình huống
- Mức độ nghiêm trọng hiện tại
- Hành động cần thiết ngay lập tức
- Các bước tiếp theo`;

        // DeepSeek V3.2 cho việc tạo báo cáo - tiết kiệm 95% chi phí
        const response = await this.client.post('/chat/completions', {
            model: 'deepseek-chat',
            messages: [
                { role: 'user', content: summaryPrompt }
            ],
            temperature: 0.2,
            max_tokens: 800
        });

        return {
            summary: response.data.choices[0].message.content,
            wordCount: response.data.choices[0].message.content.split(' ').length,
            costEstimate: this.calculateCost(response.data.usage, 'deepseek-chat'),
            model: 'deepseek-chat'
        };
    }

    // Xây dựng prompt phân tích
    buildAnalysisPrompt(imageData, sensorData, historicalData) {
        return `Phân tích tình huống cháy với dữ liệu sau:

CẢM BIẾN IoT:
- Nhiệt độ: ${sensorData.temperature || 'N/A'}°C (ngưỡng: >60°C báo động)
- Độ ẩm: ${sensorData.humidity || 'N/A'}%
- Khói: ${sensorData.smokeLevel || 'N/A'} ppm (ngưỡng: >50ppm báo động)
- CO2: ${sensorData.co2Level || 'N/A'} ppm (ngưỡng: >1000ppm nguy hiểm)
- Trạng thái sprinkler: ${sensorData.sprinklerActive ? 'HOẠT ĐỘNG' : 'TẮT'}

LỊCH SỬ (5 phút gần nhất):
${historicalData.map(h => - ${h.time}: T=${h.temperature}°C, Smoke=${h.smokeLevel}ppm).join('\n') || 'Không có dữ liệu lịch sử'}

HÌNH ẢNH CAMERA: [Base64 encoded JPEG]
${imageData.substring(0, 100)}...

YÊU CẦU: Phân tích và trả lời JSON.`;
    }

    // Tính chi phí ước tính
    calculateCost(usage, model = 'gpt-4.1') {
        const pricing = {
            'gpt-4.1': { input: 8, output: 8 }, // $8/MTok
            'claude-sonnet-4.5': { input: 15, output: 15 }, // $15/MTok
            'gemini-2.0-flash': { input: 2.50, output: 2.50 }, // $2.50/MTok
            'deepseek-chat': { input: 0.42, output: 0.42 } // $0.42/MTok - Rẻ nhất!
        };

        const p = pricing[model] || pricing['gpt-4.1'];
        const inputCost = (usage.prompt_tokens / 1000000) * p.input;
        const outputCost = (usage.completion_tokens / 1000000) * p.output;

        return {
            model: model,
            inputTokens: usage.prompt_tokens,
            outputTokens: usage.completion_tokens,
            inputCostUSD: inputCost.toFixed(6),
            outputCostUSD: outputCost.toFixed(6),
            totalCostUSD: (inputCost + outputCost).toFixed(6),
            totalCostVND: ((inputCost + outputCost) * 25000).toFixed(0) + ' VND'
        };
    }
}

module.exports = { FireAnalysisEngine };

Phần 5: Triển Khai Hoàn Chỉnh - Main Application

// main_fire_protection_system.js
// Hệ thống Phòng cháy chữa cháy Thông minh hoàn chỉnh

const { HolySheepFireAgent } = require('./holy_sheep_fire_agent.js');
const { RateLimiter } = require('./sla_rate_limiter.js');
const { AlertManager } = require('./alert_manager.js');

class FireProtectionSystem {
    constructor() {
        // Khởi tạo Holy