SiamCafe.net Blog
Technology

WordPress Headless MLOps Workflow

WordPress Headless MLOps Workflow | SiamCafe Blog
2025-10-10· อ. บอม — SiamCafe.net· 1,637 คำ

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

📖 บทความที่เกี่ยวข้อง

WordPress Headless Post-mortem Analysisอ่านบทความ → DALL-E API MLOps Workflowอ่านบทความ → WordPress Headless GitOps Workflowอ่านบทความ → Tailwind CSS v4 MLOps Workflowอ่านบทความ → WordPress Headless Security Hardening ป้องกันแฮกอ่านบทความ →

📚 ดูบทความทั้งหมด →