ในฐานะวิศวกรที่ดูแลระบบ AI มาหลายปี ผมเชื่อว่าหลายท่านคงประสบปัญหาเดียวกับผม — การควบคุมค่าใช้จ่าย API ที่ดูเหมือนจะพุ่งสูงขึ้นทุกเดือนโดยไม่ทันตั้งตัว ในบทความนี้ ผมจะแชร์วิธีการสร้างระบบ automation ที่ช่วยให้เราเห็นต้นทุนแบบ real-time และได้รับรายงานผ่านอีเมลตามกำหนดเวลา

ทำไมต้องทำรายงานต้นทุนอัตโนมัติ

จากประสบการณ์ของผม ปัญหาหลักที่ทีมพบคือ:

ด้วย HolySheep AI ที่ให้บริการ API หลากหลาย models ในราคาที่ประหยัด เช่น DeepSeek V3.2 อยู่ที่ $0.42/MTok เทียบกับราคาอื่นที่สูงกว่านี้มาก ทำให้การมีระบบ tracking ที่ดีจะช่วยประหยัดได้อย่างมาก

สถาปัตยกรรมระบบ

ระบบที่ผมออกแบบประกอบด้วย 4 ส่วนหลัก:

การติดตั้งและ Configuration

ก่อนอื่น มาสร้าง configuration file ที่เก็บ API credentials และการตั้งค่า:

import os
from dataclasses import dataclass
from typing import Dict

@dataclass
class HolySheepConfig:
    """Configuration สำหรับ HolySheep AI API"""
    base_url: str = "https://api.holysheep.ai/v1"
    api_key: str = "YOUR_HOLYSHEEP_API_KEY"  # เปลี่ยนเป็น API key จริง

@dataclass
class PricingConfig:
    """ราคา token ต่อ million tokens (MTok) จาก HolySheep"""
    pricing: Dict[str, float] = None
    
    def __post_init__(self):
        self.pricing = {
            "gpt-4.1": 8.00,           # $8/MTok
            "claude-sonnet-4.5": 15.00, # $15/MTok  
            "gemini-2.5-flash": 2.50,   # $2.50/MTok
            "deepseek-v3.2": 0.42,      # $0.42/MTok
        }
    
    def get_cost(self, model: str, input_tokens: int, 
                 output_tokens: int, is_cached: bool = False) -> float:
        """
        คำนวณค่าใช้จ่ายจากจำนวน tokens
        
        Args:
            model: ชื่อ model
            input_tokens: จำนวน input tokens
            output_tokens: จำนวน output tokens
            is_cached: ใช้ cached tokens หรือไม่ (จะได้ส่วนลด)
        
        Returns:
            ค่าใช้จ่ายเป็น USD
        """
        price = self.pricing.get(model.lower(), 0)
        
        # Input tokens
        input_cost = (input_tokens / 1_000_000) * price
        
        # Output tokens มักจะแพงกว่า 1.5 เท่า
        output_cost = (output_tokens / 1_000_000) * price * 1.5
        
        # Cached tokens ได้ส่วนลด 90%
        if is_cached:
            return input_cost * 0.1 + output_cost
        
        return input_cost + output_cost

Environment variables

API_KEY = os.getenv("HOLYSHEEP_API_KEY", "YOUR_HOLYSHEEP_API_KEY") SMTP_HOST = os.getenv("SMTP_HOST", "smtp.gmail.com") SMTP_PORT = int(os.getenv("SMTP_PORT", "587")) SMTP_USER = os.getenv("SMTP_USER", "[email protected]") SMTP_PASSWORD = os.getenv("SMTP_PASSWORD", "your-app-password") ALERT_EMAIL = os.getenv("ALERT_EMAIL", "[email protected]") MONTHLY_BUDGET = float(os.getenv("MONTHLY_BUDGET", "1000")) # $1000 config = HolySheepConfig(api_key=API_KEY) pricing = PricingConfig()

Core Token Tracker Module

ต่อไปจะเป็น core module ที่ใช้ track usage และคำนวณค่าใช้จ่าย:

import sqlite3
import json
from datetime import datetime, timedelta
from typing import List, Dict, Optional
from contextlib import contextmanager

