การ deploy AI API ใน production โดยไม่มีระบบ monitoring ที่ดี เปรียบเสมือนขับรถปิดไฟฉายตอนกลางคืน — คุณไม่รู้ว่า server กำลังร้อนเกินไปหรือ latency พุ่งสูงขึ้นจนผู้ใช้งานหงุดหงิด ในบทความนี้ผมจะสอนการตั้งค่า Prometheus monitoring สำหรับ AI API อย่างเป็นระบบ พร้อมดาชบอร์ด 4 metrics หลักที่ทุกทีมควรมี

📊 กรณีศึกษา: ทีมสตาร์ทอัพ AI ในกรุงเทพฯ

บริบทธุรกิจ

ทีมสตาร์ทอัพ AI แห่งหนึ่งในกรุงเทพฯ พัฒนาแชทบอทสำหรับธุรกิจอีคอมเมิร์ซ รับ traffic ประมาณ 50,000 requests ต่อวัน ระบบทำงานบน Kubernetes cluster ก่อนหน้านี้ใช้ OpenAI API โดยตรง

จุดเจ็บปวดของผู้ให้บริการเดิม

เหตุผลที่เลือก HolySheep

หลังจากทดสอบหลายราย ทีมตัดสินใจเลือก สมัครที่นี่ เนื่องจากปัจจัยหลัก:

ขั้นตอนการย้าย

1. การเปลี่ยน base_url

ทีมเริ่มจากการเปลี่ยน configuration เพียงจุดเดียว — base_url จาก OpenAI เป็น HolySheep:

# ก่อนหน้า (OpenAI)
OPENAI_API_BASE=https://api.openai.com/v1
OPENAI_API_KEY=sk-...

หลังย้าย (HolySheep)

HOLYSHEEP_API_BASE=https://api.holysheep.ai/v1 HOLYSHEEP_API_KEY=YOUR_HOLYSHEEP_API_KEY

2. การหมุนคีย์ (Key Rotation)

ทีมใช้ strategy หมุนคีย์เพื่อลดความเสี่ยง โดยเริ่มจาก 10% ของ traffic ก่อน:

# Kubernetes secret สำหรับ dual-key strategy
apiVersion: v1
kind: Secret
metadata:
  name: ai-api-keys
type: Opaque
stringData:
  HOLYSHEEP_KEY: "YOUR_HOLYSHEEP_API_KEY"
  OPENAI_KEY: "sk-legacy-key-for-fallback"
---

ConfigMap สำหรับ traffic split ratio

apiVersion: v1 kind: ConfigMap metadata: name: ai-api-config data: HOLYSHEEP_RATIO: "0.1" # เริ่มที่ 10% TARGET_RATIO: "1.0" # เป้าหมาย 100%

3. Canary Deploy

ทีมใช้ Argo Rollouts สำหรับ canary deployment เพื่อค่อยๆ เพิ่ม traffic ไปยัง HolySheep:

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: ai-api-service
spec:
  strategy:
    canary:
      steps:
      - setWeight: 10
      - pause: {duration: 10m}
      - setWeight: 30
      - pause: {duration: 30m}
      - setWeight: 60
      - pause: {duration: 1h}
      - setWeight: 100
      analysis:
        templates:
        - templateName: success-rate
        startingStep: 1
        args:
        - name: service-name
          value: ai-api-service

ตัวชี้วัด 30 วันหลังจากย้าย

Metric ก่อนย้าย หลังย้าย การปรับปรุง
Average Latency 420ms 180ms ↓ 57%
ค่าใช้จ่ายรายเดือน $4,200 $680 ↓ 84%
Success Rate 98.2% 99.8% ↑ 1.6%
P95 Latency 680ms 290ms ↓ 57%

🔧 การตั้งค่า Prometheus Metrics สำหรับ AI API

ต่อไปจะเป็นส่วน technical ที่จะสอนการตั้งค่า Prometheus monitoring อย่างเป็นระบบ โดยเราจะเน้น 4 metrics หลักที่เรียกว่า "Four Golden Signals"

4 Golden Signals สำหรับ AI API

  1. Latency — เวลาตอบสนองของ API
  2. Traffic — จำนวน requests ต่อวินาที
  3. Errors — อัตราความผิดพลาด
  4. Saturation — ความสามารถในการรองรับ workload

การสร้าง Prometheus Client Wrapper

import prometheus_client
from prometheus_client import Counter, Histogram, Gauge, Info
from functools import wraps
import time

