บทนำ: ทำไมต้อง Model Routing

ในฐานะวิศวกรที่ดูแลระบบ AI มาหลายปี ผมเจอปัญหาต้นทุนที่สูงเกินไปจากการใช้โมเดลขนาดใหญ่เกินความจำเป็นอยู่บ่อยครั้ง วันนี้ผมจะมาแชร์ประสบการณ์ตรงในการสร้างระบบ Model Routing ที่ช่วยประหยัดค่าใช้จ่ายได้ถึง 70% โดยไม่สูญเสียคุณภาพ

หลักการง่ายๆ คือ ไม่ใช้ F1 car ในการขับขี่ในเมือง บางงานเช่น การจำแนกประเภทข้อความ (Classification) ใช้ DeepSeek V3.2 ซึ่งมีราคา $0.42/MTok ก็เพียงพอแล้ว แต่งานวิเคราะห์เชิงลึกต้องใช้ Claude Sonnet 4.5 ($15/MTok) ถ้าใช้ GPT-4.1 ($8/MTok) ทำทุกงานโดยไม่มีการ routing ค่าใช้จ่ายจะบานปลายมาก

ผมใช้ HolySheep AI เป็นแพลตฟอร์มหลักเพราะรวมโมเดลหลากหลายไว้ที่เดียว ราคาประหยัดมาก อัตราแลกเปลี่ยน ¥1=$1 ทำให้ประหยัดได้ถึง 85%+ เมื่อเทียบกับผู้ให้บริการอื่น แถมมี latency เฉลี่ยต่ำกว่า 50ms และรองรับการจ่ายเงินผ่าน WeChat/Alipay สะดวกมาก

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

ระบบ Model Routing ที่ดีต้องมีองค์ประกอบหลัก 3 ส่วน:

การจำแนกประเภทงานและโมเดลที่เหมาะสม

จากการทดสอบใน production หลายเดือน ผมแบ่งงานออกเป็น 3 ระดับ:

โค้ด Production: Model Routing Engine

import json
import re
import time
from dataclasses import dataclass
from typing import Optional
from openai import OpenAI, RateLimitError, Timeout
import httpx

Configuration สำหรับ HolySheep AI

BASE_URL = "https://api.holysheep.ai/v1" API_KEY = "YOUR_HOLYSHEEP_API_KEY" @dataclass class ModelConfig: name: str max_tokens: int cost_per_mtok: float temperature: float = 0.7 complexity_threshold: float = 0.5

Routing Rules Configuration

