Jev State เปลี่ยนบทสนทนาที่แชทบอท AI พาไปผิดทางให้เป็นเทสต์ที่รันซ้ำได้ แล้วส่งออกเป็นโค้ด TypeScript
Jev State ช่วยวาดบทสนทนาแชทบอท AI เป็น state กับลูกศร และดูได้ทุกเทิร์นว่า AI เลือกทางไหน เซฟเคสที่พลาดเป็นเทสต์ได้ แก้รอบหน้าจึงรู้ทันทีว่าเคสไหนพัง

Jev State เป็นเครื่องมือโอเพนซอร์สที่ออกแบบมาเพื่อแก้ปัญหาของแชทบอท AI นั่นคือพอแก้ prompt ให้เคสหนึ่งตอบถูก อีกเคสที่เคยทำงานได้ดีกลับพังแทน
ลองนึกภาพแชทบอทที่คอยตอบลูกค้าของร้านค้า ลูกค้าพิมพ์มาว่าโดนตัดเงินซ้ำสองครั้ง แต่บอทกลับพาไปคุยเรื่องแก้ปัญหาเทคนิคแทนเรื่องการเงิน พอเราไปแก้ prompt จนเคสนี้ตอบถูก วันต่อมามีลูกค้าอีกคนแจ้งว่าระบบใช้งานไม่ได้ บอทกลับพาเขาไปคุยเรื่องการเงินแทน
ต้นเหตุของปัญหานี้คือทุกอย่างถูกยัดรวมไว้ใน prompt ก้อนเดียว ทำให้ไม่มีใครบอกได้เลยว่าแก้บรรทัดไหนแล้วจะกระทบอะไรบ้าง แถมเรายังไม่มีทางรู้เลยว่าทำไมบอทถึงเลือกพาผู้ใช้ไปทางนั้น
ใน README ของ Jev State ตั้งคำถามสำคัญไว้สองข้อ: บอทเปลี่ยนขั้นตอนของบทสนทนาได้ถูกจังหวะจริงไหม? และการปรับแก้ครั้งล่าสุดทำให้บทสนทนาเคสอื่นพังไปด้วยหรือเปล่า?
แนวทางแก้ปัญหาของ Jev State คือการเลิกยัดทุกอย่างไว้ใน prompt แล้วเปลี่ยนมาออกแบบบทสนทนาเป็นกล่องและลูกศรแทน โดยกล่องแต่ละใบคือ state หรือขั้นตอนของบทสนทนา ส่วนลูกศรคือเส้นทางที่ระบบอนุญาตให้ไปต่อได้ ในแต่ละเทิร์น เราสามารถเปิดดูได้ว่า AI เลือกเส้นทางไหน และมีค่าความมั่นใจเท่าไร หากเคสไหนบอทตอบพลาด เราก็กดบันทึกบทสนทนานั้นเป็น regression test ชุดทดสอบกันระบบพัง เพื่อนำมารันซ้ำได้ทุกครั้งที่มีการแก้ไข และเมื่อปรับจูนจนพอใจแล้ว ก็สามารถดาวน์โหลดทั้งหมดออกมาเป็นโค้ด TypeScript เพื่อนำไปรันบนเซิร์ฟเวอร์ของแอปเราเองได้ทันที
โปรเจกต์นี้เปิดเป็นโอเพนซอร์สบน GitHub โดยนักพัฒนาชื่อ priyankark ภายใต้สัญญาอนุญาต MIT ซึ่งเปิดให้ทุกคนนำไปใช้งาน แก้ไขโค้ด หรือโฮสต์ใช้งานเองได้
AI เสนอทาง โค้ดเป็นคนอนุญาต