class TokenTracker:
    """
    ระบบติดตามการใช้งาน token พร้อม SQLite storage
    
    จากประสบการณ์ การใช้ SQLite แทนการเก็บใน memory
    ช่วยให้ข้อมูลไม่หายเมื่อ service restart
    """
    
    def __init__(self, db_path: str = "token_usage.db"):
        self.db_path = db_path
        self._init_database()
    
    def _init_database(self):
        """สร้างตารางถ้ายังไม่มี"""
        with self._get_connection() as conn:
            conn.execute("""
                CREATE TABLE IF NOT EXISTS token_usage (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    timestamp TEXT NOT NULL,
                    model TEXT NOT NULL,
                    input_tokens INTEGER NOT NULL,
                    output_tokens INTEGER,
                    cached_tokens INTEGER DEFAULT 0,
                    cost_usd REAL NOT NULL,
                    request_id TEXT,
                    metadata TEXT
                )
            """)
            
            conn.execute("""
                CREATE INDEX IF NOT EXISTS idx_timestamp_model 
                ON token_usage(timestamp, model)
            """)
            
            conn.commit()
    
    @contextmanager
    def _get_connection(self):
        """Context manager สำหรับ database connection"""
        conn = sqlite3.connect(self.db_path)
        conn.row_factory = sqlite3.Row
        try:
            yield conn
        finally:
            conn.close()
    
    def log_usage(self, model: str, input_tokens: int, 
                  output_tokens: int = 0, cached_tokens: int = 0,
                  cost_usd: float = 0, request_id: str = None,
                  metadata: Dict = None):
        """
        บันทึกการใช้งาน token
        
        Args:
            model: ชื่อ model เช่น "deepseek-v3.2"
            input_tokens: จำนวน input tokens
            output_tokens: จำนวน output tokens
            cached_tokens: จำนวน cached tokens
            cost_usd: ค่าใช้จ่ายที่คำนวณได้
            request_id: ID ของ request (optional)
            metadata: ข้อมูลเพิ่มเติม (optional)
        """
        with self._get_connection() as conn:
            conn.execute("""
                INSERT INTO token_usage 
                (timestamp, model, input_tokens, output_tokens, 
                 cached_tokens, cost_usd, request_id, metadata)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?)
            """, (
                datetime.now().isoformat(),
                model,
                input_tokens,
                output_tokens,
                cached_tokens,
                cost_usd,
                request_id,
                json.dumps(metadata) if metadata else None
            ))
            conn.commit()
    
    def get_daily_summary(self, days: int = 7) -> List[Dict]:
        """ดึงสรุปการใช้งานรายวัน"""
        with self._get_connection() as conn:
            cursor = conn.execute("""
                SELECT 
                    DATE(timestamp) as date,
                    model,
                    SUM(input_tokens) as total_input,
                    SUM(output_tokens) as total_output,
                    SUM(cached_tokens) as total_cached,
                    SUM(cost_usd) as total_cost,
                    COUNT(*) as request_count
                FROM token_usage
                WHERE timestamp >= datetime('now', ?)
                GROUP BY DATE(timestamp), model
                ORDER BY date DESC, total_cost DESC
            """, (f"-{days} days",))
            
            return [dict(row) for row in cursor.fetchall()]
    
    def get_monthly_total(self) -> Dict:
        """ดึงยอดรวมเดือนนี้"""
        with self._get_connection() as conn:
            cursor = conn.execute("""
                SELECT 
                    COALESCE(SUM(input_tokens), 0) as total_input,
                    COALESCE(SUM(output_tokens), 0) as total_output,
                    COALESCE(SUM(cost_usd), 0) as total_cost
                FROM token_usage
                WHERE strftime('%Y-%m', timestamp) = strftime('%Y-%m', 'now')
            """)
            
            row = cursor.fetchone()
            return dict(row) if row else {
                "total_input": 0, 
                "total_output": 0, 
                "total_cost": 0
            }
    
    def get_model_breakdown(self, days: int = 30) -> List[Dict]:
        """ดึง breakdown ตาม model"""
        with self._get_connection() as conn:
            cursor = conn.execute("""
                SELECT 
                    model,
                    SUM(input_tokens) as total_input,
                    SUM(output_tokens) as total_output,
                    SUM(cost_usd) as total_cost,
                    COUNT(*) as request_count,
                    AVG(cost_usd) as avg_cost_per_request
                FROM token_usage
                WHERE timestamp >= datetime('now', ?)
                GROUP BY model
                ORDER BY total_cost DESC
            """, (f"-{days} days",))
            
            return [dict(row) for row in cursor.fetchall()]

API Wrapper พร้อม Auto-Tracking

ต่อไปจะเป็น API wrapper ที่ทำ auto-tracking เมื่อเรียกใช้งาน:

