สร้าง LINE AI Agent แบบออฟไลน์ 100% ด้วย Ollama + MCP + LINE Messaging API: ระบบตอบลูกค้าอัตโนมัติภาษาไทยตาม PDPA สำหรับ SME ไทย
ลูกค้าทัก LINE มาตอนดึก คุณตอบไม่ได้ แต่ส่งข้อมูลไป Cloud AI กลัวผิด PDPA บทความนี้พาทำระบบตอบกลับอัตโนมัติด้วย AI ที่รันบนเครื่องคุณเอง ปลอดภัย 100%
สารบัญ

ทำไม SME ไทยต้องวิตกเรื่อง AI บน Cloud?
เคยไหมที่ลูกค้าทัก LINE มาตอนตี 2 ถามราคาสินค้า พอเช้ามาคุณเปิดดู ลูกค้าหายไปแล้ว เพราะไปซื้อของร้านอื่นที่ตอบกลับเร็วกว่า
การใช้ ChatGPT API หรือ Claude API มาทำบอทตอบลูกค้าแน่นอนว่าสะดวกมาก แต่มีอุปสรรคใหญ่สำหรับธุรกิจในไทย นั่นคือ พระราชบัญญัติคุ้มครองข้อมูลส่วนบุคคล (PDPA)
เมื่อลูกค้าส่งข้อมูลส่วนบุคคล เช่น ชื่อ ที่อยู่ เบอร์โทร เข้ามาในระบบ แล้วคุณส่งข้อมูลเหล่านั้นไปประมวลผลบน Cloud ของต่างประเทศ โดยไม่มีมาตรการคุ้มครองที่รัดกุม อาจถือว่าเป็นการเปิดเผยข้อมูลส่วนบุคคลไปยังผู้ประมวลผลข้อมูล (Data Processor) ซึ่งมีความเสี่ยงต่อการละเมิด PDPA ได้
ทางออกที่กำลังจะมาแรงสำหรับนักพัฒนาและ SME คือการรัน AI บนเครื่องของเราเอง (On-premise) ด้วย Ollama และเชื่อมต่อเข้ากับ LINE Messaging API ผ่านสถาปัตยกรรม MCP (Model Context Protocol)
เครื่องมือที่ต้องเตรียม
ก่อนเริ่มเขียนโค้ด มาดูส่วนประกอบหลักที่เราจะใช้งานกันก่อน
- Ollama: เครื่องมือสำหรับรัน Large Language Model (LLM) บนเครื่องคอมพิวเตอร์ของเราแบบออฟไลน์ รองรับหลายโมเดลทั้ง Llama 3, Qwen หรือ Typhoon (โมเดลภาษาไทย)
- MCP (Model Context Protocol): มาตรฐานเปิดที่พัฒนาโดย Anthropic ใช้สำหรับเชื่อมต่อ AI เข้ากับแหล่งข้อมูลและเครื่องมือต่างๆ อย่างปลอดภัย
- LINE Messaging API: ช่องทางสื่อสารกับลูกค้า รองรับ Webhook สำหรับรับข้อความและตอบกลับ
- Python + FastAPI: สำหรับสร้าง Webhook Server และจัดการ Logic การทำงาน
เริ่มต้นติดตั้ง Ollama และโมเดลภาษาไทย
ขั้นแรก ดาวน์โหลดและติดตั้ง Ollama จากเว็บไซต์หลัก จากนั้นเปิด Terminal แล้วดึงโมเดลที่รองรับภาษาไทยมาใช้งาน ในที่นี้แนะนำ qwen2.5 หรือ typhoon ที่เก่งภาษาไทยค่อนข้างดี
# ดึงโมเดล Qwen 2.5 ขนาด 7B (ต้องการ RAM ประมาณ 8GB)
ollama pull qwen2.5:7b
# ทดสอบรันโมเดล
ollama run qwen2.5:7b "สวัสดีครับ แนะนำตัวเองหน่อย"
หากเครื่องคุณมี RAM น้อย แนะนำให้ใช้โมเดลขนาดเล็กลง เช่น qwen2.5:3b แต่ความเร็วและความเข้าใจภาษาอาจลดลงตามไปด้วย
ออกแบบสถาปัตยกรรมระบบ
ระบบของเราจะทำงานดังนี้:
- ลูกค้าส่งข้อความเข้า LINE Official Account
- LINE ส่ง Webhook ไปยัง FastAPI Server ของเรา
- Server ส่งข้อความไปประมวลผลที่ Ollama (ผ่าน MCP Client)
- Ollama สร้างคำตอบและส่งกลับมา
- Server ใช้ LINE Messaging API ตอบกลับลูกค้า
ข้อมูลทั้งหมดอยู่ในเครื่องของเรา ไม่มีการส่งออกไปยัง Cloud ภายนอกเลย
เขียน FastAPI Webhook Server
สร้างโปรเจกต์ Python ใหม่และติดตั้งไลบรารีที่จำเป็น
pip install fastapi uvicorn line-bot-sdk requests pydantic
สร้างไฟล์ main.py และเขียนโค้ด Webhook สำหรับรับข้อความจาก LINE
from fastapi import FastAPI, Request, HTTPException
from linebot.v3 import WebhookHandler
from linebot.v3.messaging import ApiClient, Configuration, MessagingApi, ReplyMessageRequest, TextMessage
from linebot.v3.webhooks import MessageEvent, TextMessageContent
import requests
import os
app = FastAPI()
# ตั้งค่า LINE Channel
LINE_CHANNEL_ACCESS_TOKEN = os.getenv("LINE_CHANNEL_ACCESS_TOKEN")
LINE_CHANNEL_SECRET = os.getenv("LINE_CHANNEL_SECRET")
configuration = Configuration(access_token=LINE_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(LINE_CHANNEL_SECRET)
# ฟังก์ชันเรียก Ollama API
async def call_ollama(prompt: str) -> str:
url = "http://localhost:11434/api/generate"
payload = {
"model": "qwen2.5:7b",
"prompt": f"คุณคือแม่ค้าออนไลน์ที่เป็นมิตร ตอบคำถามลูกค้าสั้นกระชับเป็นภาษาไทย: {prompt}",
"stream": False
}
response = requests.post(url, json=payload)
return response.json().get("response", "ขออภัยค่ะ ตอบไม่ได้ในตอนนี้")
@app.post("/webhook")
async def webhook(request: Request):
signature = request.headers.get("X-Line-Signature")
body = await request.body()
try:
handler.handle(body.decode(), signature)
except Exception as e:
raise HTTPException(status_code=400, detail=str(e))
return "OK"
@handler.add(MessageEvent, message=TextMessageContent)
def handle_message(event):
user_message = event.message.text
# เรียก Ollama ประมวลผล (ต้องรันใน async context)
import asyncio
loop = asyncio.new_event_loop()
reply_text = loop.run_until_complete(call_ollama(user_message))
# ตอบกลับ LINE
with ApiClient(configuration) as api_client:
line_api = MessagingApi(api_client)
line_api.reply_message(
ReplyMessageRequest(
reply_token=event.reply_token,
messages=[TextMessage(text=reply_text)]
)
)
รัน Server ด้วยคำสั่ง:
uvicorn main:app --host 0.0.0.0 --port 8000
เชื่อมต่อ MCP เพื่อเพิ่มความสามารถ
การใช้ MCP ช่วยให้เราเพิ่มเครื่องมือ (Tools) ให้ AI ได้โดยไม่ต้องแก้โค้ดหลัก เช่น การค้นหาสินค้าในฐานข้อมูล หรือตรวจสอบสต็อกสินค้า
สร้างไฟล์ mcp_tools.py สำหรับนิยามเครื่องมือที่ AI สามารถเรียกใช้ได้
import json
from typing import Any
# จำลองฐานข้อมูลสินค้า (ในการใช้งานจริงควรเชื่อม PostgreSQL หรือ SQLite)
PRODUCTS = {
"เสื้อยืด": {"price": 290, "stock": 15, "sizes": ["S", "M", "L", "XL"]},
"กางเกงยีนส์": {"price": 890, "stock": 8, "sizes": ["30", "32", "34", "36"]},
"รองเท้าผ้าใบ": {"price": 1290, "stock": 0, "sizes": ["40", "41", "42"]}
}
def get_product_info(product_name: str) -> str:
"""ค้นหาข้อมูลสินค้าจากชื่อ"""
for key, info in PRODUCTS.items():
if product_name in key:
stock_status = "มีสินค้า" if info["stock"] > 0 else "สินค้าหมด"
return f"{key}: ราคา {info['price']} บาท, {stock_status}, ไซส์ {', '.join(info['sizes'])}"
return "ไม่พบสินค้าที่ค้นหา"
# นิยาม MCP Tools
MCP_TOOLS = [
{
"name": "get_product_info",
"description": "ค้นหาข้อมูลสินค้า เช่น ราคา สต็อก ไซส์",
"parameters": {
"type": "object",
"properties": {
"product_name": {"type": "string", "description": "ชื่อสินค้าที่ต้องการค้นหา"}
},
"required": ["product_name"]
}
}
]
จากนั้นปรับปรุงฟังก์ชัน call_ollama ให้รองรับการเรียกใช้ Tools ผ่าน MCP
async def call_ollama_with_tools(prompt: str) -> str:
url = "http://localhost:11434/api/generate"
# ตรวจสอบว่าผู้ใช้ถามเรื่องสินค้าหรือไม่
system_prompt = f"""คุณคือแม่ค้าออนไลน์ หากลูกค้าถามเรื่องสินค้า ให้ใช้ฟังก์ชัน get_product_info
คำถามลูกค้า: {prompt}
ตอบเป็นภาษาไทยสั้นกระชับเท่านั้น"""
payload = {
"model": "qwen2.5:7b",
"prompt": system_prompt,
"stream": False,
"format": "json"
}
response = requests.post(url, json=payload)
result = response.json().get("response", "")
# ตรวจสอบว่า AI ต้องการเรียกใช้ Tool หรือไม่
try:
parsed = json.loads(result)
if "product_name" in parsed:
return get_product_info(parsed["product_name"])
except json.JSONDecodeError:
pass
return result
ข้อควรระวังด้าน PDPA
แม้ระบบนี้จะรันออฟไลน์ แต่ก็มีข้อควรระวังเพื่อให้สอดคล้องกับ PDPA อย่างสมบูรณ์
เก็บ Log อย่างระมัดระวัง
อย่าบันทึกข้อความสนทนาที่มีข้อมูลส่วนบุคคลลงในไฟล์ Log ถ้าจำเป็นต้องเก็บ ให้ทำการลบข้อมูลที่ระบุตัวตนได้ (Anonymization) ก่อนเสมอ
import re
def anonymize_text(text: str) -> str:
# ลบเบอร์โทรศัพท์
text = re.sub(r'\b0\d{8,9}\b', '[เบอร์โทร]', text)
# ลบเลขบัตรประชาชน
text = re.sub(r'\b\d{13}\b', '[เลขบัตร]', text)
return text
กำหนดนโยบายเก็บรักษาข้อมูล
กำหนดระยะเวลาเก็บรักษาข้อมูลสนทนาอย่างชัดเจน เช่น เก็บไว้ 30 วัน แล้วลบทิ้ง พร้อมแจ้งให้ลูกค้าทราบในเงื่อนไขการใช้บริการ
แจ้งสิทธิลูกค้า
ใน LINE Official Account ควรมีข้อความแจ้งว่ามีระบบ AI ตอบกลับอัตโนมัติ และลูกค้ามีสิทธิขอเข้าถึงหรือลบข้อมูลส่วนบุคคลได้ตาม PDPA
ทดสอบระบบจริง
หลังจากรัน Server และ Ollama แล้ว ใช้ ngrok เพื่อเปิด Port ให้ LINE Webhook เข้าถึงได้
ngrok http 8000
นำ URL ที่ได้ไปตั้งค่า Webhook ใน LINE Developers Console โดยใช้ path /webhook
ทดลองทักข้อความเข้า LINE Official Account เช่น "มีเสื้อยืดไหม ราคาเท่าไหร่" ระบบควรตอบกลับด้วยราคาและสต็อกสินค้าจากฐานข้อมูลของเรา
สรุปและก้าวต่อไป
การสร้าง LINE AI Agent แบบออฟไลน์ด้วย Ollama และ MCP ไม่เพียงแต่ช่วยประหยัดค่าใช้จ่ายค่า API รายเดือน แต่ยังปกป้องข้อมูลลูกค้าตามมาตรฐาน PDPA ได้อย่างมั่นใจ ข้อมูลทั้งหมดอยู่ในเครื่องของคุณ ไม่รั่วไหลไปยังบริการภายนอก
ลองนำโค้ดตัวอย่างนี้ไปปรับใช้กับธุรกิจของคุณ แล้วเล่าให้ฟังในคอมเมนต์ได้เลยว่าผลเป็นอย่างไร หรือมีปัญหาส่วนไหน อยากให้เขียนบทความต่อเรื่องการเชื่อม MCP เข้ากับ Vector Database สำหรับทำ RAG แบบออฟไลน์ไหม กดติดตามและแชร์บทความนี้ให้เพื่อนนักพัฒนาด้วยนะครับ
เนื้อหาที่จัดทำโดยมี AI ช่วยจะมีป้ายกำกับ "เรียบเรียงโดยมี AI ช่วย" เพื่อให้คุณทราบอย่างชัดเจน เราถือว่าความโปร่งใสเรื่องการใช้ AI เป็นสิ่งสำคัญต่อความไว้วางใจของผู้อ่าน
ความคิดเห็น (0)
ยังไม่มีความคิดเห็น — มาเป็นคนแรกกันเถอะ!