MODEL_CONFIGS = { "simple": ModelConfig( name="deepseek-v3.2", max_tokens=2048, cost_per_mtok=0.42, temperature=0.3 ), "medium": ModelConfig( name="gemini-2.5-flash", max_tokens=4096, cost_per_mtok=2.50, temperature=0.7 ), "complex": ModelConfig( name="gpt-4.1", max_tokens=8192, cost_per_mtok=8.00, temperature=0.9 ) } class ComplexityAnalyzer: """วิเคราะห์ความซับซ้อนของ prompt เพื่อเลือกโมเดลที่เหมาะสม""" COMPLEXITY_KEYWORDS = { "high": [ "analyze", "evaluate", "compare", "synthesize", "reason", "design", "architect", "debug", "optimize", "explain why", "step by step", "think through", "comprehensive", "detailed" ], "medium": [ "summarize", "rewrite", "translate", "paraphrase", "expand", "elaborate", "convert", "transform", "reformat", "restructure" ] } COMPLEXITY_PATTERNS = { "high": [ r"(?i)why\s+(should|would|is|does)", r"(?i)analyze\s+(the\s+)?(pros?\s+and\s+cons?|benefits?|implications?)", r"(?i)step\s+by\s+step", r"(?i)think\s+through", r"(?i)considering\s+(multiple|various|different)", ], "medium": [ r"(?i)rewrite\s+(in|as)", r"(?i)translate\s+(to|into)", r"(?i)summarize\s+(the\s+)?(above|following|text)", r"(?i)convert\s+(this|the)\s+(into|to)", ] } def analyze(self, prompt: str) -> tuple[str, float]: prompt_lower = prompt.lower() # ตรวจสอบความยาว prompt (งานที่ยาวมักซับซ้อน) length_score = min(len(prompt) / 1000, 1.0) # ตรวจสอบ keyword patterns high_keyword_matches = sum( 1 for kw in self.COMPLEXITY_KEYWORDS["high"] if kw in prompt_lower ) medium_keyword_matches = sum( 1 for kw in self.COMPLEXITY_KEYWORDS["medium"] if kw in prompt_lower ) # ตรวจสอบ regex patterns high_pattern_matches = sum( 1 for pattern in self.COMPLEXITY_PATTERNS["high"] if re.search(pattern, prompt) ) # คำนวณ complexity score score = ( (high_keyword_matches * 0.2) + (medium_keyword_matches * 0.1) + (high_pattern_matches * 0.3) + (length_score * 0.2) ) # กำหนดระดับความซับซ้อน if score >= 0.5 or high_pattern_matches >= 2: return "complex", score elif score >= 0.25 or medium_keyword_matches >= 1: return "medium", score else: return "simple", score class ModelRouter: """Routing Engine หลัก""" def __init__(self, api_key: str): self.client = OpenAI( base_url=BASE_URL, api_key=api_key, timeout=60.0, max_retries=3 ) self.analyzer = ComplexityAnalyzer() self.request_count = {"simple": 0, "medium": 0, "complex": 0} self.total_cost = {"simple": 0.0, "medium": 0.0, "complex": 0.0} def estimate_cost(self, config: ModelConfig, input_tokens: int, output_tokens: int) -> float: total_tok = input_tokens + output_tokens return (total_tok / 1_000_000) * config.cost_per_mtok def route(self, prompt: str, system_prompt: str = None, force_model: str = None) -> dict: """ส่ง request ไปยังโมเดลที่เหมาะสม""" # บังคับใช้โมเดลที่กำหนด (ถ้ามี) if force_model and force_model in MODEL_CONFIGS: level = force_model config = MODEL_CONFIGS[force_model] else: # วิเคราะห์ความซับซ้อน level, complexity_score = self.analyzer.analyze(prompt) config = MODEL_CONFIGS[level] # สร้าง messages messages = [] if system_prompt: messages.append({"role": "system", "content": system_prompt}) messages.append({"role": "user", "content": prompt}) start_time = time.time() try: response = self.client.chat.completions.create( model=config.name, messages=messages, max_tokens=config.max_tokens, temperature=config.temperature ) latency = time.time() - start_time usage = response.usage # คำนวณค่าใช้จ่าย cost = self.estimate_cost( config, usage.prompt_tokens, usage.completion_tokens ) # อัพเดท stats self.request_count[level] += 1 self.total_cost[level] += cost return { "success": True, "level": level, "model": config.name, "content": response.choices[0].message.content, "latency_ms": round(latency * 1000, 2), "prompt_tokens": usage.prompt_tokens, "completion_tokens": usage.completion_tokens, "cost_usd": round(cost, 4) } except RateLimitError as e: return { "success": False, "error": "rate_limit", "message": str(e), "retry_after": e.response.headers.get("retry-after", 5) } except Timeout: return { "success": False, "error": "timeout", "message": "Request timed out after 60 seconds" } except Exception as e: return { "success": False, "error": "unknown", "message": str(e) } def get_stats(self) -> dict: total_requests = sum(self.request_count.values()) total_cost = sum(self.total_cost.values()) return { "requests_by_level": self.request_count, "cost_by_level": self.total_cost, "total_requests": total_requests, "total_cost_usd": round(total_cost, 4), "avg_cost_per_request": round(total_cost / total_requests, 4) if total_requests > 0 else 0 }

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