ใน README สรุปวิธีคิดของ Jev State เอาไว้ว่า นอกจาก prompt แล้ว ระบบบทสนทนาของ AI ยังจำเป็นต้องมีองค์ประกอบสำคัญอีก 4 อย่าง ได้แก่:
- State ที่ชัดเจน: ระบุได้แน่นอนว่าตอนนี้บทสนทนาอยู่ในขั้นตอนไหน
- เส้นทางที่อนุญาต: กำหนดชัดเจนว่าจากขั้นตอนนี้ สามารถไปต่อที่ขั้นตอนไหนได้บ้าง
- กฎเมื่อไม่แน่ใจ: มีแนวทางชัดเจนว่าถ้า AI ลังเลหรือไม่มั่นใจ ต้องทำอย่างไร
- หลักฐานยืนยัน: มีชุดทดสอบที่พิสูจน์ได้ว่า บทสนทนายังคงทำงานถูกต้องตามที่ตั้งใจไว้จริง
ถ้าเรานำเคสตัดเงินซ้ำที่บอทตอบผิดมาวาดเป็นผัง workflow จะได้โครงสร้างที่คล้ายกับตัวอย่าง Support ในคู่มือของ Jev State
ผังตัวอย่างนี้จะเริ่มต้นที่ state ชื่อ Welcome ซึ่งแยกเส้นทางออกไปได้ 3 ทาง คือ Billing help, Technical help และ Human review จากนั้นทั้ง Billing help และ Technical help จะเชื่อมต่อไปยัง Resolved เป็น state สุดท้ายสำหรับปิดบทสนทนา
ส่วนประกอบที่ทำหน้าที่เลือกเส้นทางในแต่ละเทิร์นคือโมเดล Jev ของ TypeSafe โดยโมเดลนี้จะเลือกคำตอบจากชุดตัวเลือกที่เรากำหนดไว้ พร้อมทั้งระบุว่าค่าน้ำหนักความน่าจะเป็นกระจายไปยังตัวเลือกใดเท่าไรบ้าง (ถ้าสนใจการนำ Jev ไปประยุกต์ใช้ในรูปแบบอื่น สามารถอ่านต่อได้ในบทความ Abide)
สำหรับการเปลี่ยน state จริงในฝั่งโค้ด จะมี XState เครื่องมือจัดการสถานะจากทีม Stately เข้ามาเป็นตัวควบคุม แม้ว่า Jev State จะพัฒนาขึ้นบนเทคโนโลยีทั้งสองตัวนี้ แต่ใน README ก็ระบุไว้อย่างชัดเจนว่า นี่เป็นโปรเจกต์อิสระจากชุมชนนักพัฒนา ไม่ใช่ผลิตภัณฑ์ทางการของ TypeSafe หรือ Stately
ในแต่ละเทิร์น เมื่อผู้ใช้ส่งข้อความเข้ามา การทำงานจะแบ่งออกเป็น 5 ขั้นตอนดังนี้:
- Jev จะอ่านประวัติบทสนทนาทั้งหมดตั้งแต่เริ่มต้น ควบคู่ไปกับคำสั่งของ workflow ที่เรากำหนดไว้
- Jev จะมีสิทธิ์เลือกเฉพาะปลายทางที่มีลูกศรลากออกจาก state ปัจจุบันเท่านั้น รวมถึงตัวเลือก stay ที่ให้อยู่ที่เดิม ไว้ใช้เมื่อข้อความกำกวมหรือข้อมูลยังไม่พอ โดยแต่ละปลายทางจะมีชื่อและคำอธิบายเป็นเกณฑ์ให้ Jev นำไปใช้เปรียบเทียบ
- ก่อนเปลี่ยน state ระบบจะตรวจเสมอว่าคำตอบที่โมเดลส่งกลับมามีโครงสร้างตรงตามรูปแบบที่กำหนดหรือไม่ ถ้าไม่ตรง เทิร์นนั้นจะหยุดทันทีและไม่เปลี่ยน state
- ถ้าค่าความมั่นใจถึง threshold ที่เราตั้งไว้ บทสนทนาจะย้ายไปยัง state ถัดไปตามลูกศร แต่ถ้าไม่ถึง ระบบจะอยู่ที่ state เดิม แล้วตอบกลับจาก state ปัจจุบัน
- ระบบจะบันทึกรายละเอียดของเทิร์นนั้นไว้ทั้งหมด เพื่อให้เราสามารถเปิดตรวจสอบย้อนหลังได้
หลักจำง่ายๆ คือ "AI เป็นคนเสนอ แต่โค้ดเป็นคนอนุญาต" โดย Jev จะมีสิทธิ์เสนอทางเลือกได้เฉพาะในกรอบที่เราวาดไว้เท่านั้น ส่วนโค้ดจะตัดสินขั้นสุดท้ายจาก 3 เงื่อนไข คือโครงสร้างคำตอบถูกต้องไหม ค่าความมั่นใจผ่าน threshold หรือไม่ และมีเส้นทางไปยัง state นั้นจริงหรือเปล่า
ถ้าดูจาก workflow ตัวอย่าง เมื่อมีข้อความแรกส่งเข้ามาที่ Welcome ตัวเลือกที่ Jev เลือกได้จะมีเพียง Billing help, Technical help, Human review และ stay เท่านั้น โดยไม่มี Resolved อยู่ในตัวเลือกเลย เพราะเราไม่ได้ลากลูกศรจาก Welcome ไปยัง Resolved บอทจึงไม่มีทางพาผู้ใช้กระโดดข้ามขั้นไปปิดเรื่องตั้งแต่ข้อความแรกได้อย่างแน่นอน
ค่าความมั่นใจบอกเพียงว่าน้ำหนักความน่าจะเป็นเทไปที่ตัวเลือกใดมากน้อยแค่ไหน แต่ไม่ได้ยืนยันว่าสิ่งที่ Jev เลือกนั้นถูกต้องจริง เพราะถ้าโมเดลเทน้ำหนักไปที่ตัวเลือกที่ผิด ค่าความมั่นใจก็ยังคงสูงได้เช่นกัน เอกสาร README จึงแนะนำให้เราปรับจูนค่า threshold โดยทดลองกับเคสบทสนทนาจริงของตัวเอง และถ้าต้องการศึกษาเบื้องหลังการคำนวณค่านี้เพิ่มเติม สามารถอ่านได้จากเอกสาร confidence ของ TypeSafe
Define กับ Try: วาดผังแล้วลองคุยจริง
ขั้นตอนการทำงานทั้งหมดบน studio เว็บแอปของ Jev State แบ่งออกเป็น 4 ขั้นตอน ได้แก่ ขั้นวาดผัง Define, ขั้นทดลองคุย Try, ขั้นบันทึกชุดทดสอบ Test และขั้นดาวน์โหลดโค้ด Get code
ในหน้าแรกของ studio มีแม่แบบตัวอย่างให้เลือกนำไปปรับใช้ 3 แบบ ได้แก่ Support conversation สำหรับงานบริการลูกค้า, Product onboarding สำหรับแนะนำขั้นตอนการตั้งค่าให้ผู้ใช้ใหม่ และ Lead qualification สำหรับคัดกรองลูกค้ากลุ่มเป้าหมาย ทั้งสามชุดนี้เป็นเพียงแม่แบบตั้งต้น เมื่อเรากดใช้งาน ระบบจะสร้างสำเนาโปรเจกต์ใหม่ให้เราแก้ไขได้อิสระ โดยไม่กระทบกับตัวแม่แบบเดิม
ถ้าเราเลือก Support conversation ตั้งชื่อโปรเจกต์ แล้วกดสร้าง ระบบจะสร้างผังงานบริการลูกค้าตั้งแต่ state Welcome ไปจนถึง Resolved มาให้เราใช้งานต่อ ในขั้นตอน Define เราสามารถคลิกแต่ละ state เพื่อเข้าไปแก้ไขเกณฑ์การประเมิน ข้อความตอบกลับ และเส้นทางเชื่อมต่อไปยัง state อื่นๆ ได้ทันที
คำอธิบายของแต่ละ state มีหน้าที่ตอบคำถามสำคัญเพียงข้อเดียวคือ "เมื่อไหร่ที่ Jev ควรพาบทสนทนาเข้ามาที่ state นี้" เช่น ใน state Billing help อาจเขียนกำกับไว้ว่า "ผู้ใช้กำลังถามเรื่องการเรียกเก็บเงิน ใบแจ้งหนี้ การชำระเงิน หรือการคืนเงิน"
จุดที่พลาดง่ายคือ การเขียนคำอธิบายกว้างเกินไปจนเนื้อหาทับซ้อนกันหลายปลายทาง โดยไม่ได้ระบุจุดต่างให้ชัดเจน ซึ่งคู่มือเตือนเรื่องนี้ไว้ตรงๆ เพราะคำอธิบายเหล่านี้คือเกณฑ์ที่ Jev ใช้ตัดสินใจเลือก ถ้าคำอธิบายของ Billing help กับ Technical help คลุมเครือจนซ้อนทับกัน Jev ก็จะไม่มีเกณฑ์ที่ชัดเจนพอสำหรับแยกทั้งสองเส้นทางนี้ออกจากกัน
การเชื่อมเส้นทางทำได้โดยตรงบนหน้าผัง เพียงลากจุดเชื่อมต่อจากด้านขวาของ state หนึ่ง ไปวางที่จุดเชื่อมต่อด้านซ้ายของอีก state หนึ่ง ก็จะได้เส้นทางใหม่ทันที และไม่จำเป็นต้องลากเส้นวนกลับมาที่ตัวเอง เพราะระบบมีตัวเลือก stay ให้อยู่ที่เดิมเสมอ

