OpenThai-SystemOne ใหม่
OpenThai-SystemOne คือโมเดลตัดสินใจแบบ System One ภาษาไทย-อังกฤษ โอเพนซอร์ส (Apache 2.0) จาก iApp Technology และ OpenThaiGPT โมเดลนี้ไม่สร้างข้อความ คุณส่ง state (ข้อความหรือ JSON อะไรก็ได้: ticket ฝ่ายสนับสนุน คอมเมนต์ เอกสาร หรือ accessibility tree ของหน้าจอ) พร้อม คำถาม เชิงโครงสร้างหนึ่งข้อขึ้นไป แล้วได้ความน่าจะเป็นที่ผ่านการปรับเทียบแล้วของทุกตัวเลือกในทุกคำถาม ในการคำนวณรอบเดียว รูปแบบ HTTP เหมือนกับ POST /v1/systemone ของ Jev จาก TypeSafe AI ดังนั้นโค้ด SDK ที่เขียนไว้สำหรับ API นั้นชี้มาที่ endpoint นี้ได้โดยไม่ ต้องแก้
| ประเภทคำถาม | คุณให้ | คุณได้ |
|---|---|---|
choice | คำสั่งและตัวเลือกที่ตั้งชื่อไว้สูงสุด 255 ตัวเลือก (ใส่คำอธิบายได้) | ตัวเลือกที่ดีที่สุด ความน่าจะเป็นต่อตัวเลือก confidence และ abstain |
score | คำสั่งและระดับเรียงลำดับ 2 ถึง 10 ระดับ | คะแนนถ่วงน้ำหนักด้วยความน่าจะเป็น (เป็นทศนิยมได้) และความน่าจะเป็นต่อระดับ |
noul | คำถามใช่/ไม่ใช่ | noul = P(ใช่) |
- หน้าโมเดล: OpenThai-SystemOne
- น้ำหนักโมเดล: huggingface.co/iapp/OpenThai-SystemOne
- โค้ดและสูตรการเทรน: github.com/iapp-technology/openthai-systemone
เริ่มต้นใช้งาน
-
สิ่งที่ต ้องมี
- iApp API key ฟรี: สมัคร แล้วไปที่ API Keys และ Create New API Key
- state ที่ต้องการให้ตัดสินใจ และคำถามที่ต้องการคำตอบ
-
Endpoint
Endpoint POST https://api.iapp.co.th/v3/store/openthai/systemoneการยืนยันตัวตน header apikey: <key>Body JSON: state(ข้อความหรือ JSON) และquestions(แผนที่ของคำถามแต่ละประเภท)ข้อจำกัด 100 คำขอต่อนาที และ 1,000 การตัดสินใจต่อวันต่อ key ในช่วงพรีวิวฟรี; 255 ตัวเลือกต่อ choice, 2 ถึง 10 ระดับต่อscore, 64K โทเคนต่อคำขอผลลัพธ์ JSON หนึ่งคำตอบต่อหนึ่งคำถาม usage.output_tokensเป็น 0 เสมอ
ไปที่หน้า จัดการ API Key เพื่อดู API key ที่มีอยู่หรือขอ key ใหม่
ทดลองใช้
ตัวอย่างสี่แบบ: จัดเส้นทาง ticket ภาษาไทย คัดกรองคอมเมนต์ภาษาไทย เลือกองค์ประกอบหน้าจอให้ agent และตรวจความเกี่ยวข้องของ RAG ภาษาอังกฤษ แก้ state หรือคำถามได้ตามต้องการแล้วกดถาม เมื่อเข้าสู่ระบบ API key จะถูกใส่ให้อัตโนมัติ
ตัวอย่างโค้ด
คำขอเดียวกันในทุกภาษา: ticket ฝ่ายสนับสนุนภาษาไทย สามคำถาม หนึ่งการเรียก
- cURL
- Python
- JavaScript
curl -s https://api.iapp.co.th/v3/store/openthai/systemone \
-H "apikey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": {"ticket": "โดนหักเงินซ้ำสองครั้งเมื่อวานนี้ ขอเงินคืนด่วนนะครับ โทรไปสามรอบแล้วไม่มีใครรับ"},
"questions": {
"department": {"type": "choice", "instructions": "ทีมใดควรรับผิดชอบ",
"criteria": {"billing": "การเงิน/คืนเงิน", "technical": "ระบบใช้งานไม่ได้", "sales": null}},
"frustration": {"type": "score", "instructions": "ลูกค้าหงุดหงิดแค่ไหน",
"criteria": ["ใจเย็น", "หงุดหงิดแต่สุภาพ", "โกรธมาก"]},
"refund": {"type": "noul", "instructions": "ลูกค้าขอเงินคืนอย่างชัดเจนหรือไม่"}
}
}'
import requests
resp = requests.post(
"https://api.iapp.co.th/v3/store/openthai/systemone",
headers={"apikey": "YOUR_API_KEY"},
json={
"state": {"ticket": "โดนหักเงินซ้ำสองครั้งเมื่อวานนี้ ขอเงินคืนด่วนนะครับ โทรไปสามรอบแล้วไม่มีใครรับ"},
"questions": {
"department": {"type": "choice", "instructions": "ทีมใดควรรับผิดชอบ",
"criteria": {"billing": "การเงิน/คืนเงิน", "technical": "ระบบใช้งานไม่ได้", "sales": None}},
"frustration": {"type": "score", "instructions": "ลูกค้าหงุดหงิดแค่ไหน",
"criteria": ["ใจเย็น", "หงุดหงิดแต่สุภาพ", "โกรธมาก"]},
"refund": {"type": "noul", "instructions": "ลูกค้าขอเงินคืนอย่างชัดเจนหรือไม่"},
},
},
timeout=30,
)
answers = resp.json()["answers"]
print(answers["department"]["choice"], answers["frustration"]["score"], answers["refund"]["noul"])
# ส่งเคสที่ความมั่นใจต่ำไปโมเดลใหญ่หรือคน
if answers["department"]["confidence"] < 0.6:
print("escalate")
const res = await fetch("https://api.iapp.co.th/v3/store/openthai/systemone", {
method: "POST",
headers: { apikey: "YOUR_API_KEY", "Content-Type": "application/json" },
body: JSON.stringify({
state: { ticket: "โดนหักเงินซ้ำสองครั้งเมื่อวานนี้ ขอเงินคืนด่วนนะครับ โทรไปสามรอบแล้วไม่มีใครรับ" },
questions: {
department: { type: "choice", instructions: "ทีมใดควรรับผิดชอบ",
criteria: { billing: "การเงิน/คืนเงิน", technical: "ระบบใ ช้งานไม่ได้", sales: null } },
frustration: { type: "score", instructions: "ลูกค้าหงุดหงิดแค่ไหน",
criteria: ["ใจเย็น", "หงุดหงิดแต่สุภาพ", "โกรธมาก"] },
refund: { type: "noul", instructions: "ลูกค้าขอเงินคืนอย่างชัดเจนหรือไม่" },
},
}),
});
const { answers, usage } = await res.json();
console.log(answers.department.choice, answers.frustration.score, answers.refund.noul, usage);
ผลลัพธ์
ผลลัพธ์ที่วัดจริงของคำขอด้านบน (166 โทเคนขาเข้า 0 โทเคนขาออก การคำนวณรอบเดียว):
{
"model": "openthai-systemone",
"answers": {
"department": {"type": "choice", "choice": "billing",
"probabilities": {"billing": 0.963, "technical": 0.011, "sales": 0.026},
"confidence": 0.83, "abstain": 0.085},
"frustration": {"type": "score", "score": 1.95,
"legend": {"0": "ใจเย็น", "1": "หงุดหงิดแต่สุภาพ", "2": "โกรธมาก"},
"probabilities": {"0": 0.012, "1": 0.031, "2": 0.957}, "confidence": 0.82},
"refund": {"type": "noul", "noul": 0.946}
},
"usage": {"input_tokens": 166, "output_tokens": 0}
}
การอ่านคำตอบ
choice:choiceคือตัวเลือกที่ดีที่สุดprobabilitiesรวมกันได้ 1 ในตัวเลือกที่คุณให้confidenceคือ 1 ลบด้วยเอนโทรปีที่ทำให้เป็นมาตรฐาน และabstainคือความน่าจะเป็นที่ไม่มีตัวเลือกใดเหมาะ (ส่วนขยายของ iApp)score:scoreคือดัชนีระดับถ่วงน้ำหนักด้วยความน่าจะเป็น (เป็นทศนิยมได้)probabilitiesคือต่อระดับlegendแปลงดัชนีเป็นป้ายชื่อnoul:noulคือ P(ใช่)- ส่งคำตอบที่
confidenceต่ำไปโมเดลใหญ่หรือคน โมเดลตอบได้เฉพาะตัวเลือกที่ให้ แต่ยังผิดได้
กรณีใช้งาน
จัดเส้นทาง ticket คัดกรองคอมเมนต์ ตรวจว่าคำตอบของ LLM อ้างอิงข้อมูลจริงหรือไม่ เลือกองค์ประกอบหน้าจอที่ agent ควรกด จัดหมวดเอกสารและฟิลด์ ให้คะแนนรีวิว ทั้งหมดคือหนึ่งคำขอที่ตอบทุกคำถามพร้อมกันในหลักสิบมิลลิวินาทีบน GPU เซิร์ฟเวอร์
ประสิทธิภาพ
| การตั้งค่า | ค่าที่วัดได้ |
|---|---|
| ไป-กลับผ่านเกตเวย์ ticket ภาษาไทย 3 คำถาม (ตัวอย่างในหน้านี้ 20 ก.ย. 2569) | 0.23 วินาที |
| GPU เซิร์ฟเวอร์ (H100) batch 1, 3 คำถาม | 40 ถึง 70 มิลลิวินาท ี |
| GPU โน้ตบุ๊ก (MacBook M3 Max, MPS) | 154 มิลลิวินาที |
| โทเคนขาออก | 0 ทุกคำขอ |
ผลการวัด
วัดแบบ zero-shot บน public benchmark 13 ชุดของ Bespoke Labs สำหรับโมเดล System One ใช้ชุดข้อมูล การแบ่ง คำสั่ง และตัวสุ่มเดียวกัน ตัวเลขของ Nimble-9B และ Jev เป็นตัวเลขที่ Bespoke Labs เผยแพร่เมื่อ 18 ก.ย. 2569 ส่วนของเราวัดด้วยสคริปต์ประเมินผลที่เปิดเผยพร้อมโมเดล choice และ noul รายงานความแม่นยำ score รายงานการตรงระดับพอดี ตัวหนาคือชุดที่โมเดล 0.8B นำโมเดล 9B
| Subset | Type | n | OpenThai-SystemOne 0.8B | Nimble-9B | Jev 1.13.0 |
|---|---|---|---|---|---|
| aegis2 | noul | 250 | 58.0 | 81.2 | 80.4 |
| boolq | noul | 300 | 63.7 | 86.0 | 89.7 |
| civil_comments | noul | 300 | 78.0 | 70.3 | 81.0 |
| helpsteer2 | score | 250 | 42.8 | 39.0 | 34.1 |
| massive-de-DE | choice | 350 | 64.6 | 83.4 | 86.9 |
| massive-en-US | choice | 350 | 75.7 | 86.9 | 87.4 |
| multinli | choice | 299 | 85.6 | 85.3 | 82.9 |
| paws | noul | 250 | 67.2 | 82.8 | 89.2 |
| pubmedqa | choice | 250 | 53.6 | 75.6 | 77.2 |
| squad2 | noul | 299 | 50.2 | 80.6 | 82.9 |
| summeval-consistency | score | 144 | 84.0 | 75.7 | 81.2 |
| summeval-relevance | score | 240 | 13.8 | 49.2 | 35.0 |
| vitaminc-dev | choice | 599 | 67.1 | 76.6 | 80.1 |
| Macro average | 61.9 | 74.8 | 76.0 |
Qwen3.5-0.8B ดิบที่ prompt ด้วย letter log-probs ได้ 45.4 บนชุดเดียวกัน อ่านตามจริง: โมเดล 0.8B นำโมเดล 9B ใน 4 จาก 13 ชุด (NLI, ความสอดคล้องของบทสรุป, การให้คะแนนความช่วยเหลือ, ข้อความเป็นพิษ) และตามหลังชัดเจนในงานใช่/ไม่ใช่แบบอ่านจับใจความ (squad2 เท่าการสุ่ม, boolq, pubmedqa) และการให้คะแนนความเกี่ยวข้องของบทสรุป ซึ่งหัวคะแนนของโมเดลยังปรับเทียบไม่ดี (ECE 0.79)
ชุดทดสอบภาษาไทยที่กันไว้ ไม่เคยใช้เทรน ECE คือค่าความคลาดเคลื่อนของการปรับเทียบ ยิ่งต่ำยิ่งดี:
| Set | Type | n | Accuracy | ECE |
|---|---|---|---|---|
| MASSIVE-th intent (60-way) | choice | 5,007 | 86.4 | 0.048 |
| Prachathai67k topics | choice | 3,501 | 97.7 | 0.005 |
| XNLI-th | choice | 2,490 | 76.5 | 0.028 |
| SIB-200 Thai topic (7-way), whole dataset held out | choice | 204 | 77.5 | 0.074 |
| Wongnai review stars (1 to 5) | score | 6,203 | 63.3 | 0.010 |
| xLAM tool selection (English) | choice | 884 | 99.4 | 0.007 |
| Wisesight sentiment (4-class), whole dataset held out | choice | 2,671 | 38.7 | 0.341 |
| banking77 intent (77-way, English), whole dataset held out | choice | 3,076 | 32.7 | 0.165 |
ค่า confidence เชื่อถือได้บนชุดภาษาไทยและงาน NLI/หัวข้อ (ECE ไม่เกิน 0.05 หลังปรับเทียบ) บน public benchmark ภาษาอังกฤษ ECE มัธยฐานอยู่ที่ 0.15 จึงควรส่งการตัดสินใจใช่/ไม่ใช่ภาษาอังกฤษที่ความมั่นใจต่ำไปโมเดลใหญ่ ตารางเต็ม Brier score และการเปรียบเทียบก่อน/หลังปรับเทียบอยู่ในmodel card
ข้อจำกัด
- เวอร์ชัน 0.1 โมเดลขนาด 0.8B ไม่ใช่โมเดลคิดวิเคราะห์
- ตอบได้เฉพาะตัวเลือกที่ให้ และยังผิดได้ ใช้ค่า
confidenceส่งเคสที่ไม่มั่นใจต่อ - จุดอ่อนที่รู้แล้วใน v0.1 (ตัวเลขด้านบน): ความรู้สึกในโซเชียลไทย (Wisesight 38.7), เจตนาภาษาอังกฤษละเอียด 77 หมวด (banking77 32.7), ใช่/ไม่ใช่แบบถาม-ตอบจากข้อความ (squad2 เท่าการสุ่ม) และการให้คะแนนความเกี่ยวข้องของบทสรุป v0.2 มุ่งแก้ข้อแรก
- รับข้อความอย่างเดียว ไม่รับรูป
- สูงสุด 255 ตัวเลือกต่อ
choice, 2 ถึง 10 ระดับต่อscore, 64K โทเคนต่อคำขอ
รันบนเครื่องของคุณ
น้ำหนักโมเดลเปิด สามบรรทัดได้คำตอบเดียวกันบนเครื่องของคุณเอง:
pip install "git+https://github.com/iapp-technology/openthai-systemone"
OPENTHAI_SYSTEMONE_MODEL=iapp/OpenThai-SystemOne uvicorn openthai_systemone.server:app --port 8000
curl -s http://localhost:8000/v1/systemone -H "Content-Type: application/json" -d '{"state": "...", "questions": {...}}'
ข้อมูลอ้างอิงทางเทคนิค
คำขอ
POST https://api.iapp.co.th/v3/store/openthai/systemone, header apikey, body application/json:
| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
state | string หรือ JSON | สิ่งที่ต้องตัดสินใจ รับ JSON ใดก็ได้และแปลงเป็นข้อความให้โมเดล |
questions | object | แผนที่ของชื่อคำถามไปยังคำถาม ทุกคำถามถูกตอบในการคำนวณรอบเดียวกัน |
questions.<name>.type | choice, score หรือ noul | ประเภทคำถาม |
questions.<name>.instructions | string | สิ่งที่ต้องตัดสินใจ ภาษาไทยหรืออังกฤษ |
questions.<name>.criteria | object หรือ array | choice: object ของชื่อตัวเลือกไปยังคำอธิบาย (null ถ้าไม่มี) สูงสุด 255. score: array ของป้ายชื่อระดับ 2 ถึง 10 ระดับตามลำดับ. noul ไม่ใช้ |
ผลลัพธ์
| ฟิลด์ | คำอธิบาย |
|---|---|
model | ตัวระบุโมเดล |
answers.<name> | หนึ่ง object ต่อคำถาม type ตรงกับคำขอ ดูการอ่านคำตอบ |
usage.input_tokens | โทเคนขาเข้าที่ใช้ |
usage.output_tokens | 0 เสมอ |