if __name__ == "__main__": router = ModelRouter(API_KEY) test_prompts = [ ("simple", "จำแนกประเภทข้อความนี้: 'ผลิตภัณฑ์นี้ดีมาก' — positive หรือ negative?"), ("medium", "สรุปข้อความต่อไปนี้ให้กระชับ:\nการเรียนรู้ของเครื่อง (Machine Learning) เป็นสาขาหนึ่งของปัญญาประดิษฐ์ที่มุ่งเน้นการพัฒนาอัลกอริทึมที่สามารถเรียนรู้จากข้อมูลและทำนายผลลัพธ์ได้อย่างแม่นยำ มีการใช้งานในหลากหลายอุตสาหกรรมตั้งแต่การแพทย์จนถึงการเงิน"), ("complex", "วิเคราะห์ข้อดีข้อเสียของการใช้ Microservices เทียบกับ Monolithic Architecture โดยพิจารณาจากความซับซ้อนในการพัฒนา ความสามารถในการ scale และค่าใช้จ่ายในการดูแลรักษา") ] for expected_level, prompt in test_prompts: print(f"\n{'='*60}") print(f"Prompt Level: {expected_level}") print(f"Prompt: {prompt[:80]}...") result = router.route(prompt) if result["success"]: print(f"✅ Routed to: {result['model']} ({result['level']})") print(f" Latency: {result['latency_ms']}ms") print(f" Tokens: {result['prompt_tokens']} in / {result['completion_tokens']} out") print(f" Cost: ${result['cost_usd']}") else: print(f"❌ Error: {result['error']} - {result['message']}") print(f"\n{'='*60}") print("📊 Statistics:") stats = router.get_stats() print(json.dumps(stats, indent=2))

การ Benchmark และวัดประสิทธิภาพ

จากการทดสอบใน production environment ผมวัดประสิทธิภาพของแต่ละโมเดลใน HolySheep AI ได้ผลดังนี้:

สมมติว่ามี workload 10,000 requests/วัน แบ่งเป็น 60% simple, 30% medium, 10% complex:

โค้ด Production: Smart Load Balancer

import asyncio
import logging
from collections import defaultdict
from dataclasses import dataclass, field
from datetime import datetime, timedelta
from typing import Dict, List, Optional
import httpx

Logging setup

logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @dataclass class ModelMetrics: total_requests: int = 0 total_errors: int = 0 total_latency: float = 0.0 total_cost: float = 0.0 last_used: datetime = field(default_factory=datetime.now) @property def avg_latency(self) -> float: if self.total_requests == 0: return float('inf') return self.total_latency / self.total_requests @property def error_rate(self) -> float: if self.total_requests == 0: return 0.0 return self.total_errors / self.total_requests @dataclass class LoadBalancerConfig: base_url: str api_key: str max_requests_per_minute: int = 60 timeout_seconds: int = 30 enable_fallback: bool = True class SmartLoadBalancer: """ Load Balancer อัจฉริยะที่กระจาย request ไปยังโมเดลต่างๆ ตามความพร้อมใช้งานและประสิทธิภาพ """ def __init__(self, config: LoadBalancerConfig): self.config = config self.client = httpx.Client( base_url=config.base_url, headers={ "Authorization": f"Bearer {config.api_key}", "Content-Type": "application/json" }, timeout=config.timeout_seconds ) # ติดตาม metrics ของแต่ละโมเดล self.model_metrics: Dict[str, ModelMetrics] = defaultdict(ModelMetrics) # Rate limiting self.request_timestamps: Dict[str, List[datetime]] = defaultdict(list) # Fallback chain self.fallback_models = { "gpt-4.1": ["gemini-2.5-flash", "deepseek-v3.2"], "gemini-2.5-flash": ["deepseek-v3.2"], "deepseek-v3.2": [] } def _check_rate_limit(self, model: str) -> bool: """ตรวจสอบ rate limit ของโมเดล""" now = datetime.now() cutoff = now - timedelta(minutes=1) # ลบ timestamps เก่ากว่า 1 นาที self.request_timestamps[model] = [ ts for ts in self.request_timestamps[model] if ts > cutoff ] return len(self.request_timestamps[model]) < self.config.max_requests_per_minute async def _make_request( self, model: str, messages: List[Dict], temperature: float = 0.7, max_tokens: int = 2048 ) -> dict: """ส่ง request ไปยังโมเดลที่กำหนด""" payload = { "model": model, "messages": messages, "temperature": temperature, "max_tokens": max_tokens } start_time = datetime.now() try: response = self.client.post("/chat/completions", json=payload) response.raise_for_status() latency = (datetime.now() - start_time).total_seconds() result = response.json() # อัพเดท metrics metrics = self.model_metrics[model] metrics.total_requests += 1 metrics.total_latency += latency metrics.last_used = datetime.now() # คำนวณค่าใช้จ่าย usage = result.get("usage", {}) cost = self._calculate_cost(model, usage) metrics.total_cost += cost return { "success": True, "model": model, "content": result["choices"][0]["message"]["content"], "latency_ms": round(latency * 1000, 2), "tokens": usage, "cost_usd": cost } except