เมื่อเข้าสู่ขั้นตอน Try เราจะได้ทดลองสนทนาจริงกับผังที่เพิ่งวาดเสร็จ
ในขั้นตอนนี้ studio จะตั้งค่าเริ่มต้นเป็นโหมด Live Jev ให้อัตโนมัติ ซึ่งโหมดนี้จะให้โมเดล Jev เป็นผู้ตัดสินใจจริงๆ จึงจำเป็นต้องใส่ API key ของ TypeSafe ก่อน แต่ถ้าใครยังไม่มี key ก็สามารถสลับไปใช้โหมด Simulation แทนได้ โดยโหมดนี้จะใช้เพียงคีย์เวิร์ดจับคู่เส้นทาง และไม่เรียกไปยังโมเดลจริง
เมื่อพร้อมแล้ว ลองส่งข้อความ 2 ประโยคนี้ต่อกันตามคู่มือ:
I was charged twice(โดนตัดเงินซ้ำสองครั้ง)It is fixed now(ตอนนี้เรียบร้อยแล้ว)
เส้นทางที่คาดไว้คือ Welcome → Billing help → Resolved
ในแต่ละเทิร์น เราสามารถคลิกดูรายละเอียดได้ว่า:
- Jev ได้รับข้อมูลอะไรไปบ้าง
- ใช้เกณฑ์ของ state ปลายทางไหนมาเปรียบเทียบบ้าง
- ค่าน้ำหนักความน่าจะเป็นกระจายไปที่แต่ละตัวเลือกอย่างไร
- ใช้เวลาประมวลผลและจำนวน token ไปเท่าไร
- ทำไมค่า threshold ถึงอนุญาตหรือไม่อนุญาตให้ย้าย state
ในการทดสอบด้วยโหมด Live เส้นทางที่ AI เลือกจริงอาจไม่ตรงกับที่เราคาดหวังไว้เสมอไป คู่มือจึงแนะนำให้เปิดดูผลลัพธ์จริงแทนการคาดเดาไปเอง ซึ่งรายละเอียดในแต่ละเทิร์นจะช่วยให้เราไล่ตรวจเช็กสาเหตุได้จาก 4 ประเด็นนี้:
- ลากเส้นลูกศรเชื่อมต่อไปยังปลายทางที่ควรไปแล้วหรือยัง
- คำอธิบายหรือเกณฑ์ของปลายทางนั้นเขียนไว้ชัดเจนพอหรือไม่
- ข้อมูลที่จำเป็นต่อการตัดสินใจมีอยู่ในบริบทของบทสนทนาแล้วหรือยัง
- ค่าความมั่นใจของตัวเลือกที่ได้ไม่ผ่าน threshold ที่ตั้งไว้หรือเปล่า
เปลี่ยนบทสนทนาที่ตอบพลาด ให้กลายเป็นเทสต์ที่รันซ้ำได้