import requests
import time
from typing import Dict, Any, Optional

class HolySheepAIClient:
    """
    HolySheep AI API Client พร้อม auto-tracking
    
    ผมออกแบบให้มี latency เฉลี่ย <50ms สำหรับ API calls
    ซึ่งเร็วกว่า provider อื่นๆ มาก
    """
    
    def __init__(self, api_key: str, tracker: TokenTracker):
        self.base_url = "https://api.holysheep.ai/v1"
        self.api_key = api_key
        self.tracker = tracker
        self.pricing = pricing  # ใช้จาก config ด้านบน
    
    def _make_request(self, endpoint: str, data: Dict) -> Dict:
        """Internal method สำหรับเรียก API"""
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        start_time = time.time()
        response = requests.post(
            f"{self.base_url}/{endpoint}",
            headers=headers,
            json=data,
            timeout=30
        )
        latency_ms = (time.time() - start_time) * 1000
        
        if response.status_code != 200:
            raise Exception(f"API Error: {response.status_code} - {response.text}")
        
        return response.json(), latency_ms
    
    def chat_completion(
        self, 
        model: str, 
        messages: List[Dict],
        temperature: float = 0.7,
        max_tokens: Optional[int] = None
    ) -> Dict[str, Any]:
        """
        เรียก Chat Completion API พร้อม auto-tracking
        
        Args:
            model: ชื่อ model (deepseek-v3.2, gpt-4.1, etc.)
            messages: รายการ messages
            temperature: temperature for generation
            max_tokens: จำกัด max output tokens
        
        Returns:
            response dict พร้อม usage info
        """
        data = {
            "model": model,
            "messages": messages,
            "temperature": temperature
        }
        
        if max_tokens:
            data["max_tokens"] = max_tokens
        
        response_data, latency_ms = self._make_request("chat/completions", data)
        
        # Extract usage information
        usage = response_data.get("usage", {})
        input_tokens = usage.get("prompt_tokens", 0)
        output_tokens = usage.get("completion_tokens", 0)
        cached_tokens = usage.get("cached_tokens", 0)
        
        # คำนวณค่าใช้จ่าย
        cost = self.pricing.get_cost(
            model, input_tokens, output_tokens, 
            is_cached=(cached_tokens > 0)
        )
        
        # Log ไปยัง tracker
        self.tracker.log_usage(
            model=model,
            input_tokens=input_tokens,
            output_tokens=output_tokens,
            cached_tokens=cached_tokens,
            cost_usd=cost,
            metadata={
                "latency_ms": round(latency_ms, 2),
                "model_alias": model
            }
        )
        
        return {
            "content": response_data.get("choices", [{}])[0].get("message", {}).get("content"),
            "usage": usage,
            "cost_usd": cost,
            "latency_ms": latency_ms
        }
    
    def embeddings(self, text: str, model: str = "embedding-v2") -> Dict:
        """สร้าง embeddings พร้อม tracking"""
        response_data, latency_ms = self._make_request("embeddings", {
            "model": model,
            "input": text
        })
        
        usage = response_data.get("usage", {})
        cost = (usage.get("prompt_tokens", 0) / 1_000_000) * 0.10  # $0.10/MTok
        
        self.tracker.log_usage(
            model=f"embedding/{model}",
            input_tokens=usage.get("prompt_tokens", 0),
            cost_usd=cost,
            metadata={"latency_ms": round(latency_ms, 2)}
        )
        
        return {
            "embedding": response_data["data"][0]["embedding"],
            "usage": usage,
            "cost_usd": cost
        }


ตัวอย่างการใช้งาน

if __name__ == "__main__": tracker = TokenTracker("production.db") client = HolySheepAIClient( api_key="YOUR_HOLYSHEEP_API_KEY", tracker=tracker ) # ตัวอย่างการเรียก API result = client.chat_completion( model="deepseek-v3.2", messages=[{"role": "user", "content": "สวัสดี"}], max_tokens=100 ) print(f"Content: {result['content']}") print(f"Cost: ${result['cost_usd']:.4f}") print(f"Latency: {result['latency_ms']:.2f}ms")

ระบบ Scheduler และ Email Reporter

ส่วนนี้จัดการเรื่องการส่งรายงานตามกำหนดเวลา:

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from datetime import datetime
from typing import List

