import spaces # ZeroGPU Spaces require at least one @spaces.GPU function @spaces.GPU def _zerogpu_startup_check(): # Free-tier Gradio Spaces run on ZeroGPU. This satisfies its startup check. # Real inference below runs on CPU and does not consume GPU quota. return 'ok' import os import numpy as np from openai import OpenAI from sentence_transformers import SentenceTransformer import gradio as gr client = OpenAI(api_key=os.environ['TYPHOON_API_KEY'], base_url='https://api.opentyphoon.ai/v1') MODEL = 'typhoon-v2.5-30b-a3b-instruct' SIAMTECH_DOCS = { '01_employee_handbook.md': '# คู่มือพนักงาน บริษัท สยามเทค เอไอ จำกัด (ฉบับย่อ)\n\n## เกี่ยวกับบริษัท\nบริษัท สยามเทค เอไอ จำกัด (SiamTech AI Co., Ltd.) ก่อตั้งเมื่อปี พ.ศ. 2565 สำนักงานใหญ่ตั้งอยู่ที่อาคารเกษตรอินโนเวชั่น ชั้น 8 ถนนพหลโยธิน กรุงเทพมหานคร บริษัทพัฒนาเทคโนโลยีปัญญาประดิษฐ์สำหรับอุตสาหกรรมอาหารและการเกษตร ผลิตภัณฑ์หลักคือแอปพลิเคชัน "อร่อยไหม" (AroiMai) ระบบรู้จำอาหารไทยอัตโนมัติจากภาพถ่าย ปัจจุบันบริษัทมีพนักงานทั้งหมด 46 คน แบ่งเป็นทีมวิศวกรรม 28 คน ทีมข้อมูลและโมเดล 10 คน และทีมธุรกิจ 8 คน\n\n## เวลาทำงาน\nเวลาทำงานปกติคือวันจันทร์ถึงวันศุกร์ เวลา 09:00–18:00 น. โดยมีช่วงเวลาหลัก (core hours) ที่ทุกคนต้องออนไลน์หรืออยู่ที่สำนักงานคือ 10:00–16:00 น. พนักงานสามารถทำงานจากที่บ้าน (Work from Home) ได้สัปดาห์ละไม่เกิน 2 วัน โดยต้องแจ้งหัวหน้าทีมล่วงหน้าอย่างน้อย 1 วันผ่านระบบ SiamHR\n\n## การแต่งกาย\nบริษัทใช้นโยบายแต่งกายแบบ smart casual ในวันที่มีการประชุมกับลูกค้าภายนอก ให้แต่งกายแบบ business casual ห้ามสวมรองเท้าแตะและกางเกงขาสั้นในสำนักงาน\n\n## ช่องทางติดต่อภายใน\n- ฝ่ายบุคคล (HR): hr@siamtech.example โทรภายใน 101\n- ฝ่ายไอที (IT Helpdesk): helpdesk@siamtech.example โทรภายใน 202\n- ฝ่ายความปลอดภัยข้อมูล: security@siamtech.example โทรภายใน 303\n- ระบบลาและสวัสดิการ: portal.siamtech.example (ระบบ SiamHR)\n\n## โครงสร้างการรายงาน\nพนักงานทุกคนมีหัวหน้าทีม (Team Lead) เป็นผู้ประเมินผลงานหลัก การประเมินผลจัดขึ้นปีละ 2 ครั้ง ในเดือนมิถุนายนและเดือนธันวาคม ผลการประเมินใช้ประกอบการพิจารณาโบนัสประจำปีซึ่งจ่ายในเดือนมกราคมของปีถัดไป\n', '02_leave_policy.md': '# นโยบายการลา บริษัท สยามเทค เอไอ จำกัด\n\n## วันลาพักร้อน (ลาพักผ่อนประจำปี)\nพนักงานประจำมีสิทธิ์ลาพักร้อนปีละ 14 วันทำการ โดยเริ่มใช้สิทธิ์ได้หลังผ่านช่วงทดลองงาน วันลาพักร้อนที่ใช้ไม่หมดในปีนั้น สามารถสะสมข้ามปีได้ไม่เกิน 7 วัน ส่วนที่เกินจะถูกตัดทิ้งในวันที่ 31 มีนาคมของปีถัดไป การลาพักร้อนต้องยื่นคำขอผ่านระบบ SiamHR ล่วงหน้าอย่างน้อย 3 วันทำการ และต้องได้รับอนุมัติจากหัวหน้าทีมก่อนจึงจะถือว่าลาสมบูรณ์\n\n## วันลาป่วย\nพนักงานลาป่วยได้ตามจริงไม่เกินปีละ 30 วันทำการโดยได้รับค่าจ้าง หากลาป่วยติดต่อกันตั้งแต่ 3 วันทำการขึ้นไป ต้องแนบใบรับรองแพทย์ในระบบ SiamHR การลาป่วยให้แจ้งหัวหน้าทีมโดยเร็วที่สุด ภายในเวลา 10:00 น. ของวันที่ลา\n\n## วันลากิจ\nพนักงานมีสิทธิ์ลากิจส่วนตัวปีละ 6 วันทำการโดยได้รับค่าจ้าง การลากิจต้องยื่นล่วงหน้าอย่างน้อย 1 วันทำการ ยกเว้นกรณีฉุกเฉินให้แจ้งทันทีที่ทำได้\n\n## วันลาอื่น ๆ\n- ลาคลอดบุตร: 98 วันตามกฎหมาย โดยบริษัทจ่ายค่าจ้างเต็มจำนวน 45 วันแรก\n- ลาเพื่อดูแลบุตรแรกเกิด (สำหรับคู่สมรส): 15 วันทำการ\n- ลาบวช: ไม่เกิน 15 วันทำการ (ครั้งเดียวตลอดอายุงาน ต้องมีอายุงานครบ 1 ปี)\n- ลาเพื่อรับราชการทหาร: ตามหมายเรียกของทางราชการ\n\n## ช่วงทดลองงาน\nพนักงานใหม่มีช่วงทดลองงาน 119 วัน ระหว่างทดลองงานสามารถลาป่วยได้ตามจริง แต่ยังไม่มีสิทธิ์ลาพักร้อนและลากิจ\n\n## วันหยุดประจำปี\nบริษัทประกาศวันหยุดตามประเพณีปีละ 16 วัน ประกาศล่วงหน้าภายในเดือนธันวาคมของทุกปี หากวันหยุดตรงกับวันเสาร์-อาทิตย์ จะชดเชยในวันทำการถัดไปตามประกาศของฝ่ายบุคคล\n', '03_expense_policy.md': '# ระเบียบการเบิกค่าใช้จ่าย บริษัท สยามเทค เอไอ จำกัด\n\n## หลักการทั่วไป\nการเบิกค่าใช้จ่ายทุกประเภทต้องมีใบเสร็จรับเงินหรือใบกำกับภาษีตัวจริงแนบในระบบ SiamHR และยื่นภายใน 30 วันนับจากวันที่เกิดค่าใช้จ่าย รายการที่ยื่นเกินกำหนดจะไม่ได้รับการอนุมัติ ยกเว้นได้รับอนุมัติพิเศษจากผู้อำนวยการฝ่าย\n\n## เบี้ยเลี้ยงเดินทางปฏิบัติงานนอกสถานที่\n- ปฏิบัติงานต่างจังหวัด (ค้างคืน): เบี้ยเลี้ยง 800 บาทต่อวัน\n- ปฏิบัติงานต่างจังหวัด (ไปเช้าเย็นกลับ): เบี้ยเลี้ยง 400 บาทต่อวัน\n- ปฏิบัติงานในเขตกรุงเทพฯ และปริมณฑลนอกสำนักงาน: เบี้ยเลี้ยง 250 บาทต่อวัน\n- ที่พักต่างจังหวัด: เบิกตามจริงไม่เกิน 1,800 บาทต่อคืน\n\n## ค่าเดินทาง\n- รถแท็กซี่/รถรับจ้างผ่านแอป: เบิกตามจริง ต้องแนบใบเสร็จหรือภาพหน้าจอค่าโดยสาร\n- ใช้รถยนต์ส่วนตัวเพื่องานบริษัท: ชดเชยกิโลเมตรละ 6 บาท (คำนวณตามระยะทางจริงจากแผนที่)\n- เครื่องบินภายในประเทศ: ชั้นประหยัดเท่านั้น จองผ่านฝ่ายธุรการล่วงหน้าอย่างน้อย 7 วัน\n\n## อุปกรณ์ทำงาน\nพนักงานสายวิศวกรรมและทีมข้อมูลมีงบประมาณคอมพิวเตอร์โน้ตบุ๊ก 45,000 บาท ต่อรอบ 3 ปี ส่วนอุปกรณ์เสริม (จอภาพ คีย์บอร์ด เมาส์ หูฟัง) มีงบรวม 8,000 บาทต่อรอบ 2 ปี การจัดซื้อทุกรายการต้องขออนุมัติผ่านหัวหน้าทีมและฝ่ายไอทีก่อนสั่งซื้อ\n\n## ค่าอบรมและพัฒนาตนเอง\nพนักงานที่ผ่านทดลองงานแล้วมีงบอบรม สัมมนา และคอร์สออนไลน์ คนละ 12,000 บาทต่อปี การใช้งบต้องเกี่ยวข้องกับงานที่รับผิดชอบและได้รับอนุมัติจากหัวหน้าทีมล่วงหน้า หลังอบรมต้องสรุปความรู้แบ่งปันในทีมภายใน 2 สัปดาห์\n\n## ค่ารับรองลูกค้า\nเฉพาะพนักงานระดับหัวหน้าทีมขึ้นไป เบิกได้ไม่เกิน 1,500 บาทต่อครั้ง และไม่เกิน 6,000 บาทต่อเดือน ต้องระบุชื่อลูกค้าและวัตถุประสงค์ในการรับรองทุกครั้ง\n', '04_product_faq.md': '# คำถามที่พบบ่อย ผลิตภัณฑ์ "อร่อยไหม" (AroiMai)\n\n## อร่อยไหมคืออะไร\n"อร่อยไหม" (AroiMai) คือแอปพลิเคชันและ API สำหรับรู้จำอาหารไทยจากภาพถ่ายด้วยปัญญาประดิษฐ์ ผู้ใช้ถ่ายรูปจานอาหาร ระบบจะระบุชื่อเมนู ประเมินแคลอรี่โดยประมาณ และแนะนำข้อมูลโภชนาการ ปัจจุบันรองรับเมนูอาหารไทย 50 เมนูหลัก และมีแผนขยายเป็น 120 เมนูภายในปี พ.ศ. 2570\n\n## เทคโนโลยีเบื้องหลัง\nระบบรู้จำภาพของอร่อยไหมใช้โมเดล Vision Transformer ที่ผ่านการ fine-tune จากโมเดล pretrained ด้วยชุดข้อมูลภาพอาหารไทยมากกว่า 150,000 ภาพ ความแม่นยำบนชุดทดสอบมาตรฐานอยู่ที่ 94.2% (Top-1 accuracy) ส่วนระบบถาม-ตอบโภชนาการใช้เทคนิค RAG (Retrieval-Augmented Generation) ร่วมกับโมเดลภาษาไทย เพื่อให้คำตอบอ้างอิงจากฐานข้อมูลโภชนาการของกรมอนามัยเท่านั้น\n\n## แพ็กเกจและราคา (สำหรับลูกค้าองค์กร)\n- แพ็กเกจ Starter: 5,000 คำขอต่อเดือน ราคา 2,900 บาทต่อเดือน\n- แพ็กเกจ Growth: 50,000 คำขอต่อเดือน ราคา 19,900 บาทต่อเดือน\n- แพ็กเกจ Enterprise: ไม่จำกัดคำขอ ราคาตามข้อตกลง พร้อม SLA รับประกันความพร้อมใช้งาน 99.5%\nผู้ใช้ทั่วไปดาวน์โหลดแอปได้ฟรี ใช้งานได้วันละ 10 ภาพ\n\n## ข้อจำกัดของระบบ\nระบบอาจจำแนกผิดพลาดในกรณีภาพมืดหรือเบลอมาก อาหารหลายจานในภาพเดียว หรือเมนูที่หน้าตาคล้ายกันมาก เช่น แกงเขียวหวานกับแกงเผ็ด ค่าแคลอรี่เป็นการประมาณจากขนาดจานมาตรฐานเท่านั้น ไม่ควรใช้แทนคำแนะนำของนักโภชนาการหรือแพทย์\n\n## ความเป็นส่วนตัวของข้อมูล\nภาพที่ผู้ใช้ถ่ายจะถูกประมวลผลและลบออกจากเซิร์ฟเวอร์ภายใน 24 ชั่วโมง เว้นแต่ผู้ใช้กดยินยอมบริจาคภาพเพื่อพัฒนาโมเดล ข้อมูลส่วนบุคคลทั้งหมดจัดเก็บตามพระราชบัญญัติคุ้มครองข้อมูลส่วนบุคคล พ.ศ. 2562 (PDPA) ผู้ใช้ขอลบข้อมูลของตนได้ที่ privacy@siamtech.example\n\n## การติดต่อฝ่ายสนับสนุน\nลูกค้าองค์กรติดต่อ sales@siamtech.example ผู้ใช้ทั่วไปแจ้งปัญหาในแอปเมนู "ช่วยเหลือ" ทีมสนับสนุนตอบภายใน 1 วันทำการ\n', '05_it_security_policy.md': '# นโยบายความปลอดภัยสารสนเทศ บริษัท สยามเทค เอไอ จำกัด\n\n## บัญชีผู้ใช้และรหัสผ่าน\nรหัสผ่านของระบบภายในทุกระบบต้องยาวอย่างน้อย 14 ตัวอักษร ประกอบด้วยตัวพิมพ์ใหญ่ ตัวพิมพ์เล็ก ตัวเลข และอักขระพิเศษ ต้องเปลี่ยนรหัสผ่านทุก 180 วัน และห้ามใช้รหัสผ่านซ้ำกับ 5 รหัสล่าสุด พนักงานทุกคนต้องเปิดใช้การยืนยันตัวตนสองขั้นตอน (2FA) ภายใน 7 วันแรกของการเริ่มงาน\n\n## การใช้งานเครือข่าย\nการเข้าถึงระบบภายในจากนอกสำนักงานต้องผ่าน VPN ของบริษัทเท่านั้น ห้ามใช้ Wi-Fi สาธารณะทำงานกับข้อมูลลูกค้าโดยไม่เชื่อมต่อ VPN อุปกรณ์ส่วนตัวที่ใช้ทำงาน (BYOD) ต้องลงทะเบียนกับฝ่ายไอทีและติดตั้งโปรแกรมป้องกันไวรัสที่บริษัทกำหนด\n\n## การใช้เครื่องมือปัญญาประดิษฐ์ภายนอก\nห้ามนำข้อมูลลูกค้า ข้อมูลส่วนบุคคล ซอร์สโค้ดของบริษัท หรือข้อมูลลับทางธุรกิจ ไปป้อนในบริการปัญญาประดิษฐ์ภายนอก (เช่น แชตบอตสาธารณะ) ที่บริษัทไม่ได้ทำสัญญาประมวลผลข้อมูลไว้ หากต้องการใช้เครื่องมือ AI ช่วยงาน ให้ใช้บริการที่บริษัทจัดเตรียมไว้ หรือขออนุมัติจากฝ่ายความปลอดภัยข้อมูลก่อน การฝ่าฝืนถือเป็นความผิดวินัยร้ายแรง\n\n## การจัดชั้นความลับของข้อมูล\nข้อมูลของบริษัทแบ่งเป็น 3 ระดับ ได้แก่ Public (เผยแพร่ได้), Internal (ใช้ภายในเท่านั้น), Confidential (จำกัดเฉพาะผู้เกี่ยวข้อง) ข้อมูลลูกค้าและข้อมูลส่วนบุคคลจัดเป็นระดับ Confidential เสมอ การส่งข้อมูล Confidential ออกนอกบริษัทต้องเข้ารหัสและได้รับอนุมัติจากหัวหน้าฝ่าย\n\n## การรายงานเหตุการณ์ผิดปกติ\nหากพบหรือสงสัยว่าเกิดเหตุการณ์ด้านความปลอดภัย เช่น บัญชีถูกแฮ็ก ข้อมูลรั่วไหล อีเมลหลอกลวง (phishing) หรือทำอุปกรณ์บริษัทสูญหาย ต้องรายงานฝ่ายความปลอดภัยข้อมูลที่ security@siamtech.example หรือโทรภายใน 303 ภายใน 24 ชั่วโมง การรายงานโดยสุจริตจะไม่ถูกลงโทษแม้ความเสียหายเกิดจากความผิดพลาดของผู้รายงานเอง\n\n## การสำรองข้อมูล\nข้อมูลงานทั้งหมดต้องเก็บในระบบคลาวด์ของบริษัทเท่านั้น ห้ามเก็บงานไว้ในเครื่องส่วนตัวเพียงแห่งเดียว ระบบสำรองข้อมูลอัตโนมัติทำงานทุกวันเวลา 02:00 น. และเก็บย้อนหลัง 35 วัน\n', '06_onboarding_guide.md': '# คู่มือพนักงานใหม่ บริษัท สยามเทค เอไอ จำกัด\n\n## สัปดาห์แรกของคุณ\nวันแรกให้มาถึงสำนักงานเวลา 09:30 น. ติดต่อฝ่ายบุคคลที่ชั้น 8 เพื่อรับบัตรพนักงาน โน้ตบุ๊ก และอีเมลบริษัท จากนั้นเข้าประชุมปฐมนิเทศช่วงบ่าย (13:30–16:00 น.) ภายในสัปดาห์แรกพนักงานใหม่ต้องทำรายการต่อไปนี้ให้ครบ:\n1. เปิดใช้การยืนยันตัวตนสองขั้นตอน (2FA) กับทุกระบบ\n2. ลงทะเบียนบัญชีในระบบ SiamHR และตรวจสอบข้อมูลส่วนตัว\n3. อ่านและลงนามรับทราบนโยบายความปลอดภัยสารสนเทศ\n4. เรียนคอร์สออนไลน์ภายใน "PDPA สำหรับพนักงาน" ให้จบ (ใช้เวลาประมาณ 2 ชั่วโมง)\n5. นัดคุยตัวต่อตัวกับหัวหน้าทีมและพี่เลี้ยง\n\n## ระบบพี่เลี้ยง (Buddy Program)\nพนักงานใหม่ทุกคนจะมีพี่เลี้ยง 1 คนจากทีมเดียวกัน ดูแลตลอด 90 วันแรก พี่เลี้ยงมีหน้าที่ตอบคำถาม แนะนำวัฒนธรรมการทำงาน และประชุมติดตามกับพนักงานใหม่สัปดาห์ละ 1 ครั้งเป็นอย่างน้อย\n\n## ช่วงทดลองงานและการประเมิน\nช่วงทดลองงานมีระยะเวลา 119 วัน มีการประเมิน 2 ครั้ง คือวันที่ 45 และวันที่ 100 ของการทำงาน เกณฑ์การประเมินประกอบด้วยคุณภาพงาน การเรียนรู้ การทำงานร่วมกับทีม และการปฏิบัติตามค่านิยมบริษัท ผลการประเมินจะแจ้งโดยหัวหน้าทีมพร้อมข้อเสนอแนะเป็นลายลักษณ์อักษร\n\n## เครื่องมือหลักที่ใช้ในบริษัท\n- สื่อสารภายใน: Slack (ช่องทางหลัก ตอบภายในเวลาทำงาน)\n- จัดการงาน: Jira สำหรับทีมวิศวกรรม, Notion สำหรับเอกสารทีม\n- โค้ดและรีวิว: GitHub องค์กร ทุก pull request ต้องมีผู้รีวิวอย่างน้อย 1 คน\n- ข้อมูลและการทดลองโมเดล: MLflow สำหรับติดตามการทดลอง, DVC สำหรับจัดการชุดข้อมูล\n\n## ค่านิยมบริษัท (SIAM)\n- **S — Ship it**: ของจริงที่ใช้งานได้ สำคัญกว่าสไลด์ที่สวยงาม\n- **I — Integrity of data**: เคารพข้อมูลของผู้ใช้เหมือนเป็นของครอบครัวเรา\n- **A — Always learning**: แบ่งปันสิ่งที่เรียนรู้ให้ทีมทุกสัปดาห์\n- **M — Measure everything**: ตัดสินใจด้วยตัวเลข ไม่ใช่ความรู้สึก\n\n## คำถามที่พนักงานใหม่ถามบ่อย\nถาม: เบิกค่าเดินทางมาทำงานวันแรกได้ไหม — ตอบ: ไม่ได้ การเดินทางมาทำงานปกติไม่อยู่ในระเบียบการเบิก\nถาม: ใช้วันลาพักร้อนช่วงทดลองงานได้ไหม — ตอบ: ไม่ได้ สิทธิ์ลาพักร้อนเริ่มหลังผ่านทดลองงาน 119 วัน\nถาม: อยากย้ายทีมทำอย่างไร — ตอบ: คุยกับหัวหน้าทีมปัจจุบันก่อน จากนั้นยื่นความประสงค์กับฝ่ายบุคคล พิจารณาปีละ 2 รอบ\n', } def chunk_document(fname, text, min_len=40): chunks, current_section = [], '' for block in text.split('\n\n'): lines = block.strip().split('\n') while lines and lines[0].lstrip().startswith('#'): current_section = lines[0].lstrip('# ').strip(); lines = lines[1:] body = '\n'.join(lines).strip() if len(body) >= min_len: chunks.append({'doc': fname, 'section': current_section, 'text': body}) return chunks all_chunks = [] for fname, content in SIAMTECH_DOCS.items(): all_chunks.extend(chunk_document(fname, content)) embedder = SentenceTransformer('intfloat/multilingual-e5-small', device='cpu') # pin to CPU — ZeroGPU's fake-CUDA hijacks auto device selection chunk_emb = embedder.encode([f"passage: {c['section']} — {c['text']}" for c in all_chunks], normalize_embeddings=True) RAG_SYSTEM = '''คุณคือผู้ช่วย HR ของบริษัทสยามเทค เอไอ ตอบคำถามพนักงานเป็นภาษาไทย กติกาเหล็ก: 1. ตอบโดยใช้ข้อมูลจาก "เอกสารอ้างอิง" ที่ให้มาเท่านั้น ห้ามใช้ความรู้อื่น 2. ระบุชื่อเอกสารที่ใช้อ้างอิงท้ายคำตอบ ในรูปแบบ [อ้างอิง: ชื่อไฟล์] 3. ถ้าเอกสารอ้างอิงไม่มีคำตอบ ให้ตอบว่า "ขออภัย ไม่พบข้อมูลนี้ในเอกสารบริษัท กรุณาติดต่อ hr@siamtech.example" ห้ามเดา''' def rag_answer(question, k=3): q = embedder.encode([f'query: {question}'], normalize_embeddings=True) idx = np.argsort((chunk_emb @ q.T).ravel())[::-1][:k] context = '\n\n'.join( f"[เอกสาร: {all_chunks[i]['doc']} | หัวข้อ: {all_chunks[i]['section']}]\n{all_chunks[i]['text']}" for i in idx) r = client.chat.completions.create(model=MODEL, temperature=0, max_tokens=512, messages=[ {'role': 'system', 'content': RAG_SYSTEM}, {'role': 'user', 'content': f'เอกสารอ้างอิง:\n{context}\n\nคำถาม: {question}'}]) return r.choices[0].message.content def chat_fn(message, history): try: return rag_answer(message) except Exception as e: return f'ขออภัย ระบบขัดข้อง: {type(e).__name__} — ลองใหม่อีกครั้ง' demo = gr.ChatInterface( fn=chat_fn, title='💬 SiamTech HR Assistant', description='RAG chatbot · Workshop "AI in the Real World" · KU KPS (ข้อมูลบริษัทสมมติ)', examples=['ลาพักร้อนได้กี่วันต่อปี?', 'เบี้ยเลี้ยงไปต่างจังหวัดวันละเท่าไหร่?', 'รหัสผ่านต้องยาวกี่ตัวอักษร?']) demo.launch()