ขั้นตอน Test คือส่วนที่แก้ปัญหา "แก้จุดนี้หาย แต่อีกจุดกลับพัง" ได้ตรงจุดที่สุด
ที่ด้านล่างของบทสนทนาที่เราเพิ่งทดสอบคุยเสร็จ จะมีปุ่ม Save as regression test เมื่อกดแล้ว ระบบจะแปลงบทสนทนานั้นเป็นชุดทดสอบ เพื่อนำมารันซ้ำทุกครั้งหลังจากแก้ไข workflow เพื่อเช็กว่าเคสที่บันทึกไว้ยังผ่านอยู่
ปุ่มนี้ใช้บันทึกได้ทั้งบทสนทนาที่ตอบถูกและบทสนทนาที่ตอบผิด โดยระบบจะดึงข้อความทั้งหมดของผู้ใช้มาใส่ไว้ให้เรียบร้อยแล้ว เรามีหน้าที่เพียงระบุว่า state ปลายทางที่ถูกต้องควรเป็นอะไร แม้ตอนคุยจริงบอทจะตอบผิดจนหลุดไปจบที่ state อื่นก็ตาม
ในแต่ละเคสสามารถใส่ข้อความของผู้ใช้ได้ตั้งแต่ 1 ถึง 5 ข้อความ ควบคู่ไปกับ state สุดท้ายที่คาดหวัง และถ้าต้องการความรัดกุมมากขึ้น เรายังสามารถกำหนดเงื่อนไขเพิ่มได้อีก 2 อย่าง คือ state ที่คาดหวังในแต่ละเทิร์นระหว่างทาง และคีย์เวิร์ดสำคัญที่จำเป็นต้องมีอยู่ในคำตอบสุดท้าย
ตัวเลือกสำคัญที่ไม่ควรมองข้ามคือ Check intermediate states ซึ่งจะช่วยตรวจสอบ state ระหว่างทางในแต่ละขั้นตอนด้วย ลองนึกถึงเคสที่ลูกค้าแจ้งว่าโดนตัดเงินซ้ำ แต่บอทดันพาแวะไปที่ Technical help ก่อน แล้วค่อยวกกลับมาจบที่ Resolved ถ้าเราไม่ได้เปิดตัวเลือกนี้ เคสนี้จะผ่านฉลุยเหมือนไม่มีอะไรผิดพลาดเพราะดูแค่ปลายทาง ทั้งที่จริงแล้ว บอทได้พาลูกค้าออกนอกเรื่องไปแล้วหนึ่งเทิร์น
พอแก้ workflow แล้วรันชุดทดสอบเดิมอีกรอบ รายงานจะเทียบผลกับรอบก่อนหน้าในโหมดเดียวกันให้ทันที และบอกชัดว่าเคสไหนเคยผ่านแต่กลับมาพัง เคสไหนแก้จนผ่านแล้วบ้าง นี่คือสิ่งที่ prompt ก้อนเดียวทำไม่ได้
ถ้าเราเข้าไปแก้ไข state ที่คาดหวังของเคสใด ระบบจะติดแท็กเคสนั้นว่า Test changed และไม่นับว่าเคสนั้นแก้ผ่านแล้ว เพราะการเปลี่ยนเฉลยให้ตรงกับคำตอบที่บอทตอบผิด ไม่ได้แปลว่าบอททำงานฉลาดขึ้นจริง ส่วนค่า path coverage จะแสดงให้เห็นว่า มีเส้นทางไหนในผังที่ยังไม่เคยมีชุดทดสอบวิ่งผ่าน เส้นทางที่ยังว่างอยู่นั้นจึงเป็นจุดที่เราควรเพิ่มเคสทดสอบเข้าไปเสริม

