WordPress Headless MLOps Workflow คืออะไร
WordPress Headless CMS คือการใช้ WordPress เป็น backend สำหรับจัดการเนื้อหา โดยแยก frontend ออกไปใช้ framework อื่น เช่น Next.js, Nuxt.js หรือ Gatsby เข้าถึงข้อมูลผ่าน REST API หรือ GraphQL (WPGraphQL) MLOps (Machine Learning Operations) คือแนวปฏิบัติสำหรับ deploy, monitor และ maintain ML models ใน production การรวมสองแนวคิดนี้ช่วยสร้าง content platform ที่ใช้ AI/ML เช่น content recommendation, auto-tagging, sentiment analysis และ SEO optimization
Headless WordPress Architecture
# headless_arch.py — Headless WordPress + ML architecture
import json
class HeadlessMLArch:
LAYERS = {
"cms_backend": {
"name": "WordPress CMS Backend",
"description": "จัดการ content, users, media — expose ผ่าน REST API/GraphQL",
"components": ["WordPress Core", "WPGraphQL", "ACF (Advanced Custom Fields)", "Custom Post Types"],
},
"ml_layer": {
"name": "ML Service Layer",
"description": "ML models สำหรับ content intelligence — recommendation, classification, NLP",
"components": ["Model Serving (FastAPI)", "Feature Store", "Model Registry (MLflow)", "Training Pipeline"],
},
"api_gateway": {
"name": "API Gateway",
"description": "รวม WordPress API + ML API เข้าด้วยกัน — auth, rate limiting, caching",
"components": ["Kong/Nginx", "Redis Cache", "JWT Auth"],
},
"frontend": {
"name": "Frontend (SSG/SSR)",
"description": "Next.js/Nuxt.js สำหรับ render — ISR สำหรับ performance",
"components": ["Next.js", "React", "TailwindCSS", "Vercel/Netlify"],
},
"mlops_infra": {
"name": "MLOps Infrastructure",
"description": "CI/CD สำหรับ ML models — training, testing, deployment, monitoring",
"components": ["MLflow", "DVC", "GitHub Actions", "Prometheus/Grafana"],
},
}
def show_architecture(self):
print("=== Headless WordPress + MLOps ===\n")
for key, layer in self.LAYERS.items():
print(f"[{layer['name']}]")
print(f" {layer['description']}")
print(f" Components: {', '.join(layer['components'][:4])}")
print()
arch = HeadlessMLArch()
arch.show_architecture()
ML Use Cases for WordPress
# ml_usecases.py — ML use cases for WordPress content
import json
class MLUseCases:
CASES = {
"recommendation": {
"name": "Content Recommendation",
"description": "แนะนำบทความที่เกี่ยวข้อง — เพิ่ม engagement + pageviews",
"model": "Collaborative filtering + Content-based (TF-IDF, embeddings)",
"input": "User reading history, content features, categories",
"output": "Top-N recommended posts",
},
"auto_tagging": {
"name": "Auto-Tagging & Categorization",
"description": "จัดหมวดหมู่และ tag บทความอัตโนมัติเมื่อ publish",
"model": "Text classification (BERT, distilbert-base-multilingual)",
"input": "Post title + content",
"output": "Categories, tags, topics",
},
"seo_optimization": {
"name": "SEO Content Optimization",
"description": "วิเคราะห์ content และแนะนำ SEO improvements",
"model": "NLP analysis + keyword extraction + readability scoring",
"input": "Post content, target keyword",
"output": "SEO score, suggestions, meta description",
},
"sentiment": {
"name": "Comment Sentiment Analysis",
"description": "วิเคราะห์ sentiment ของ comments — filter toxic content",
"model": "Sentiment classifier (multilingual BERT)",
"input": "Comment text",
"output": "Positive/Negative/Neutral score, toxicity flag",
},
"image_alt": {
"name": "Auto Image Alt Text",
"description": "สร้าง alt text สำหรับรูปภาพอัตโนมัติ — accessibility + SEO",
"model": "Image captioning (BLIP, GIT)",
"input": "Image file",
"output": "Descriptive alt text in Thai/English",
},
}
def show_cases(self):
print("=== ML Use Cases ===\n")
for key, case in self.CASES.items():
print(f"[{case['name']}]")
print(f" {case['description']}")
print(f" Model: {case['model']}")
print()
cases = MLUseCases()
cases.show_cases()
ML Service Implementation
# ml_service.py — ML service for WordPress
import json
class MLService:
CODE = """
# content_ml_service.py — FastAPI ML service for WordPress
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np
import requests
import json
app = FastAPI(title="WordPress ML Service")
# Load models
embedder = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2')
class ContentRequest(BaseModel):
post_id: int
title: str
content: str
class RecommendationResponse(BaseModel):
post_id: int
recommendations: list
# Cache post embeddings
post_embeddings = {}
@app.post("/api/ml/recommend")
async def recommend_content(request: ContentRequest):
'''Get content recommendations based on similarity'''
# Get embedding for current post
text = f"{request.title} {request.content[:500]}"
current_embedding = embedder.encode([text])[0]
# Compare with all cached embeddings
if not post_embeddings:
await refresh_embeddings()
similarities = []
for pid, emb in post_embeddings.items():
if pid != request.post_id:
sim = cosine_similarity([current_embedding], [emb])[0][0]
similarities.append((pid, float(sim)))
# Top 5 recommendations
similarities.sort(key=lambda x: x[1], reverse=True)
top_5 = similarities[:5]
return {
"post_id": request.post_id,
"recommendations": [{"post_id": pid, "score": round(score, 3)} for pid, score in top_5],
}
@app.post("/api/ml/auto-tag")
async def auto_tag(request: ContentRequest):
'''Auto-generate tags for a post'''
from keybert import KeyBERT
kw_model = KeyBERT(model=embedder)
keywords = kw_model.extract_keywords(
request.content,
keyphrase_ngram_range=(1, 2),
stop_words=None,
top_n=10,
)
return {
"post_id": request.post_id,
"tags": [{"keyword": kw, "score": round(score, 3)} for kw, score in keywords],
}
@app.post("/api/ml/seo-analyze")
async def seo_analyze(title: str, content: str, target_keyword: str = ""):
'''Analyze content for SEO'''
word_count = len(content.split())
has_keyword_title = target_keyword.lower() in title.lower() if target_keyword else False
keyword_density = content.lower().count(target_keyword.lower()) / max(word_count, 1) * 100 if target_keyword else 0
score = 0
suggestions = []
if word_count >= 1000: score += 20
else: suggestions.append(f"เพิ่มเนื้อหาให้อย่างน้อย 1000 คำ (ปัจจุบัน {word_count})")
if has_keyword_title: score += 20
else: suggestions.append("เพิ่ม keyword ในชื่อบทความ")
if 1 <= keyword_density <= 3: score += 20
else: suggestions.append(f"Keyword density ควรอยู่ 1-3% (ปัจจุบัน {keyword_density:.1f}%)")
return {
"seo_score": score,
"word_count": word_count,
"keyword_density": round(keyword_density, 2),
"suggestions": suggestions,
}
async def refresh_embeddings():
'''Fetch all posts from WordPress and compute embeddings'''
resp = requests.get("https://cms.example.com/wp-json/wp/v2/posts?per_page=100")
posts = resp.json()
for post in posts:
text = f"{post['title']['rendered']} {post['excerpt']['rendered']}"
post_embeddings[post['id']] = embedder.encode([text])[0]
"""
def show_code(self):
print("=== ML Service ===")
print(self.CODE[:600])
ml = MLService()
ml.show_code()
MLOps Pipeline
# mlops_pipeline.py — MLOps pipeline for WordPress ML
import json
class MLOpsPipeline:
PIPELINE = """
# .github/workflows/mlops.yml
name: MLOps Pipeline
on:
push:
paths: ['ml/**', 'models/**']
schedule:
- cron: '0 2 * * 0' # Weekly retrain
jobs:
test-models:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: pip install -r ml/requirements.txt
- name: Run model tests
run: pytest ml/tests/ -v
- name: Validate model performance
run: python ml/scripts/validate_model.py --min-accuracy 0.85
retrain:
needs: test-models
if: github.event_name == 'schedule'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: pip install -r ml/requirements.txt
- name: Fetch training data from WordPress
run: python ml/scripts/fetch_training_data.py
env:
WP_API_URL: }
- name: Retrain recommendation model
run: python ml/scripts/train_recommender.py
- name: Log to MLflow
run: python ml/scripts/log_mlflow.py
env:
MLFLOW_TRACKING_URI: }
- name: Deploy model
run: python ml/scripts/deploy_model.py
"""
MLFLOW_CODE = """
# train_recommender.py — Train with MLflow tracking
import mlflow
from sentence_transformers import SentenceTransformer
import json
mlflow.set_experiment("wordpress-recommender")
with mlflow.start_run():
# Log parameters
mlflow.log_param("model_name", "paraphrase-multilingual-MiniLM-L12-v2")
mlflow.log_param("training_posts", 5000)
# Train / compute embeddings
model = SentenceTransformer("paraphrase-multilingual-MiniLM-L12-v2")
# Evaluate
accuracy = 0.89 # recommendation relevance score
mlflow.log_metric("accuracy", accuracy)
mlflow.log_metric("latency_ms", 45)
# Log model
mlflow.sklearn.log_model(model, "recommender")
print(f"Model trained: accuracy={accuracy}")
"""
def show_pipeline(self):
print("=== MLOps Pipeline ===")
print(self.PIPELINE[:500])
def show_mlflow(self):
print(f"\n=== MLflow Training ===")
print(self.MLFLOW_CODE[:400])
pipeline = MLOpsPipeline()
pipeline.show_pipeline()
pipeline.show_mlflow()
WordPress Plugin Integration
# wp_plugin.py — WordPress plugin for ML integration
import json
class WPPluginIntegration:
PLUGIN_CODE = """
// wp-ml-integration.php — WordPress ML Integration Plugin
/*
Plugin Name: WP ML Integration
Description: Connect WordPress with ML services
Version: 1.0.0
*/
// Auto-tag on publish
add_action('publish_post', function($post_id) {
$post = get_post($post_id);
$response = wp_remote_post('http://ml-service:8000/api/ml/auto-tag', [
'body' => json_encode([
'post_id' => $post_id,
'title' => $post->post_title,
'content' => wp_strip_all_tags($post->post_content),
]),
'headers' => ['Content-Type' => 'application/json'],
]);
if (!is_wp_error($response)) {
$data = json_decode(wp_remote_retrieve_body($response), true);
// Set tags
$tags = array_column($data['tags'], 'keyword');
wp_set_post_tags($post_id, array_slice($tags, 0, 5), true);
}
});
// Add recommendations to REST API
add_action('rest_api_init', function() {
register_rest_route('ml/v1', '/recommend/(?P\d+)', [
'methods' => 'GET',
'callback' => function($request) {
$post_id = $request['id'];
$post = get_post($post_id);
$response = wp_remote_post('http://ml-service:8000/api/ml/recommend', [
'body' => json_encode([
'post_id' => $post_id,
'title' => $post->post_title,
'content' => wp_strip_all_tags($post->post_content),
]),
'headers' => ['Content-Type' => 'application/json'],
]);
return json_decode(wp_remote_retrieve_body($response), true);
},
]);
});
// SEO analysis meta box
add_action('add_meta_boxes', function() {
add_meta_box('ml-seo', 'ML SEO Analysis', function($post) {
echo 'Analyzing...';
echo '';
}, 'post', 'side');
});
"""
def show_plugin(self):
print("=== WordPress Plugin ===")
print(self.PLUGIN_CODE[:600])
plugin = WPPluginIntegration()
plugin.show_plugin()
FAQ - คำถามที่พบบ่อย
Q: Headless WordPress คุ้มค่าไหม?
A: คุ้มถ้า: ต้องการ performance สูง (ISR/SSG), ต้องการ custom frontend, ต้องการ integrate ML/AI ไม่คุ้มถ้า: ทีมเล็ก ใช้ WordPress themes ได้เพียงพอ, ไม่มี frontend developer ข้อดี: performance, security, flexibility, modern stack ข้อเสีย: ซับซ้อนกว่า, ต้อง maintain 2 systems, plugin ecosystem จำกัด
Q: ML model ไหนเหมาะกับ content ภาษาไทย?
A: Embeddings: paraphrase-multilingual-MiniLM-L12-v2 (รองรับไทย ดีมาก) Classification: bert-base-multilingual-cased หรือ WangchanBERTa (เฉพาะไทย) Keyword extraction: KeyBERT + multilingual model Sentiment: multilingual BERT หรือ ThaiNLP libraries แนะนำ: เริ่มจาก multilingual models → fine-tune กับ Thai data ถ้าต้องการ accuracy สูงขึ้น
Q: MLOps จำเป็นสำหรับ WordPress ไหม?
A: ถ้าใช้ ML จริงจัง: จำเป็น — model drift, retraining, monitoring ถ้าใช้แค่ simple features: ไม่จำเป็น — ใช้ pre-trained models + API เริ่มจาก: simple deployment (FastAPI + Docker) → เพิ่ม MLflow tracking → CI/CD pipeline Full MLOps: ถ้ามี 3+ models ใน production + ต้อง retrain regularly
Q: WPGraphQL กับ REST API อันไหนดี?
A: WPGraphQL: query เฉพาะ fields ที่ต้องการ → ลด data transfer, flexible REST API: built-in, simple, ecosystem ใหญ่กว่า, caching ง่ายกว่า สำหรับ ML integration: REST API เพียงพอ — ML service เรียก REST สำหรับ Frontend: WPGraphQL ดีกว่า — ลด over-fetching แนะนำ: ใช้ทั้งสอง — WPGraphQL สำหรับ frontend, REST สำหรับ ML services