สวัสดีครับ ผมเชื่อว่าหลายคนที่เพิ่งเริ่มใช้งาน AI ผ่าน API คงเคยเจอปัญหาแบบนี้: "สั่งให้ AI ดึงข้อมูลจากเว็บมา แต่มันตอบกลับมาเป็นข้อความยาวเหยียด แทนที่จะเป็นข้อมูลที่จัดเก็บลงฐานข้อมูลได้เลย" — ผมเจอปัญหานี้บ่อยมากในช่วงแรกที่เริ่มใช้งาน และวันนี้ผมจะมาแบ่งปันวิธีแก้ที่ใช้มาจริงๆ จนได้ผลลัพธ์ที่ดีมาก
บทความนี้จะสอนเทคนิคที่เรียกว่า JSON Schema Structured Output ซึ่งจะช่วยให้ AI ตอบกลับมาในรูปแบบที่คุณกำหนดได้แม่นยำ เหมาะสำหรับนำไปใช้งานต่อได้ทันที ไม่ว่าจะเป็นการเก็บข้อมูล สร้างรายงาน หรือประมวลผลอัตโนมัติ
ทำความรู้จักกับ JSON Schema แบบง่ายๆ
ก่อนจะไปลงมือทำ ผมอยากให้เข้าใจพื้นฐานก่อนนะครับ ลองนึกภาพว่า JSON Schema ก็เหมือนกับ "แบบฟอร์ม" ที่คุณกำหนดให้ AI กรอกข้อมูลตามช่องที่คุณต้องการ ถ้าเป็นแบบฟอร์มย่อยๆ ก็จะมีช่องให้กรอก ชื่อ-นามสกุล อายุ เบอร์โทร ที่อยู่ ซึ่งถ้าคุณกำหนดแบบฟอร์มไว้ชัดเจน AI ก็จะตอบมาตรงตามที่คุณต้องการพอดี
{
"ชื่อ": "สมชาย",
"อายุ": 28,
"อาชีพ": "วิศวกรซอฟต์แวร์"
}
นี่คือตัวอย่างข้อมูล JSON ที่มีโครงสร้างชัดเจน คุณสามารถอ่านและเข้าใจได้ทันทีว่าแต่ละช่องคืออะไร
เริ่มต้นใช้งาน: ตั้งค่าโครงสร้างข้อมูลที่ต้องการ
ขั้นตอนแรก คุณต้องสร้างโครงสร้าง JSON Schema ที่บอก AI ว่าต้องการข้อมูลอะไรบ้าง มาดูตัวอย่างกันครับ สมมติว่าผมต้องการให้ AI วิเคราะห์รีวิวสินค้าแล้วดึงข้อมูลออกมาเป็นระเบียบ
import anthropic
import json
ตั้งค่า API Key และ Endpoint
client = anthropic.Anthropic(
api_key="YOUR_HOLYSHEEP_API_KEY",
base_url="https://api.holysheep.ai/v1"
)
กำหนดโครงสร้างข้อมูลที่ต้องการ
schema = {
"name": "product_review_analysis",
"schema": {
"type": "object",
"properties": {
"sentiment": {
"type": "string",
"description": "ความรู้สึกโดยรวม เช่น บวก, ลบ, กลางๆ",
"enum": ["บวก", "ลบ", "กลางๆ"]
},
"score": {
"type": "number",
"description": "คะแนนจาก 1-5"
},
"pros": {
"type": "array",
"items": {"type": "string"},
"description": "ข้อดีที่พบในรีวิว"
},
"cons": {
"type": "array",
"items": {"type": "string"},
"description": "ข้อเสียที่พบในรีวิว"
}
},
"required": ["sentiment", "score"]
}
}
ส่งคำขอพร้อมโครงสร้างที่กำหนด
message = client.beta.messages.create(
model="gpt-4o",
max_tokens=1024,
betas=["json-schema-2024-11-28"],
messages=[{
"role": "user",
"content": 'วิเคราะห์รีวิวนี้: "สินค้าดีมาก แต่ส่งช้าไปหน่อย แพ็คกิ้งก็เฉยๆ"'
}],
json_schema=schema
)
แปลงผลลัพธ์เป็นข้อมูลที่ใช้งานได้
result = json.loads(message.content[0].text)
print(f"ความรู้สึก: {result['sentiment']}")
print(f"คะแนน: {result['score']}")
print(f"ข้อดี: {result['pros']}")
print(f"ข้อเสีย: {result['cons']}")
จากโค้ดด้านบน ผมได้กำหนดโครงสร้างที่บังคับว่าต้องมี sentiment และ score เป็นข้อมูลที่จำเป็น และกำหนด enum ให้ sentiment ต้องเป็นค่าใดค่าหนึ่งจากที่กำหนดไว้ ทำให้ผลลัพธ์ที่ได้มีความแม่นยำและคงที่
การตรวจสอบความถูกต้องของผลลัพธ์ (Validation)
แม้ว่าเราจะกำหนดโครงสร้างไว้แล้ว แต่ในบางกรณี AI อาจตอบมาไม่ตรงตามที่กำหนด ผมจึงแนะนำให้เพิ่มการตรวจสอบความถูกต้องทุกครั้ง เพื่อป้องกันข้อผิดพลาดที่จะเกิดขึ้นในขั้นตอนถัดไป
import anthropic
import json
from jsonschema import validate, ValidationError
ตั้งค่า API Client
client = anthropic.Anthropic(
api_key="YOUR_HOLYSHEEP_API_KEY",
base_url="https://api.holysheep.ai/v1"
)
โครงสร้าง JSON Schema สำหรับตรวจสอบ
schema = {
"type": "object",
"properties": {
"ชื่อสินค้า": {"type": "string"},
"ราคา": {"type": "number", "minimum": 0},
"หมวดหมู่": {
"type": "string",
"enum": ["อาหาร", "เครื่องดื่ม", "เครื่องใช้", "เสื้อผ้า"]
},
"มีสินค้าพร้อมส่ง": {"type": "boolean"}
},
"required": ["ชื่อสินค้า", "ราคา", "หมวดหมู่"]
}
def get_structured_product_data(product_description):
"""ฟังก์ชันดึงข้อมูลสินค้าแบบมีโครงสร้างพร้อมตรวจสอบ"""
response = client.beta.messages.create(
model="gpt-4o",
max_tokens=512,
betas=["json-schema-2024-11-28"],
messages=[{
"role": "system",
"content": "คุณคือผู้ช่วยดึงข้อมูลสินค้า ตอบกลับเฉพาะ JSON ที่ถูกต้องเท่านั้น"
}, {
"role": "user",
"content": f"ดึงข้อมูลจากข้อความนี้: {product_description}"
}],
json_schema={
"name": "product_data",
"schema": schema
}
)
# แปลงข้อความตอบกลับเป็น JSON
result = json.loads(response.content[0].text)
# ตรวจสอบความถูกต้องตามโครงสร้างที่กำหนด
try:
validate(instance=result, schema=schema)
print("ผ่านการตรวจสอบ ✓")
return result
except ValidationError as e:
print(f"พบข้อผิดพลาด: {e.message}")
return None
ทดสอบการใช้งาน
product_info = "กาแฟสดร้อน ราคา 45 บาท หมวดเครื่องดื่ม สินค้าพร้อมส่ง"
data = get_structured_product_data(product_info)
if data:
print(json.dumps(data, ensure_ascii=False, indent=2))
ในโค้ดนี้ ผมได้ใช้ library ที่ชื่อ jsonschema มาช่วยตรวจสอบว่าผลลัพธ์ที่ได้มาตรงตามโครงสร้างที่กำหนดไว้หรือไม่ ถ้าไม่ตรงจะมีการแจ้งเตือนและสามารถจัดการได้ทันที
การจัดการข้อผิดพลาดอย่างมีประสิทธิภาพ
ในการใช้งานจริง มีโอกาสที่จะเกิดข้อผิดพลาดหลายแบบ เช่น API ล่ม, token เกิน limit, หรือ AI ตอบมาไม่ตรง format ผมจึงแนะนำให้สร้างระบบจัดการข้อผิดพลาดที่ครอบคลุม
import anthropic
import json
import time
from typing import Optional
client = anthropic.Anthropic(
api_key="YOUR_HOLYSHEEP_API_KEY",
base_url="https://api.holysheep.ai/v1"
)
class APIClientError(Exception):
"""Exception สำหรับข้อผิดพลาดทั่วไปของ API"""
pass
class ValidationError(Exception):
"""Exception สำหรับข้อมูลไม่ถูกต้องตาม schema"""
pass
def safe_api_call(prompt: str, max_retries: int = 3) -> Optional[dict]:
"""
เรียก API อย่างปลอดภัยพร้อมระบบ retry และ validation
"""
schema = {
"type": "object",
"properties": {
"หัวข้อ": {"type": "string"},
"สรุป": {"type": "string", "maxLength": 200},
"คีย์เวิร์ด": {
"type": "array",
"items": {"type": "string"},
"maxItems": 5
}
},
"required": ["หัวข้อ", "สรุป"]
}
for attempt in range(max_retries):
try:
print(f"พยายามครั้งที่ {attempt + 1}/{max_retries}...")
response = client.beta.messages.create(
model="gpt-4o",
max_tokens=256,
betas=["json-schema-2024-11-28"],
messages=[{
"role": "user",
"content": f"สรุปเนื้อหานี้เป็น JSON: {prompt}"
}],
json_schema={"name": "summary", "schema": schema}
)
# แปลงผลลัพธ์
result = json.loads(response.content[0].text)
# ตรวจสอบว่ามีฟิลด์ที่จำเป็นครบหรือไม่
if "หัวข้อ" not in result or "สรุป" not in result:
raise ValidationError("ข้อมูลที่ได้รับไม่ครบถ้วน ลองใหม่")
print("สำเร็จ! ✓")
return result
except json.JSONDecodeError as e:
print(f"ข้อผิดพลาด JSON: {e}")
if attempt < max_retries - 1:
time.sleep(2 ** attempt) # รอเพิ่มขึ้นทีละเท่า
else:
raise APIClientError("ไม่สามารถแปลงผลลัพธ์เป็น JSON ได้")
except Exception as e:
print(f"เกิดข้อผิดพลาด: {e}")
if attempt < max_retries - 1:
time.sleep(2)
else