นอกจากนี้ ชุดทดสอบทั้งหมดยังสามารถนำไปรันผ่าน CLI ได้ด้วย โดยใช้ไฟล์โปรเจกต์ที่ดาวน์โหลดมาจากปุ่ม Export project:
npm run evaluate -- --project my-project.json --out report.jsonคำสั่งนี้จะทำงานในโหมด Simulation จึงไม่มีการเรียกไปยังโมเดลจริง แต่ถ้าต้องการให้โมเดล Jev เป็นผู้ตัดสินใจจริง ให้ระบุพารามิเตอร์ --mode live เพิ่มเติม ซึ่งจะเริ่มมีค่าใช้จ่ายกับบัญชีผู้ให้บริการโมเดลของคุณ เมื่อรันเสร็จสิ้น คำสั่งจะส่ง exit code กลับมาเพื่อบอกผลลัพธ์:
0ทุกเคสผ่าน1มีบางเคสที่ผลลัพธ์ไม่ตรงตามที่คาดหวัง2input ไม่ถูกต้อง ชุดทดสอบว่างเปล่า หรือรันคำสั่งไม่ได้
รหัสสถานะเหล่านี้ช่วยให้เรานำชุดทดสอบไปผูกกับ CI/CD เพื่อรันตรวจสอบทุกครั้งที่อัปเดตโค้ดได้ทันที ถ้าการแก้ workflow ทำให้เคสเดิมพัง เราก็จะเห็นได้ทันทีก่อนนำโค้ดขึ้นระบบจริง
อีกเรื่องที่ต้องระวังคือ ในไฟล์รายงานจะบันทึกข้อความบทสนทนาจริงเอาไว้ด้วย ดังนั้นถ้ามีข้อมูลส่วนบุคคลหรือข้อมูลสำคัญ จึงไม่ควรนำไฟล์รายงานขึ้นไปเก็บบน repository สาธารณะ
Get code: ดาวน์โหลดไฟล์ ZIP ที่รันได้ทันที
ขั้นตอนสุดท้ายคือ Get code ซึ่งให้ดาวน์โหลดโปรเจกต์ทั้งหมดเป็นไฟล์ ZIP ที่รันได้จริง ข้างในมีไฟล์สำคัญดังนี้:
| ไฟล์ | หน้าที่การทำงาน |
|---|---|
workflow.json | บันทึกข้อมูล state, เส้นทางเชื่อมต่อ, ค่า threshold และชุดเคสทดสอบทั้งหมด |
workflow.ts | รวมฟังก์ชัน startConversation และ sendMessage สำหรับนำไปเชื่อมต่อเข้ากับแอปพลิเคชัน |
lib/ | เอนจินหลักตัวเดียวกับที่ studio ใช้งานจริง |
example.ts | ตัวอย่างโค้ดเรียกใช้งานฝั่งเซิร์ฟเวอร์ที่พร้อมคัดลอกไปปรับใช้ต่อ |
evaluate.ts | สคริปต์สำหรับสั่งรันชุดทดสอบ ทั้งบนเครื่องตนเองและบนระบบ CI |
.github/workflows/check.yml | เวิร์กโฟลว์ของ GitHub Actions สำหรับรัน typecheck และรันเทสต์ในโหมด Simulation อัตโนมัติทุกครั้งที่มีการ push หรือสร้าง pull request โดยไม่ต้องใช้ API key |
validation.json | บันทึกสถานะผลการทดสอบล่าสุด โดยแยกชัดเจนระหว่างโหมด Simulation และ Live |
เมื่อแตกไฟล์ ZIP ออกมาแล้ว ให้เปิดโฟลเดอร์นั้นขึ้นมา โดยเครื่องต้องติดตั้ง Node.js เวอร์ชัน 22 ขึ้นไป แล้วรัน 4 คำสั่งนี้ตามลำดับ:
npm install
npm run typecheck
npm test
npm startทั้ง 4 คำสั่งนี้ทำงานในโหมด Simulation จึงไม่ต้องใส่ API key และไม่เรียกไปยังผู้ให้บริการโมเดลใดๆ เลย โค้ดชุดนี้ยังทำงานได้ด้วยตัวเองทั้งหมดโดยไม่ต้องพึ่งเว็บ studio ส่วนตอนใช้งานจริง เซิร์ฟเวอร์ของแอปเราจะส่งคำขอไปยัง TypeSafe หรือ OpenAI โดยตรง
สำหรับใครที่ใช้ coding agent หรือ AI ช่วยเขียนโค้ดอยู่แล้ว ให้สังเกตไฟล์ .agents/skills/integrate-jev-workflow/SKILL.md ที่แนบมากับทุกไฟล์ ZIP
ไฟล์นี้คือ skill สำหรับให้ AI agent อ่านและปฏิบัติตาม โดยคำสั่งจะบอกให้ agent เข้าไปศึกษาโครงสร้าง workflow และผลการทดสอบ จากนั้นจึงนำไปผสานเข้ากับระบบเซิร์ฟเวอร์และการจัดการ session ในรูปแบบที่แอปของคุณใช้อยู่เดิม พร้อมทั้งรักษาการตัดสินใจเปลี่ยน state ให้ทำงานถูกต้องเหมือนเดิม และตรวจสอบความเรียบร้อยผ่านโหมด Simulation
วิธีใช้งานก็สะดวกมาก เพียงเปิดโฟลเดอร์โปรเจกต์ที่แตกไฟล์ ZIP ไว้คู่กับโปรเจกต์แอปของคุณ จากนั้นกดปุ่ม Copy agent prompt ในหน้า Get code แล้วนำข้อความไปสั่ง agent หรือจะบอกให้ agent เปิดอ่านไฟล์ skill นี้โดยตรงก็ได้ ไม่จำเป็นต้องติดตั้ง skill แบบ global แค่เก็บไฟล์ไว้คู่กับโฟลเดอร์ที่ส่งออกโค้ดมา เพื่อให้ลิงก์อ้างอิงภายในเอกสารทำงานได้ครบถ้วน
ส่วนใครที่ต้องการเขียนโค้ดเชื่อมต่อเอง ตัวอย่างการเรียกใช้งานฝั่งเซิร์ฟเวอร์จะมีหน้าตาดังนี้:
import { startConversation, sendMessage } from "./workflow.js";
let session = startConversation({ mode: "live" }); // uses your server's keys
const result = await sendMessage(session, "I was charged twice");
session = result.session;
// result.decision.to / reply / confidence / probabilities
// Persist session per user and pass it to the next sendMessage call.startConversation ใช้สำหรับเริ่มบทสนทนาใหม่ในโหมด live ซึ่งจะดึง API key จากเซิร์ฟเวอร์ของคุณไปใช้งาน
sendMessage ทำหน้าที่รับข้อความของผู้ใช้ในแต่ละเทิร์น แล้วส่งอ็อบเจกต์ session ใหม่กลับมา พร้อมรายละเอียดการตัดสินใจ เช่น เปลี่ยนไปที่ state ใด, ข้อความตอบกลับคืออะไร, ค่าความมั่นใจเท่าไร และค่าน้ำหนักความน่าจะเป็น โดยฟังก์ชันนี้จะไม่แก้ไข session เดิมโดยตรง หน้าที่บันทึก session ของผู้ใช้แต่ละคนเพื่อส่งต่อให้ sendMessage ในเทิร์นถัดไป จึงเป็นหน้าที่ของฝั่งเซิร์ฟเวอร์คุณเอง
ข้อสำคัญคือ ก่อนเริ่มใช้งานในโหมด live อย่าลืมคัดลอกไฟล์ .env.example ไปเป็น .env แล้วใส่ค่า TYPESAFE_API_KEY ของคุณให้เรียบร้อย
3 โหมดของ Jev State กับเรื่องค่าใช้จ่ายและ API Key
| โหมด | ใครเลือกทาง | ใครเขียนคำตอบ | Key ที่ต้องใช้ |
|---|---|---|---|
| Simulation | ใช้คีย์เวิร์ดแรกที่ตรง โดยไล่ตามลำดับเส้นทาง ถ้าไม่ตรงเลยจะอยู่ที่เดิม | ข้อความที่กำหนดไว้ในแต่ละ state | ไม่ต้องใช้ |
| Live Jev | โมเดล Jev เลือกจากเส้นทางที่อนุญาตหรือเลือก stay | ข้อความที่กำหนดไว้ในแต่ละ state | TypeSafe |
| Live Jev + generated replies | โมเดล Jev เลือกเส้นทางเช่นเดียวกัน | โมเดล OpenAI สร้างข้อความตอบกลับตามประวัติการคุยและ state ปัจจุบัน | TypeSafe และ OpenAI |
จุดหนึ่งที่อาจทำให้สับสนคือ โหมด Simulation ก็แสดงค่าความมั่นใจเช่นกัน แต่ตัวเลขนี้เป็นเพียงค่าคงที่ที่กำหนดไว้สำหรับทดสอบหน้าจอเท่านั้น ไม่ใช่ค่าที่โมเดลประเมินออกมาจริงๆ ตัวอย่างในคู่มือคือ เมื่อเราส่งคำว่า Hello ซึ่งไม่ตรงกับคีย์เวิร์ดใดเลย บอทจะยังคงอยู่ที่ Welcome พร้อมแสดงค่าความมั่นใจคงที่ 60% ซึ่งต่ำกว่า threshold 75% ที่ตั้งไว้ในตัวอย่าง โหมดนี้จึงมีไว้ตรวจว่าระบบเชื่อมต่อกันถูกต้องหรือไม่ ไม่ได้ใช้วัดความแม่นยำของ AI
ในทำนองเดียวกัน การแก้คีย์เวิร์ดในโหมด Simulation ก็ไม่ได้ฝึกหรือสอนโมเดลในโหมด Live แต่อย่างใด ถ้าต้องการเปลี่ยนการตัดสินใจของ AI จริงๆ ต้องไปแก้ที่คำอธิบายของแต่ละ state และคำสั่งของ workflow แทน
เรื่องค่าใช้จ่ายต้องแยกออกจากกันให้ชัดเจน: ตัวเว็บ studio และซอร์สโค้ดทั้งหมดใช้งานได้ฟรีภายใต้สัญญาอนุญาต MIT โดยไม่ต้องลงทะเบียนบัญชีและไม่มีค่าบริการรายเดือน แต่สำหรับโหมด Live จะมีค่าใช้จ่ายเกิดขึ้นกับบัญชีของผู้ให้บริการโมเดลอย่าง TypeSafe หรือ OpenAI ตามปริมาณการใช้งานจริง ซึ่งการกรอก API key ทิ้งไว้เฉยๆ จะยังไม่เสียค่าใช้จ่าย จนกว่าจะส่งข้อความคุยจริงหรือสั่งรันชุดทดสอบ
ส่วนความปลอดภัยของ API key ที่กรอกลงใน studio บนหน้าเว็บ คีย์จะเก็บไว้เฉพาะในหน่วยความจำของแท็บเบราว์เซอร์นั้นๆ เท่านั้น เมื่อเราปิดแท็บ รีโหลดหน้าเว็บ หรือกดปุ่ม Disconnect and forget keys ข้อมูลคีย์จะถูกลบออกทันที โดยระบบไม่ได้บันทึกลงในหน่วยความจำเบราว์เซอร์อย่าง localStorage, คุกกี้ หรือฐานข้อมูลใดๆ แต่ในจังหวะที่มีการเรียกใช้งาน คีย์จะส่งผ่านเซิร์ฟเวอร์ของเว็บโฮสต์เพื่อต่อไปยังผู้ให้บริการโมเดล เอกสาร README จึงแนะนำให้ใช้งานผ่านโดเมนที่คุณไว้วางใจผู้ดูแล หรือเลือกติดตั้งและรัน studio ด้วยตัวเองในเครื่อง
คุณเลือกวิธีใช้งานได้ตามความเหมาะสม ใช้ studio บนเว็บจะสะดวกกว่า แต่คีย์ต้องส่งผ่านเซิร์ฟเวอร์ภายนอก ส่วนการรันเองในเครื่อง คีย์จะอยู่ในความดูแลของคุณเองอย่างปลอดภัย แลกกับการต้องคัดลอกโค้ดมารันเองด้วยชุดคำสั่งนี้:
git clone https://github.com/priyankark/jev-state.git
cd jev-state
npm ci
cp .env.example .env.local
npm run devจากนั้นเปิดเบราว์เซอร์เข้าไปที่ localhost:5173
ไม่ว่าจะเลือกใช้งานแบบไหน ทั้งข้อมูลโปรเจกต์ ประวัติการสนทนา และรายงานผลการทดสอบทั้งหมด จะบันทึกไว้ในเบราว์เซอร์ของเครื่องที่คุณใช้งานเท่านั้น โดยไม่มีระบบบัญชีผู้ใช้และไม่มีการซิงก์ข้อมูลข้ามเครื่อง
ข้อจำกัดที่ควรรู้ของ Jev State ในปัจจุบัน
ก่อนตัดสินใจนำ Jev State ไปใช้กับแชทบอทที่ให้บริการจริง มีข้อจำกัดสำคัญ 7 ข้อที่ควรรู้ไว้:
- รองรับเฉพาะผังแบบชั้นเดียว: ยังสร้าง state ซ้อนกันหลายระดับไม่ได้ ไม่มี parallel regions ที่ให้หลายสถานะทำงานพร้อมกัน และยังนำเข้าผังที่เขียนด้วย XState จากภายนอกไม่ได้
- ขนาดการทำงานยังจำกัด: หนึ่ง workflow มีได้ 2 ถึง 12 state บทสนทนายาวได้ไม่เกิน 20 เทิร์น แต่ละโปรเจกต์มีเคสทดสอบได้สูงสุด 30 เคส และแต่ละเคสมีข้อความได้ 1 ถึง 5 เทิร์น
- studio เก็บประวัติได้จำนวนจำกัด: ตัวเว็บแอปจะบันทึกประวัติการสนทนาไว้เพียง 60 รายการล่าสุด และเก็บรายงานผลการทดสอบได้ 40 รายการล่าสุดเท่านั้น ถ้าต้องการเก็บมากกว่านั้น ต้องส่งออกหรือสำรองข้อมูลออกมาเก็บเอง
- ยังไม่มีแพ็กเกจทางการบน npm: ทั้งแพ็กเกจ
@jev-state/coreและ@jev-state/typesafeยังไม่ได้เผยแพร่บนคลังแพ็กเกจส่วนกลางอย่าง npm registry ตอนนี้จึงนำโค้ดไปใช้ได้เพียงการดาวน์โหลดจาก Get code หรือคัดลอก repository ต้นฉบับมาใช้เท่านั้น - ไม่ได้สั่ง action จริง: studio จะไม่สั่งงานระบบภายนอกจริง เช่น ไม่ได้ทำเรื่องคืนเงินหรือส่งข้อความหาใคร ไม่ว่าบทสนทนาจะย้ายไปที่ state ใดก็ตาม ส่วนโค้ดที่ส่งออกไปก็ไม่มีระบบล็อกอิน ฐานข้อมูล หรือระบบจัดการ session แยกตามผู้ใช้มาให้ นักพัฒนาต้องสร้างส่วนนี้เองในฝั่งแอปพลิเคชัน
- ชุดทดสอบผ่าน ไม่ได้การันตีว่าจะถูกต้องเสมอไป: คำว่าผ่านหมายถึงผ่านเฉพาะชุดเคสทดสอบที่เราเขียนเตรียมไว้เท่านั้น เอกสาร README จึงแนะนำให้ออกแบบเคสทดสอบเพิ่มให้ครอบคลุม ทั้งข้อความที่กำกวม เคสที่ไม่ตรงกับทางเลือกใดเลย และบทสนทนาที่มีการโต้ตอบหลายเทิร์น
- ฟีเจอร์ในแผนพัฒนายังใช้ไม่ได้: ฟีเจอร์ขั้นสูงอย่าง state ซ้อนกันหลายระดับ หรือการปล่อยแพ็กเกจติดตั้งบน npm ยังเป็นเพียงแผนงาน และตอนนี้ยังใช้จริงไม่ได้
ลองสร้างเคสทดสอบที่ตั้งใจให้ล้มดูสักครั้ง
ถ้าอยากลองใช้งานจริงโดยไม่เสียค่าใช้จ่าย ทำตาม 5 ขั้นตอนนี้ได้ทันที:
- เปิดหน้าเว็บ studio ขึ้นมา แล้วคลิกปุ่ม Use this example ในกล่อง Support conversation
- เมื่อเข้าสู่หน้า Try ให้สลับโหมดการทำงานเป็น Simulation ด้วยตัวเอง เพราะระบบจะตั้งค่าเริ่มต้นเป็น Live Jev
- พิมพ์ข้อความ
I was charged twiceโดยคำว่า charged เป็นคีย์เวิร์ดที่พาบทสนทนาเข้าสู่ state Billing help - กดปุ่ม Save as regression test เพื่อบันทึกเป็นเคสทดสอบ
- ทำสำเนาเคสนั้น แล้วลองจงใจแก้ state ที่คาดหวังให้เป็น Technical help จากนั้นกดรัน เพื่อดูว่าเมื่อมีเคสทดสอบล้มเหลว ตัวรายงานจะแสดงผลและชี้จุดผิดพลาดอย่างไรบ้าง เมื่อทดลองเสร็จแล้วค่อยลบเคสที่ตั้งใจทำให้พังนี้ทิ้งไป
เมื่อไรที่คุณพร้อมและอยากเห็นการตัดสินใจของโมเดล Jev ในการทำงานจริง ค่อยนำ API key ของ TypeSafe มาเชื่อมต่อภายหลัง
สำหรับทีมที่มีแชทบอทเปิดให้บริการอยู่แล้ว ลองย้อนนึกถึง 3 ครั้งล่าสุดที่บอทพาผู้ใช้หลงประเด็นหรือไม่เข้าใจคำถาม บทสนทนาจริงทั้ง 3 เคสนั้น คือชุดทดสอบ 3 เคสแรกที่ดีที่สุดของคุณ โดยที่คุณแทบไม่ต้องคิดบทพูดขึ้นมาเองเลย เพราะผู้ใช้จริงเขียนเตรียมไว้ให้หมดแล้ว
ที่มา:
- บทความ priyankark/jev-state: Build and regression-test conversational state machines powered by Jev จาก priyankark
- บทความ jev-state/docs/TUTORIAL.md จาก priyankark
- บทความ jev-state/docs/GET_CODE.md จาก priyankark
- บทความ Jev State — Test decisions. Get code. จาก jev-state.vercel.app
ชอบเรื่องแนวนี้ มีอีบุ๊คฟรีให้อ่านต่อ
สร้าง Claude Skill แบบไม่ต้องรู้โค้ด คู่มือสร้าง Claude Skill ของคุณเองด้วยการคุยกับ Claude Code เป็นภาษาไทย
กดสมัครแล้วเราจะส่งเทคนิค AI และของแจกใหม่ๆ ให้ทางอีเมล เลิกรับได้ตลอด
สร้าง AI Automation Pipeline ทุกแบบ ด้วย Agents และ Skills

ปูจากพื้นฐาน prompt, context และ cost ไปจนปั้น Skill สั่ง Agent กับ Sub-agent แล้วต่อทุกอย่างเป็น pipeline อัตโนมัติที่ออกแบบเองได้ ดูฟรี 7 บทก่อนตัดสินใจ


