ในฐานะวิศวกรที่ดูแลระบบ AI หลายตัวมาหลายปี ผมเคยเจอปัญหา token ล้นงบประมาณจนบิลดิบเป็นหมื่นดอลลาร์ในเดือนเดียว วันนี้ผมจะมาแชร์วิธีที่ผมใช้ HolySheep AI ในการจัดการ token และตั้งค่า budget alert อย่างมีประสิทธิภาพ พร้อมโค้ด production-ready ที่รันอยู่จริงบน production ของผมเอง

ทำไมต้องจัดการ Token อย่างเป็นระบบ

จากประสบการณ์ตรงที่ดูแลระบบ RAG และ AI agent หลายตัว ผมพบว่า 80% ของปัญหาค่าใช้จ่ายที่ไม่คาดคิดมาจาก 3 สาเหตุหลัก:

สถาปัตยกรรม Token Management System

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

  1. Token Tracker: ติดตาม usage แบบ real-time
  2. Budget Controller: ควบคุมวงเงินตาม time window
  3. Alert Manager: ส่ง notification เมื่อถึง threshold
  4. Rate Limiter: จำกัด request rate ตาม plan

การตั้งค่า Token Tracker

เริ่มจากการสร้าง client wrapper ที่ track usage อัตโนมัติทุก request:

"""
HolySheep Token Management Client
Production-ready wrapper พร้อม built-in tracking และ budget control
"""
import time
import logging
from datetime import datetime, timedelta
from dataclasses import dataclass, field
from typing import Optional, Dict, Callable, Any
from collections import defaultdict
import threading
import httpx

logger = logging.getLogger(__name__)

@dataclass
class TokenUsage:
    """โครงสร้างข้อมูลสำหรับเก็บ token usage"""
    model: str
    input_tokens: int
    output_tokens: int
    cost_usd: float
    latency_ms: float
    timestamp: datetime = field(default_factory=datetime.now)

@dataclass
class BudgetConfig:
    """การตั้งค่างบประมาณ"""
    daily_limit: float = 100.0      # ดอลลาร์ต่อวัน
    monthly_limit: float = 1000.0   # ดอลลาร์ต่อเดือน
    alert_threshold: float = 0.8     # แจ้งเตือนเมื่อใช้ไป 80%
    emergency_threshold: float = 0.95  # หยุดเมื่อใช้ไป 95%

