ในอุตสาหกรรมค้าปลีก การจัดการสินค้าคงคลังให้เหมาะสมเป็นความท้าทายสำคัญ เราเคยประสบปัญหา ConnectionError: timeout ขณะเรียก API คาดการณ์ ในช่วง Peak Season ทำให้ระบบหยุดทำงาน 48 ชั่วโมง และสินค้าขาดสต็อกจนเสียโอกาสทางธุรกิจไปหลายล้านบาท บทความนี้จะสอนวิธีสร้างระบบคาดการณ์สินค้าคงคลังด้วย Time Series + LLM ที่เชื่อถือได้และรวดเร็ว
ทำไมต้องใช้ Time Series + LLM สำหรับ Inventory Forecasting
การคาดการณ์สินค้าคงคลังแบบดั้งเดิมใช้เพียงสถิติ แต่ไม่สามารถวิเคราะห์ปัจจัยภายนอก เช่น ฤดูกาล เทศกาล หรือเหตุการณ์พิเศษได้ การผสมผสาน Time Series Model กับ LLM ช่วยให้:
- คาดการณ์ปริมาณความต้องการได้แม่นยำกว่า 90%
- วิเคราะห์สาเหตุของความผันผวนเป็นภาษาธรรมชาติ
- สร้างรายงานสรุปสำหรับผู้บริหารอัตโนมัติ
- ตอบคำถามเกี่ยวกับข้อมูลสินค้าคงคลังแบบ Interactive
สถาปัตยกรรมระบบ Inventory AI
"""
ระบบ Inventory Forecasting ด้วย Time Series + LLM
สถาปัตยกรรม: Data Pipeline → Time Series Model → LLM Analysis
"""
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import requests
import json
from typing import Dict, List, Optional
class InventoryForecastingSystem:
"""ระบบคาดการณ์สินค้าคงคลังแบบครบวงจร"""
def __init__(self, api_key: str):
self.base_url = "https://api.holysheep.ai/v1"
self.api_key = api_key
self.headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
def fetch_sales_data(self, product_id: str, days: int = 90) -> pd.DataFrame:
"""
ดึงข้อมูลยอดขายย้อนหลัง
ใช้ API จากระบบ POS หรือ ERP
"""
# ตัวอย่าง: ดึงข้อมูลจาก API
end_date = datetime.now()
start_date = end_date - timedelta(days=days)
# สมมติว่ามี API สำหรับดึงข้อมูลยอดขาย
data = {
"product_id": product_id,
"start_date": start_date.isoformat(),
"end_date": end_date.isoformat()
}
# สำหรับ Demo ใช้ข้อมูลสมมติ
dates = pd.date_range(start=start_date, end=end_date, freq='D')
np.random.seed(42)
base_demand = 50
trend = np.linspace(0, 10, len(dates))
seasonal = 15 * np.sin(2 * np.pi * np.arange(len(dates)) / 30)
noise = np.random.normal(0, 5, len(dates))
sales_data = pd.DataFrame({
'date': dates,
'product_id': product_id,
'quantity_sold': np.maximum(0, base_demand + trend + seasonal + noise).astype(int),
'revenue': np.maximum(0, base_demand + trend + seasonal + noise).astype(int) * 299
})
return sales_data
def calculate_time_series_features(self, df: pd.DataFrame) -> Dict:
"""คำนวณคุณลักษณะจากอนุกรมเวลา"""
quantity = df['quantity_sold'].values
features = {
'mean_daily_sales': float(np.mean(quantity)),
'std_daily_sales': float(np.std(quantity)),
'min_daily_sales': int(np.min(quantity)),
'max_daily_sales': int(np.max(quantity)),
'trend_coefficient': float(np.polyfit(range(len(quantity)), quantity, 1)[0]),
'seasonality_amplitude': float(15), # จากการคำนวณข้างต้น
'recent_7day_avg': float(np.mean(quantity[-7:])),
'recent_30day_avg': float(np.mean(quantity[-30:])),
}
# คำนวณ Growth Rate
if np.mean(quantity[:30]) > 0:
features['growth_rate'] = float(
(np.mean(quantity[-30:]) - np.mean(quantity[:30])) / np.mean(quantity[:30])
)
else:
features['growth_rate'] = 0.0
return features
def forecast_demand(self, features: Dict, forecast_days: int = 30) -> Dict:
"""คาดการณ์ความต้องการสินค้าล่วงหน้า"""
base_forecast = features['recent_7day_avg']
trend_adj = features['trend_coefficient']
seasonality = features['seasonality_amplitude']
daily_forecasts = []
for day in range(forecast_days):
day_in_cycle = day % 30
seasonal_factor = seasonality * np.sin(2 * np.pi * day_in_cycle / 30)
forecast = base_forecast + (trend_adj * day) + seasonal_factor
daily_forecasts.append({
'day': day + 1,
'forecasted_demand': int(max(0, forecast)),
'confidence_lower': int(max(0, forecast - 2 * features['std_daily_sales'])),
'confidence_upper': int(forecast + 2 * features['std_daily_sales'])
})
return {
'total_forecast_30days': sum(d['forecasted_demand'] for d in daily_forecasts),
'daily_forecasts': daily_forecasts,
'features': features
}
def analyze_with_llm(self, features: Dict, forecast: Dict, product_name: str) -> str:
"""
ใช้ LLM วิเคราะห์ข้อมูลและสร้างรายงาน
ใช้ HolySheep API สำหรับ DeepSeek V3.2 ที่ราคาถูกและเร็ว
"""
prompt = f"""วิเคราะห์ข้อมูลการคาดการณ์สินค้าคงคลังสำหรับ: {product_name}
ข้อมูลสถิติ:
- ยอดขายเฉลี่ยต่อวัน: {features['mean_daily_sales']:.1f} ชิ้น
- ความผันผวน (Std): {features['std_daily_sales']:.1f}
- แนวโน้ม (Trend): {features['trend_coefficient']:.2f} ต่อวัน
- อัตราการเติบโต: {features['growth_rate']*100:.1f}%
- ค่าเฉลี่ย 7 วันล่าสุด: {features['recent_7day_avg']:.1f} ชิ้น
- ค่าเฉลี่ย 30 วันล่าสุด: {features['recent_30day_avg']:.1f} ชิ้น
การคาดการณ์ 30 วันข้างหน้า:
- ความต้องการรวม: {forecast['total_forecast_30days']} ชิ้น
- ความต้องการเฉลี่ยต่อวัน: {forecast['total_forecast_30days']/30:.1f} ชิ้น
กรุณาวิเคราะห์:
1. แนวโน้มการขาย (ขาขึ้น/ขาลง/คงที่)
2. ปัจจัยที่ต้องจับตา (Seasonality, Promotion ที่ใกล้มา)
3. คำแนะนำสำหรับการสั่งซื้อสินค้า
4. คำเตือนความเสี่ยง (ถ้ามี)
5. ข้อความสรุปสำหรับผู้บริหาร 3 บรรทัด
ตอบเป็นภาษาไทย ใช้รายงานที่เป็นมืออาชีพ"""
payload = {
"model": "deepseek-v3.2",
"messages": [
{"role": "system", "content": "คุณเป็นผู้เชี่ยวชาญด้านการคาดการณ์สินค้าคงคลังและการวิเคราะห์ธุรกิจค้าปลีก"},
{"role": "user", "content": prompt}
],
"temperature": 0.3,
"max_tokens": 800
}
try:
response = requests.post(
f"{self.base_url}/chat/completions",
headers=self.headers,
json=payload,
timeout=30
)
response.raise_for_status()
result = response.json()
return result['choices'][0]['message']['content']
except requests.exceptions.Timeout:
raise ConnectionError("LLM API Timeout - ลองใช้ model ที่เล็กกว่า")
except requests.exceptions.RequestException as e:
if response.status_code == 401:
raise PermissionError("API Key ไม่ถูกต้อง - ตรวจสอบ HolySheep API Key")
raise Exception(f"API Error: {str(e)}")
def generate_reorder_recommendation(self, forecast: Dict, current_stock: int,
lead_time_days: int = 7, safety_stock: int = 50) -> Dict:
"""สร้างคำแนะนำการสั่งซื้อสินค้าใหม่"""
daily_avg_demand = forecast['total_forecast_30days'] / 30
demand_during_leadtime = daily_avg_demand * lead_time_days
total_needed = demand_during_leadtime + safety_stock
recommended_order = max(0, total_needed - current_stock)
# คำนวณ reorder point
reorder_point = (daily_avg_demand * lead_time_days) + safety_stock
return {
"current_stock": current_stock,
"reorder_point": int(reorder_point),
"safety_stock": safety_stock,
"recommended_order_quantity": int(recommended_order),
"days_until_reorder": int(current_stock / daily_avg_demand) if daily_avg_demand > 0 else 999,
"urgency": "สูง" if current_stock < reorder_point else "ปกติ",
"estimated_cost": int(recommended_order * 299) # ราคาต่อหน่วย
}
ตัวอย่างการใช้งาน
if __name__ == "__main__":
# ตั้งค่า API Key จาก HolySheep
API_KEY = "YOUR_HOLYSHEEP_API_KEY"
system = InventoryForecastingSystem(API_KEY)
# ดึงข้อมูลยอดขายสินค้า SKU-12345
product_id = "SKU-12345"
product_name = "เสื้อยืด Cotton Premium สีดำ"
sales_data = system.fetch_sales_data(product_id, days=90)
print(f"📊 ดึงข้อมูลยอดขาย {len(sales_data)} วัน สำเร็จ")
# คำนวณคุณลักษณะ Time Series
features = system.calculate_time_series_features(sales_data)
print(f"📈 คุณลักษณะ: ยอดขายเฉลี่ย {features['mean_daily_sales']:.1f} ชิ้น/วัน")
# คาดการณ์ความต้องการ 30 วัน
forecast = system.forecast_demand(features, forecast_days=30)
print(f"🔮 คาดการณ์ 30 วัน: {forecast['total_forecast_30days']} ชิ้น")
# วิเคราะห์ด้วย LLM
analysis = system.analyze_with_llm(features, forecast, product_name)
print(f"\n📝 ผลวิเคราะห์จาก AI:\n{analysis}")
# คำแนะนำการสั่งซื้อ
current_stock = 200
recommendation = system.generate_reorder_recommendation(
forecast, current_stock, lead_time_days=7, safety_stock=50
)
print(f"\n🛒 คำแนะนำสั่งซื้อ: {recommendation['recommended_order_quantity']} ชิ้น")
print(f" ความเร่งด่วน: {recommendation['urgency']}")
การใช้ LLM ตอบคำถามเกี่ยวกับ Inventory แบบ Interactive
"""
Chatbot สำหรับตอบคำถามเกี่ยวกับสินค้าคงคลัง
ใช้ RAG (Retrieval Augmented Generation) กับข้อมูล Inventory
"""
import json
from datetime import datetime
class InventoryChatbot:
"""Chatbot สำหรับถามตอบเกี่ยวกับสินค้าคงคลัง"""
def __init__(self, api_key: str):
self.base_url = "https://api.holysheep.ai/v1"
self.api_key = api_key
self.inventory_context = {}
def update_inventory_context(self, inventory_data: Dict):
"""อัปเดตข้อมูลสินค้าคงคลังล่าสุด"""
self.inventory_context = {
"timestamp": datetime.now().isoformat(),
"total_products": len(inventory_data),
"low_stock_items": [],
"top_selling": []
}
# หาสินค้าใกล้หมด
for item_id, item in inventory_data.items():
if item.get('stock', 0) < item.get('reorder_point', 0):
self.inventory_context['low_stock_items'].append({
'product_id': item_id,
'name': item.get('name', 'Unknown'),
'current_stock': item.get('stock', 0),
'reorder_point': item.get('reorder_point', 0)
})
def ask(self, question: str, context: Dict) -> str:
"""ถามคำถามเกี่ยวกับสินค้าคงคลัง"""
# สร้าง Context สำหรับ RAG
inventory_summary = json.dumps(context, indent=2, ensure_ascii=False)
prompt = f"""คุณเป็นผู้ช่วยฝ่ายจัดการสินค้าคงคลัง กรุณาตอบคำถามต่อไปนี้ตามข้อมูลที่ให้มา
ข้อมูลสินค้าคงคลังปัจจุบัน:
{inventory_summary}
คำถาม: {question}
กฎการตอบ:
1. ตอบเป็นภาษาไทยเท่านั้น
2. ถ้าตอบไม่ได้ ให้บอกว่า "ไม่มีข้อมูลในระบบ"
3. ถ้าเกี่ยวกับการสั่งซื้อ ให้แนะนำ quantity ที่เหมาะสม
4. ถ้าสินค้าใกล้หมด ให้แจ้งเตือนความเร่งด่วน
5. ตอบกระชับ ใช้ตารางถ้ามีหลายรายการ"""
payload = {
"model": "deepseek-v3.2",
"messages": [
{"role": "system", "content": "ผู้ช่วยจัดการสินค้าคงคลังที่เป็นมืออาชีพ"},
{"role": "user", "content": prompt}
],
"temperature": 0.2,
"max_tokens": 500
}
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
response = requests.post(
f"{self.base_url}/chat/completions",
headers=headers,
json=payload,
timeout=30
)
if response.status_code == 401:
raise PermissionError("❌ API Key ไม่ถูกต้อง กรุณาตรวจสอบที่ https://www.holysheep.ai/register")
response.raise_for_status()
return response.json()['choices'][0]['message']['content']
def generate_daily_report(self, inventory_data: Dict) -> str:
"""สร้างรายงานประจำวันอัตโนมัติ"""
total_value = sum(
item.get('stock', 0) * item.get('unit_cost', 0)
for item in inventory_data.values()
)
low_stock_count = sum(
1 for item in inventory_data.values()
if item.get('stock', 0) < item.get('reorder_point', 0)
)
report_prompt = f"""สร้างรายงานสินค้าคงคลังประจำวัน {datetime.now().strftime('%d/%m/%Y')}
สรุป:
- จำนวน SKU ทั้งหมด: {len(inventory_data)}
- มูลค่าสินค้าคงคลังรวม: ฿{total_value:,.0f}
- สินค้าใกล้หมด (ต่ำกว่า Reorder Point): {low_stock_count} รายการ
รายละเอียดสินค้าใกล้หมด:
{json.dumps(self.inventory_context.get('low_stock_items', [])[:5], indent=2, ensure_ascii=False)}
กรุณาสร้างรายงานที่ประกอบด้วย:
1. สรุปสถานะโดยรวม (ดี/ปานกลาง/ต้องแก้ไข)
2. รายการสินค้าเร่งด่วนที่ต้องสั่งซื้อ
3. คำแนะนำสำหรับวันนี้
4. ความเสี่ยงที่ต้องจับตามอง
ตอบเป็นภาษาไทย กระชับ เข้าใจง่าย"""
payload = {
"model": "gpt-4.1",
"messages": [
{"role": "user", "content": report_prompt}
],
"temperature": 0.3,
"max_tokens": 600
}
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
response = requests.post(
f"{self.base_url}/chat/completions",
headers=headers,
json=payload,
timeout=45
)
return response.json()['choices'][0]['message']['content']
ตัวอย่างการใช้งาน Chatbot
def demo_inventory_chatbot():
API_KEY = "YOUR_HOLYSHEEP_API_KEY"
chatbot = InventoryChatbot(API_KEY)
# ข้อมูลสินค้าคงคลังตัวอย่าง
inventory = {
"SKU-001": {"name": "เสื้อยืด Cotton Premium", "stock": 45, "reorder_point": 100, "unit_cost": 150},
"SKU-002": {"name": "กางเกงยีนส์ Slim Fit", "stock": 200, "reorder_point": 80, "unit_cost": 450},
"SKU-003": {"name": "รองเท้าสนีคเกอร์ Running", "stock": 12, "reorder_point": 50, "unit_cost": 890},
"SKU-004": {"name": "กระเป๋า Backpack Urban", "stock": 75, "reorder_point": 60, "unit_cost": 650},
}
# อัปเดต Context
chatbot.update_inventory_context(inventory)
# ถามคำถาม
questions = [
"มีสินค้าตัวไหนที่ต้องสั่งซื้อด่วนบ้าง?",
"ถ้าต้องการสั่งสินค้า SKU-003 ควรสั่งกี่ชิ้น?",
"สรุปสถานะสินค้าคงคลังวันนี้เป็นอย่างไร?"
]
for q in questions:
print(f"\n❓ คำถาม: {q}")
answer = chatbot.ask(q, inventory)
print(f"💬 คำตอบ: {answer}")
# สร้างรายงานประจำวัน
print("\n" + "="*50)
print("📋 รายงานประจำวัน")
print("="*50)
report = chatbot.generate_daily_report(inventory)
print(report)
if __name__ == "__main__":
demo_inventory_chatbot()
ข้อผิดพลาดที่พบบ่อยและวิธีแก้ไข
1. ConnectionError: Timeout ขณะเรียก LLM API
# ❌ วิธีผิด: ไม่มีการจัดการ Timeout
response = requests.post(url, json=payload) # ค้างถ้า server ตอบช้า
✅ วิธีถูก: เพ