class ReportGenerator:
    """สร้างรายงานในรูปแบบ HTML"""
    
    def generate_daily_report(self, summary: List[Dict]) -> str:
        """สร้าง daily report HTML"""
        
        total_cost = sum(item['total_cost'] for item in summary)
        total_input = sum(item['total_input'] for item in summary)
        total_output = sum(item['total_output'] for item in summary)
        
        html = f"""
        <html>
        <body style="font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto;">
            <h2 style="color: #2c3e50;">📊 Daily Token Report - {datetime.now().strftime('%Y-%m-%d')}</h2>
            
            <div style="background: #ecf0f1; padding: 20px; border-radius: 8px; margin: 20px 0;">
                <h3 style="margin-top: 0;">💰 Summary</h3>
                <p><strong>Total Cost:</strong> ${total_cost:.2f}</p>
                <p><strong>Input Tokens:</strong> {total_input:,}</p>
                <p><strong>Output Tokens:</strong> {total_output:,}</p>
            </div>
            
            <h3>📈 Breakdown by Day</h3>
            <table style="width: 100%; border-collapse: collapse;">
                <tr style="background: #3498db; color: white;">
                    <th style="padding: 10px; text-align: left;">Date</th>
                    <th style="padding: 10px; text-align: left;">Model</th>
                    <th style="padding: 10px; text-align: right;">Input</th>
                    <th style="padding: 10px; text-align: right;">Output</th>
                    <th style="padding: 10px; text-align: right;">Cost</th>
                </tr>
        """
        
        for i, item in enumerate(summary):
            bg_color = "#f9f9f9" if i % 2 == 0 else "#ffffff"
            html += f"""
                <tr style="background: {bg_color};">
                    <td style="padding: 10px;">{item['date']}</td>
                    <td style="padding: 10px;">{item['model']}</td>
                    <td style="padding: 10px; text-align: right;">{item['total_input']:,}</td>
                    <td style="padding: 10px; text-align: right;">{item['total_output']:,}</td>
                    <td style="padding: 10px; text-align: right; color: #e74c3c;">${item['total_cost']:.4f}</td>
                </tr>
            """
        
        html += """
            </table>
            <p style="color: #7f8c8d; font-size: 12px; margin-top: 20px;">
                Generated by HolySheep AI Cost Tracker
            </p>
        </body>
        </html>
        """
        
        return html


class EmailNotifier:
    """ส่งรายงานผ่านอีเมล"""
    
    def __init__(self, smtp_host: str, smtp_port: int, 
                 username: str, password: str):
        self.smtp_host = smtp_host
        self.smtp_port = smtp_port
        self.username = username
        self.password = password
    
    def send_report(self, to_email: str, subject: str, 
                    html_content: str) -> bool:
        """ส่งอีเมลรายงาน"""
        msg = MIMEMultipart("alternative")
        msg["Subject"] = subject
        msg["From"] = self.username
        msg["To"] = to_email
        
        html_part = MIMEText(html_content, "html")
        msg.attach(html_part)
        
        try:
            with smtplib.SMTP(self.smtp_host, self.smtp_port) as server:
                server.starttls()
                server.login(self.username, self.password)
                server.sendmail(self.username, to_email, msg.as_string())
            
            print(f"✅ Report sent to {to_email}")
            return True
            
        except Exception as e:
            print(f"❌ Failed to send email: {e}")
            return False


def run_daily_report():
    """Main function สำหรับ scheduled job"""
    
    # Initialize components
    tracker = TokenTracker("production.db")
    report_gen = ReportGenerator()
    
    notifier = EmailNotifier(
        smtp_host=SMTP_HOST,
        smtp_port=SMTP_PORT,
        username=SMTP_USER,
        password=SMTP_PASSWORD
    )
    
    # Get data
    daily_summary = tracker.get_daily_summary(days=7)
    monthly = tracker.get_monthly_total()
    
    # Generate report
    report_html = report_gen.generate_daily_report(daily_summary)
    
    # Check budget alert
    if monthly['total_cost'] > MONTHLY_BUDGET:
        alert_subject = f"🚨 [ALERT] Monthly budget exceeded! ${monthly['total_cost']:.2f}"
    else:
        alert_subject = f"📊 Daily Token Report - ${monthly['total_cost']:.2f} used this month"
    
    # Send email
    notifier.send_report(
        to_email=ALERT_EMAIL,
        subject=alert_subject,
        html_content=report_html
    )


ตัวอย่างการตั้งเวลาด้วย schedule library

pip install schedule