class AIMetrics:
    """Prometheus metrics wrapper สำหรับ AI API"""
    
    def __init__(self, service_name: str = "ai-api"):
        self.service_name = service_name
        
        # 1. Latency Histogram (วินาที)
        self.request_latency = Histogram(
            'ai_request_latency_seconds',
            'AI API request latency in seconds',
            ['model', 'endpoint', 'status'],
            buckets=[0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0]
        )
        
        # 2. Traffic Counter
        self.request_total = Counter(
            'ai_request_total',
            'Total AI API requests',
            ['model', 'endpoint', 'status']
        )
        
        # 3. Error Counter
        self.error_total = Counter(
            'ai_error_total',
            'Total AI API errors',
            ['model', 'error_type', 'endpoint']
        )
        
        # 4. Saturation Gauge
        self.token_usage = Gauge(
            'ai_token_usage',
            'Current token usage',
            ['model', 'type']  # type: prompt/completion
        )
        
        # Token counter สำหรับ cost calculation
        self.tokens_total = Counter(
            'ai_tokens_total',
            'Total tokens used',
            ['model', 'type']
        )
        
        # Cost gauge
        self.cost_usd = Gauge(
            'ai_cost_usd',
            'Accumulated cost in USD',
            ['model']
        )
    
    def track_request(self, model: str, endpoint: str):
        """Decorator สำหรับ track request metrics"""
        def decorator(func):
            @wraps(func)
            async def wrapper(*args, **kwargs):
                start_time = time.perf_counter()
                status = 'success'
                error_type = None
                
                try:
                    result = await func(*args, **kwargs)
                    return result
                except Exception as e:
                    status = 'error'
                    error_type = type(e).__name__
                    self.error_total.labels(
                        model=model,
                        error_type=error_type,
                        endpoint=endpoint
                    ).inc()
                    raise
                finally:
                    latency = time.perf_counter() - start_time
                    self.request_latency.labels(
                        model=model,
                        endpoint=endpoint,
                        status=status
                    ).observe(latency)
                    self.request_total.labels(
                        model=model,
                        endpoint=endpoint,
                        status=status
                    ).inc()
            
            return wrapper
        return decorator

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

metrics = AIMetrics("holysheep-api") @metrics.track_request(model="gpt-4", endpoint="/chat/completions") async def call_holysheep(messages): """เรียก HolySheep API พร้อม track metrics""" async with aiohttp.ClientSession() as session: async with session.post( 'https://api.holysheep.ai/v1/chat/completions', headers={ 'Authorization': f'Bearer {os.environ.get("HOLYSHEEP_API_KEY")}', 'Content-Type': 'application/json' }, json={'model': 'gpt-4.1', 'messages': messages} ) as response: data = await response.json() # Track token usage prompt_tokens = data.get('usage', {}).get('prompt_tokens', 0) completion_tokens = data.get('usage', {}).get('completion_tokens', 0) metrics.tokens_total.labels(model='gpt-4.1', type='prompt').inc(prompt_tokens) metrics.tokens_total.labels(model='gpt-4.1', type='completion').inc(completion_tokens) # Track cost (GPT-4.1 = $8/MTok) cost = (prompt_tokens + completion_tokens) / 1_000_000 * 8 metrics.cost_usd.labels(model='gpt-4.1').set(cost) return data

📈 การตั้งค่า Prometheus Server และ Scraping

# prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

alerting:
  alertmanagers:
  - static_configs:
    - targets: []

rule_files:
  - "alert_rules.yml"

scrape_configs:
  # Scrape Prometheus itself
  - job_name: 'prometheus'
    static_configs:
    - targets: ['localhost:9090']

  # Scrape AI API service
  - job_name: 'ai-api'
    kubernetes_sd_configs:
    - role: pod
    relabel_configs:
    # กรองเฉพาะ pods ที่มี label ai-api
    - source_labels: [__meta_kubernetes_pod_label_app]
      regex: ai-api
      action: keep
    # ดึง port จาก container port
    - source_labels: [__meta_kubernetes_pod_container_port_number]
      regex: "9090"
      action: keep
    # แปลง port เป็น target
    - source_labels: [__meta_kubernetes_pod_ip]
      regex: "(.*)"
      replacement: "${1}:9090"
      target_label: __address__
    # เพิ่ม labels
    - source_labels: [__meta_kubernetes_namespace]
      target_label: namespace
    - source_labels: [__meta_kubernetes_pod_name]
      target_label: pod_name

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

1. ปัญหา: 429 Too Many Requests Error

สาเหตุ: เรียก API เร็วเกินไปหลังจากได้รับ rate limit error ทำให้ถูก ban ชั่วคราว

# ❌ วิธีที่ผิด - retry ทันที
async def call_api_broken():
    for i in range(10):
        response = await api_call()
        if response.status == 429:
            continue  # ทำให้รุนแรงขึ้น!

✅ วิธีที่ถูก - exponential backoff

async def call_api_fixed(max_retries: int = 5): async with aiohttp.ClientSession() as session: for attempt in