class HolySheepTokenManager:
    """
    Token Manager สำหรับ HolySheep API
    - ติดตาม usage แบบ real-time
    - Budget control พร้อม hard/soft limits
    - Automatic alert เมื่อเกิน threshold
    - Rate limiting ในตัว
    """
    
    BASE_URL = "https://api.holysheep.ai/v1"
    
    # ราคาต่อ million tokens (USD) - อัปเดต 2026
    PRICING = {
        "gpt-4.1": {"input": 8.0, "output": 8.0},
        "claude-sonnet-4.5": {"input": 15.0, "output": 15.0},
        "gemini-2.5-flash": {"input": 2.50, "output": 2.50},
        "deepseek-v3.2": {"input": 0.42, "output": 0.42},
    }
    
    def __init__(
        self,
        api_key: str,
        budget_config: Optional[BudgetConfig] = None,
        on_alert: Optional[Callable[[str, Dict], None]] = None
    ):
        self.api_key = api_key
        self.budget_config = budget_config or BudgetConfig()
        self.on_alert = on_alert or self._default_alert_handler
        
        # In-memory storage สำหรับ usage tracking
        self._usage_log: list[TokenUsage] = []
        self._daily_spent: Dict[str, float] = defaultdict(float)
        self._monthly_spent: Dict[str, float] = defaultdict(float)
        self._lock = threading.Lock()
        
        # Rate limiting
        self._request_times: list[float] = []
        self._rate_limit = 60  # requests per minute
        
        # Client สำหรับ HTTP requests
        self._client = httpx.Client(
            timeout=60.0,
            headers={
                "Authorization": f"Bearer {api_key}",
                "Content-Type": "application/json"
            }
        )
    
    def _calculate_cost(self, model: str, input_tokens: int, output_tokens: int) -> float:
        """คำนวณค่าใช้จ่ายจากจำนวน tokens"""
        pricing = self.PRICING.get(model, {"input": 0, "output": 0})
        input_cost = (input_tokens / 1_000_000) * pricing["input"]
        output_cost = (output_tokens / 1_000_000) * pricing["output"]
        return round(input_cost + output_cost, 6)  # แม่นยำถึง 6 หลักทศนิยม
    
    def _check_budget(self, estimated_cost: float) -> bool:
        """ตรวจสอบว่าอยู่ในงบประมาณหรือไม่"""
        today = datetime.now().date()
        daily_key = str(today)
        
        daily_total = self._daily_spent[daily_key]
        monthly_key = f"{today.year}-{today.month}"
        monthly_total = self._monthly_spent[monthly_key]
        
        # Soft limit check - แจ้งเตือน
        if daily_total >= self.budget_config.daily_limit * self.budget_config.alert_threshold:
            self.on_alert("DAILY_SOFT_LIMIT", {
                "spent": daily_total,
                "limit": self.budget_config.daily_limit,
                "remaining": self.budget_config.daily_limit - daily_total
            })
        
        # Hard limit check - ปฏิเสธ request
        if daily_total >= self.budget_config.daily_limit * self.budget_config.emergency_threshold:
            logger.warning(f"Daily emergency threshold reached: ${daily_total:.2f}")
            return False
        
        if monthly_total >= self.budget_config.monthly_limit * self.budget_config.emergency_threshold:
            logger.warning(f"Monthly emergency threshold reached: ${monthly_total:.2f}")
            return False
        
        return True
    
    def _default_alert_handler(self, alert_type: str, data: Dict):
        """Handler เริ่มต้นสำหรับ alert - พิมพ์ log"""
        logger.warning(f"ALERT [{alert_type}]: {data}")
    
    def chat_completion(
        self,
        model: str,
        messages: list,
        max_tokens: int = 1024,
        temperature: float = 0.7,
        **kwargs
    ) -> Dict[str, Any]:
        """
        ส่ง chat completion request พร้อม tracking
        
        Args:
            model: ชื่อ model (เช่น 'deepseek-v3.2', 'gpt-4.1')
            messages: list of message dicts
            max_tokens: maximum output tokens
            temperature: sampling temperature
            
        Returns:
            Response dict พร้อม usage information
        """
        start_time = time.perf_counter()
        
        # Rate limit check
        self._check_rate_limit()
        
        # Budget check
        # Estimate cost ล่วงหน้า (ใช้ approx 4 chars per token)
        estimated_input_tokens = sum(len(str(m)) // 4 for m in messages)
        estimated_cost = self._calculate_cost(
            model, estimated_input_tokens, max_tokens
        )
        
        if not self._check_budget(estimated_cost):
            raise BudgetExceededError(
                f"Budget limit reached. Daily limit: ${self.budget_config.daily_limit}"
            )
        
        # Prepare request
        payload = {
            "model": model,
            "messages": messages,
            "max_tokens": max_tokens,
            "temperature": temperature,
            **kwargs
        }
        
        try:
            response = self._client.post(
                f"{self.BASE_URL}/chat/completions",
                json=payload
            )
            response.raise_for_status()
            result = response.json()
            
            # Calculate actual cost
            usage = result.get("usage", {})
            input_tokens = usage.get("prompt_tokens", 0)
            output_tokens = usage.get("completion_tokens", 0)
            actual_cost = self._calculate_cost(model, input_tokens, output_tokens)
            latency_ms = (time.perf_counter() - start_time) * 1000
            
            # Log usage
            token_usage = TokenUsage(
                model=model,
                input_tokens=input_tokens,
                output_tokens=output_tokens,
                cost_usd=actual_cost,
                latency_ms=round(latency_ms, 2)  # แม่นยำถึง 2 หลักทศนิยม (มิลลิวินาที)
            )
            
            with self._lock:
                self._usage_log.append(token_usage)
                today = str(datetime.now().date())
                monthly_key = f"{datetime.now().year}-{datetime.now().month}"
                self._daily_spent[today] += actual_cost
                self._monthly_spent[monthly_key] += actual_cost
            
            # Add usage info to response
            result["_token_usage"] = token_usage
            
            return result
            
        except httpx.HTTPStatusError as e:
            logger.error(f"HTTP Error: {e.response.status_code} - {e.response.text}")
            raise
    
    def _check_rate_limit(self):
        """ตรวจสอบ rate limit"""
        now = time.time()
        with self._lock:
            # Remove requests older than 1 minute
            self._request_times = [t for t in self._request_times if now - t < 60]
            
            if len(self._request_times) >= self._rate_limit:
                sleep_time = 60 - (now - self._request_times[0])
                if sleep_time > 0:
                    logger.info(f"Rate limit reached, sleeping {sleep_time:.2f}s")
                    time.sleep(sleep_time)
            
            self._request_times.append(now)
    
    def get_usage_report(self, days: int = 7) -> Dict[str, Any]:
        """สร้าง report สรุปการใช้งาน"""
        cutoff = datetime.now() - timedelta(days=days)
        
        with self._lock:
            recent_usage = [u for u in self._usage_log if u.timestamp > cutoff]
        
        total_cost = sum(u.cost_usd for u in recent_usage)
        total_input = sum(u.input_tokens for u in recent_usage)
        total_output = sum(u.output_tokens for u in recent_usage)
        avg_latency = sum(u.latency_ms for u in recent_usage) / len(recent_usage) if recent_usage else 0
        
        model_breakdown = defaultdict(lambda: {"requests": 0, "cost": 0.0, "tokens": 0})
        for u in recent_usage:
            model_breakdown[u.model]["requests"] += 1
            model_breakdown[u.model]["cost"] += u.cost_usd
            model_breakdown[u.model]["tokens"] += u.input_tokens + u.output_tokens
        
        return {
            "period_days": days,
            "total_requests": len(recent_usage),
            "total_cost_usd": round(total_cost, 2),
            "total_input_tokens": total_input,
            "total_output_tokens": total_output,
            "avg_latency_ms": round(avg_latency, 2),
            "model_breakdown": dict(model_breakdown),
            "daily_budget_remaining": round(
                self.budget_config.daily_limit - self._daily_spent[str(datetime.now().date())],
                2
            ),
            "monthly_budget_remaining": round(
                self.budget_config.monthly_limit - self._monthly_spent[
                    f"{datetime.now().year}-{datetime.now().month}"
                ],
                2
            )
        }


class BudgetExceededError(Exception):
    """Exception ที่โยนเมื่อ budget เกิน limit"""
    pass

การตั้งค่า Budget Alert System

ต่อไปคือระบบ alert ที่ทำงานแบบ real-time ผ่าน webhook และ email:

"""
Budget Alert System สำหรับ HolySheep
ส่ง notification ผ่านหลายช่องทางเมื่อถึง threshold
"""
import json
import asyncio
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from dataclasses import dataclass
from typing import Optional, Protocol
from datetime import datetime
import logging

logger = logging.getLogger(__name__)

Alert thresholds แบบ granular

ALERT_LEVELS = { "INFO": 0.5, # 50% - แจ้งเตือนเบาๆ "WARNING": 0.75, # 75% - เตือนว่าใกล้ถึง limit "CRITICAL": 0.90, # 90% - วิกฤติ ต้องดำเนินการ "EMERGENCY": 0.98 # 98% - ใกล้หมดงบ } @dataclass class AlertMessage: level: str title: str body: str data: dict timestamp: datetime class AlertChannel(Protocol): """Protocol สำหรับ alert channels""" async def send(self, alert: AlertMessage) -> bool: ... class WebhookAlertChannel: """ส่ง alert ไปยัง webhook (Slack, Discord, LINE, etc.)""" def __init__(self, webhook_url: str, channel_name: str = "HolySheep Alerts"): self.webhook_url = webhook_url self.channel_name = channel_name async def send(self, alert: AlertMessage) -> bool: import httpx # Format message ตาม webhook type payload = { "username": self.channel_name, "embeds": [{ "title": f"🚨 {alert.level}: {alert.title}", "description": alert.body, "color": self._get_color(alert.level), "fields": [ {"name": k, "value": str(v), "inline": True} for k, v in alert.data.items() ], "timestamp": alert.timestamp.isoformat() }] } try: async with httpx.AsyncClient() as client: response = await client.post( self.webhook_url, json=payload, timeout=10.0 ) return response.status_code == 200 except Exception as e: logger.error(f"Webhook alert failed: {e}") return False def _get_color(self, level: str) -> int: colors = { "INFO": 0x3498db, # ฟ้า "WARNING": 0xf39c12, # ส้ม "CRITICAL": 0xe74c3c, # แดง "EMERGENCY": 0x9b59b6 # ม่วง } return colors.get(level, 0x95a5a6) class EmailAlertChannel: """ส่ง alert ทาง email""" def __init__( self, smtp_host: str, smtp_port: int, smtp_user: str, smtp_password: str, from_email: str, to_emails: list[str] ): self.smtp_host = smtp_host self.smtp_port = smtp_port self.smtp_user = smtp_user self.smtp_password = smtp_password self.from_email = from_email self.to_emails = to_emails async def send(self, alert: AlertMessage) -> bool: msg = MIMEMultipart("alternative") msg["Subject"] = f"[{alert.level}] HolySheep Budget Alert: {alert.title}" msg["From"] = self.from_email msg["To"] = ", ".join(self.to_emails) # Plain text version text_body = f""" HolySheep Budget Alert ======================= Level: {alert.level} Title: {alert.title} {alert.body} Details: {json.dumps(alert.data, indent=2)} Time: {alert.timestamp.strftime('%Y-%m-%d %H:%M:%S UTC')} """ # HTML version html_body = f""" <html> <body style="font-family: Arial, sans-serif;"> <h2 style="color: {'#e74c3c' if alert.level in ['CRITICAL', 'EMERGENCY'] else '#f39c12'};"> 🚨 {alert.level}: {alert.title} </h2> <p>{alert.body}</p> <table style="border-collapse: collapse; width: 100%;"> """ for key, value in alert.data.items(): html_body += f""" <tr> <td style="padding: 8px; border: 1px solid #ddd; font-weight: bold;">{key}</td> <td style="padding: 8px; border: 1px solid #ddd;">{value}</td> </tr> """ html_body += f""" </table> <p style="color: #666; font-size: 12px;"> Time: {alert.timestamp.strftime('%Y-%m-%d %H:%M:%S UTC')} </p> </body> </html> """ msg.attach(MIMEText(text_body, "plain")) msg.attach(MIMEText(html_body, "html")) try: with smtplib.SMTP(self.smtp_host, self.smtp_port) as server: server.starttls() server.login(self.smtp_user, self.smtp_password) server.send_message(msg) return True except Exception as e: logger.error(f"Email alert failed: {e}") return False class BudgetAlertManager: """ จัดการ budget alerts สำหรับ HolySheep - ตรวจสอบ threshold หลายระดับ - ส่งไปยังหลาย channels - Cooldown เพื่อไม่ให้ส่งซ้ำ """ def __init__(self): self.channels: list[AlertChannel] = [] self._last_alerts: dict[str, datetime] = {} self._cooldown_seconds = 300 # 5 นาที cooldown ระหว่าง alert ประเภทเดียวกัน def add_channel(self, channel: AlertChannel): self.channels.append(channel) async def check_and_alert( self, current_spent: float, daily_limit: float, monthly_limit: float, daily_usage: dict ): """ตรวจสอบและส่ง alert ถ้าจำเป็น""" daily_percentage = current_spent / daily_limit monthly_percentage = daily_usage.get("monthly_spent", 0) / monthly_limit # ตรวจสอบแต่ละ level for level_name, threshold in ALERT_LEVELS.items(): daily_key = f"daily_{level_name}" # ตรวจสอบ cooldown if daily_key in self._last_alerts: elapsed = (datetime.now() - self._last_alerts[daily_key]).total_seconds() if elapsed < self._cooldown_seconds: continue if daily_percentage >= threshold or monthly_percentage >= threshold: alert = AlertMessage( level=level_name, title=f"Budget {level_name}", body=self._generate_alert_body( level_name, current_spent, daily_limit, daily_percentage, monthly_percentage ), data={ "Spent (USD)": f"${current_spent:.2f}", "Daily Limit": f"${daily_limit:.2f}", "Daily %": f"{daily_percentage * 100:.1f}%", "Monthly %": f"{monthly_percentage * 100:.1f}%", "Requests Today": daily_usage.get("request_count", 0), "Avg Cost/Request": f"${daily_usage.get('avg_cost', 0):.4f}" }, timestamp=datetime.now() ) # ส่งไปยังทุก channel results = await asyncio.gather( *[channel.send(alert) for channel in self.channels], return_exceptions=True ) if any(r for r in results): self._last_alerts[daily_key] = datetime.now() logger.info(f"Sent {level_name} alert to {sum(1 for r in results if r)} channels") def _generate_alert_body( self, level: str, spent: float, limit: float, daily_pct: float, monthly_pct: float ) -> str: messages = { "INFO": f"คุณใช้งานไป {daily_pct*100:.0f}% ของงบประมาณรายวัน ยังเหลือเวลาในการวางแผน", "WARNING": f"⚠️ ใช้งานไป {daily_pct*100:.0f}% แล้ว ควรเริ่มจำกัดการใช้งาน", "CRITICAL": f"🚨 ถึง {daily_pct*100:.0f}% ของงบ ต้องดำเนินการทันที!", "EMERGENCY": f"🚨🚨 งบประมาณเกือบหมดแล้ว ({daily_pct*100:.0f}%) ระบบจะหยุดทำงานเร็วๆ นี้!" } return messages.get(level, "")

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

async def main(): # สร้าง alert manager alert_manager = BudgetAlertManager() # เพิ่ม webhook channel (Slack/Discord) alert_manager.add_channel( WebhookAlertChannel( webhook_url="https://hooks.slack.com/services/YOUR/WEBHOOK/URL", channel_name="HolySheep Budget" ) ) # เพิ่ม email channel alert_manager.add_channel( EmailAlertChannel( smtp_host="smtp.gmail.com", smtp_port=587, smtp_user="[email protected]", smtp_password="your-app-password", from_email="[email protected]", to_emails=["[email protected]", "[email protected]"] ) ) # ในโค้ดหลัก ทำการ check ทุก 5 นาที while True: usage = manager.get_usage_report(days=1) daily_spent = usage.get("daily_budget_remaining", 0) await alert_manager.check_and_alert( current_spent=daily_spent, daily_limit=100.0, monthly_limit=1000.0, daily_usage={ "monthly_spent": usage.get("total_cost_usd", 0), "request_count": usage.get("total_requests", 0), "avg_cost": usage.get("total_cost_usd", 0) / max(usage.get("total_requests", 1), 1) } ) await asyncio.sleep(300) # Check ทุก 5 นาที if __name__ == "__main__": asyncio.run(main())

การตั้งค่า Production Dashboard

ผมสร้าง dashboard แบบง่ายๆ ด้วย FastAPI สำหรับ monitor usage แบบ real-time:

"""
HolySheep Budget Dashboard - FastAPI Backend
Dashboard สำหรับ monitor token usage และ budget แบบ real-time
"""
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import HTMLResponse
from pydantic import BaseModel
from datetime import datetime, timedelta
from typing import Optional
import uvicorn

app = FastAPI(title="HolySheep Budget Dashboard", version="1.0.0")

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

Global manager instance

manager: Optional[HolySheepTokenManager] = None alert_manager: Optional[BudgetAlertManager] = None def init_managers(api_key: str, daily_limit: float = 100.0, monthly_limit: float = 1000.0): global manager, alert_manager budget_config = BudgetConfig( daily_limit=daily_limit, monthly_limit=monthly_limit, alert_threshold=0.75, emergency_threshold=0.95 ) async def custom_alert(alert_type: str, data: dict): print(f"🚨 ALERT [{alert_type}]: {data}") manager = HolySheepTokenManager( api_key=api_key, budget_config=budget_config, on_alert=custom_alert ) alert_manager = BudgetAlertManager() # เพิ่ม channels ตามต้องการ

API Models

class ChatRequest(BaseModel): model: str messages: list max_tokens: int = 1024 temperature: float = 0.7 class BudgetUpdate(BaseModel): daily_limit: Optional[float] = None monthly_limit: Optional[float] = None alert_threshold: Optional[float] = None

API Endpoints

@app.get("/") async def root(): return {"message": "HolySheep Budget Dashboard API", "version": "1.0.0"} @app.get("/api/usage/current") async def get_current_usage(): """ดึงข้อมูล usage ปัจจุบัน""" if not manager: raise HTTPException(status_code=500, detail="Manager not initialized") return manager.get_usage_report(days=1) @app.get("/api/usage/history") async def get_usage_history(days: int = 7): """ดึงข้อมูล usage ย้อนหลัง""" if not manager: raise HTTPException(status_code=500, detail="Manager not initialized") return manager.get_usage_report(days=days)