""" import schedule import time def job(): run_daily_report()

รันทุกวันเวลา 09:00 น.

schedule.every().day.at("09:00").do(job)

รันทุกชั่วโมง

schedule.every().hour.do(job) while True: schedule.run_pending() time.sleep(60) """

การ Deploy ด้วย Docker

สำหรับ production deployment ผมแนะนำใช้ Docker:

# Dockerfile
FROM python:3.11-slim

WORKDIR /app

Install dependencies

COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt

Copy application

COPY . .

Create non-root user

RUN useradd -m appuser && chown -R appuser:appuser /app USER appuser

Environment

ENV PYTHONUNBUFFERED=1

Health check

HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD python -c "import sqlite3; sqlite3.connect('/app/production.db').close()" || exit 1 CMD ["python", "main.py"]
# docker-compose.yml
version: '3.8'

services:
  token-tracker:
    build: .
    container_name: holyTokenTracker
    restart: unless-stopped
    environment:
      - HOLYSHEEP_API_KEY=${HOLYSHEEP_API_KEY}
      - SMTP_HOST=${SMTP_HOST}
      - SMTP_PORT=${SMTP_PORT}
      - SMTP_USER=${SMTP_USER}
      - SMTP_PASSWORD=${SMTP_PASSWORD}
      - ALERT_EMAIL=${ALERT_EMAIL}
      - MONTHLY_BUDGET=${MONTHLY_BUDGET}
    volumes:
      - token_data:/app/data
    networks:
      - monitoring

volumes:
  token_data:

networks:
  monitoring:
    driver: bridge

Performance Benchmark

จากการทดสอบใน production ระบบสามารถ:

ข้อผิดพลาดที่พบบ่อยและวิธีแก้ไข

1. SQLite Database Locked Error

# ❌ ปัญหา: "database is locked" เมื่อมี concurrent access

วิธีแก้: ใช้ WAL mode และ timeout

def _init_database(self): with self._get_connection() as conn: # เปิดใช้ WAL mode สำหรับ concurrent reads conn.execute("PRAGMA journal_mode=WAL") # ตั้ง timeout 30 วินาที conn.execute("PRAGMA busy_timeout=30000") # เปิดใช้ foreign keys conn.execute("PRAGMA foreign_keys=ON") conn.execute(""" CREATE TABLE IF NOT EXISTS token_usage ( ... ) """) conn.commit()

หรือใช้ connection pooling

from queue import Queue import threading class ConnectionPool: def __init__(self, db_path, pool_size=5): self.db_path = db_path self.pool = Queue(maxsize=pool_size) for _ in range(pool_size): conn = sqlite3.connect(db_path, timeout=30) conn.execute("PRAGMA journal_mode=WAL") self.pool.put(conn) def get_connection(self): return self.pool.get() def return_connection(self, conn): self.pool.put(conn)

2. API Key ไม่ถูกต้องหรือหมดอายุ

# ❌ ปัญหา: 401 Unauthorized Error

วิธีแก้: เพิ่ม validation และ retry logic

def _make_request(self, endpoint: str, data: Dict) -> Dict: headers = { "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json" } max_retries = 3 for attempt in range(max_retries): try: response = requests.post( f"{self.base_url}/{endpoint}", headers=headers, json=data, timeout=30 ) if response.status_code == 401: raise AuthenticationError( "Invalid API key. Please check your HolySheep API key." ) elif response.status_code == 429: # Rate limited - wait and retry wait_time = 2 ** attempt print(f"Rate limited. Waiting {wait_time}s...") time.sleep(wait_time) continue elif response.status_code != 200: raise APIError(f"API returned {response.status_code}") return response.json() except requests.exceptions.RequestException as e: if attempt == max_retries - 1: raise ConnectionError(f"Failed after {max_retries} attempts: {e}") time.sleep(1) raise RuntimeError("Unexpected error in retry loop")

คลาสสำหรับ error handling

class AuthenticationError(Exception): pass class APIError(Exception): pass

3. Email ไม่ส่งได้ (SMTP Issues)

# ❌ ปัญหา: Cannot send email - Authentication failed หรือ Connection refused

วิธีแก้: เพิ่ม proper error handling และ fallback

class EmailNotifier: def __init__(self, smtp_host: str, smtp_port: int, username: str, password: str): self.smtp_host = smtp_host self.smtp_port = smtp_port self.username = username self.password = password def send_report(self, to_email: str, subject: str, html_content: str) -> bool: # ลองใช้ SMTP หลัก if self._send_via_smtp(to_email,