Siam East · datawarehouse."Orasa" · สร้าง 07/10/2569 · datawarehouse."Orasa" (203.150.148.186) · โหลดจาก item code _CATEGORIES_COMPLETED.xlsx

Orasa (Ai)

แพลตฟอร์ม ML ของ Siam East ที่ตอบได้หลายเรื่อง — ความรู้แยกเป็น 6 หมวด (Knowledge Domain) แต่ละ skill อยู่ในหมวดของตัวเองบน core เดียวกัน · skill แรกคือ Item Code Search: ค้นได้ทั้งรหัส · part number · คำอธิบาย · ความหมาย และเรียนรู้จากการใช้งานจริง

6 Knowledge Domain7 Skill (1 ใช้งาน)14 Table16,572 Item74,121 บรรทัดขายIT จัดการ token เอง

Next Step · รอข้อมูลจากพนักงาน SE แล้ว Train

ตัดสิน 10 ต.ค. 2026 (ที่รัก) — Orasa ใช้เฉพาะใน Siam East · model ที่เทรนเรียนภาษาที่คน SE ใช้เรียกสินค้าเท่านั้น · ยังไม่เทรนตอนนี้ เพราะ log ก่อน 9 ต.ค. 09:10 เป็นการทดลอง (is_test) — ต้องรอให้พนักงาน SE ใช้งานจริงก่อน

ขั้นทำอะไรเริ่มเมื่อสถานะ
1 · Deploy ให้พนักงาน SE ใช้IT SE ดึง main ขึ้น docker + รัน sql/007, sql/008 · แจก extension ให้ Sales / จัดซื้อที่รัก add IT SE เข้า GitHub⏳ รอ
2 · สะสมข้อมูลจริงทุกการค้น → เลือก ลง interaction_log (is_test = false) · ดูยอดที่ GET /api/learning/statsหลัง deploy⏳ รอ
3 · ชุดสอบ held-outแยกคำค้นจริง 100 คำ (ไม่ใช้สอน) ไว้วัดทุก modelมีการค้นจริง ~300 ครั้ง⏳ รอ
4 · Train Ranker (ชั้น 3)LightGBM LambdaMART จากคู่ เลือก / ถูกข้าม · ขึ้นเป็น candidate รัน shadow ก่อน activeมีการเลือก ~1,500 ครั้ง⏳ รอ
5 · Fine-tune bge-m3 (ชั้น 4)คู่ (คำค้น, item ที่เลือก) + hard negative → model ของ SE · ขนาด ~2 GB รัน CPU ใน docker ของ IT ได้มีคู่ ~1,000–2,000 คู่ และ Ranker ใช้งานแล้ว⏳ รอ
  • •✅ 30 ต.ค. 2569 · IT Admin ของ SE deploy Search API 0.2.0 เรียบร้อย — สร้าง / ปิด / ออก token ใหม่ / ดูการใช้งานล่าสุด ได้เองบน SE server (คู่มือ Orasa_Deploy_SE_IT_Admin_API0.2.0_2026-10-30 ใน Source files ข้อ 5)
  • •✅ 1 คน = 1 token — IT เป็นคนสร้างและส่งให้พนักงานเอง token ของ SE ไม่ผ่านทีม DV · ทุกคำค้นบันทึกตามชื่อผู้ใช้ใน interaction_log
  • •⏳ IT ออก token ให้พนักงาน SE ที่จะใช้ (Sales / จัดซื้อ / Admin) แล้วติดตั้ง extension 0.7.0 ในเครื่อง
  • •⏳ ติดตามด้วย `api.users list` (คอลัมน์ "ใช้ล่าสุด") และ /api/learning/stats — พอมีการค้นจริงต่อเนื่อง จึงเริ่มเทรน Ranker

ไม่เทรน LLM ให้จำ item ทั้ง 16,572 ตัว — LLM แต่งรหัสที่ไม่มีจริงได้ และ item เปลี่ยนทุกวัน · ค้นจาก DB เหมือนเดิม ให้ model ช่วยเข้าใจคำค้นและจัดลำดับเท่านั้น

สรุป

Orasa (Ai) ไม่ใช่ ML ที่ตอบได้เรื่องเดียว — เป็นแพลตฟอร์มที่ความรู้แยกเป็นหมวด และเพิ่ม skill ใหม่ได้โดยไม่แก้ core ทุก skill ใช้ตารางกลางร่วมกัน (skill · model_registry · interaction_log · embedding · knowledge) จึงได้ข้อมูลเทรนจากการใช้งานจริงเหมือนกันหมด Skill แรก — Item Code Search: ข้อมูลใน Excel เป็นบรรทัดขายจริง ไม่ใช่ master สินค้า จึงแยกเป็น master สินค้า (item) กับประวัติการขาย (sales_line) แล้วผูกกับรหัสอ้างอิง Brand / Product / Category

  • •Knowledge แยก 6 หมวด: product · sales · purchase · asset · service · document — ทุก skill / ความรู้ / vector ติด domain_code ค้นและเทรนในหมวดของตัวเอง
  • •ใช้ได้ 2 ทาง: Web App (React + FastAPI) และ Floating widget (Chrome/Edge extension · Alt+O) ลอยบนทุก Web App แล้ว Copy / Insert Item Code
  • •Item Code 20 ตัวอักษร = Brand 2 + Product 2 + "-" + Model/Spec 15 — ถอดเป็นคอลัมน์ได้ตรง ๆ
  • •รหัส Product 2 หลักไม่ได้มีความหมายเดียวทุก Brand (69 รหัสมีชื่อต่างกันตาม Brand) → ต้องมีตารางคู่ Brand+Product
  • •ตาราง interaction_log คือหัวใจของ ML — ไม่มีข้อมูลการค้นจริง ก็ไม่มีอะไรให้โมเดลเรียน
  • •สร้างแล้วใน datawarehouse schema "Orasa": item 16,572 · sales_line 74,121 · search_term 52,692 · pg_trgm ติดตั้งแล้ว · pgvector 0.8.6 ลงแล้ว (IT 07/10) · embedding ด้วย bge-m3 ครบ 16,572 item + HNSW index แล้ว (ดู Item Search 8)

A. Knowledge Domains

ความรู้แยกหมวด — แต่ละหมวดประกาศว่าเรียนจาก schema ไหนของ datawarehouse

Domainความรู้เรียนจากSkill
productสินค้า · Item Code · Brand · Product · หมวดOrasaItem Code Search ✅ · Item Code Suggest
salesประวัติขาย · ราคา · ลูกค้าOrasa · CRMPrice Suggest · Customer Cross-sell
purchaseใบสั่งซื้อ · supplierPurchasePurchase Anomaly
assetทรัพย์สิน · ซ่อมบำรุง · ticket / jobAssetManagementAsset Maintenance
serviceงานบริการหน้างานse_connex— (เพิ่มได้โดยไม่แก้ core)
documentคู่มือ · spec · datasheetไฟล์เอกสารDocument Q&A

B. Skills

skill = ความสามารถหนึ่งเรื่องของ Orasa · ทุกตัวทำตามสัญญาเดียวกัน predict / train / evaluate

SkillDomainสถานะทำอะไร
item_searchproduct✅ ใช้งานค้นหา Item Code จากรหัส / part no / คำอธิบาย / ความหมาย
item_code_suggestproductวางแผนเสนอ Brand / Product / หมวด ให้สินค้าใหม่
price_suggestsalesวางแผนเสนอราคาจากประวัติขาย
cross_sellsalesวางแผนลูกค้ารายนี้น่าจะซื้ออะไรต่อ
purchase_anomalypurchaseวางแผนจับ PO ผิดปกติ
asset_maintenanceassetวางแผนทำนายการซ่อมบำรุง
doc_qadocumentวางแผนถามตอบจากคู่มือ / spec สินค้า

กติกา: 1 skill = 1 โฟลเดอร์ · skill ไม่อ่าน table ของ skill อื่นตรง ๆ · log ที่เดียว (interaction_log) · โมเดลใหม่ต้องชนะตัวเดิมก่อน active · สิทธิ์ราย domain

Item Search 1 · ข้อมูลที่ได้รับ

Sheetแถวเนื้อหา
PRODUCTSยกเว้น GF74,121บรรทัดขาย 2018–2026 · 13,964 Item Code · invoice / SO / qty / revenue / หมวด
GF GRUNDFOS8,328Item GF 2,608 ตัว · Part Number · Customer Code · หมวด PUMP ทั้งหมด
MASTER 4 digits item code933รหัส Brand 2 หลัก + Product 2 หลัก พร้อมชื่อ
Master R1 4di w categ534คู่ Brand+Product → Category + กลุ่มสินค้า (1=PUMP, 2=VALVE, 3=Consumable, 4=Process Equipment, 7=Power, 9=Service)
Master SO CODE268โครงสร้างเลข Sale Order (ประเภทขาย · กลุ่ม · location · ปี · product · พนักงาน · running)

Item Search 2 · โครงสร้าง Item Code

ตำแหน่งความหมายตัวอย่าง
ตัวที่ 1–2BrandTD = TOMOE DECANTER
ตัวที่ 3–4ProductSP = SPARE PART
ตัวที่ 5ขีดคั่น-
ตัวที่ 6–20Model / Spec / Part (เติม X ให้ครบ)STSTS1303ABPTM9 · ELPAPERXXXXXXXX

ตัวอย่างเต็ม: TDSP-STSTS1303ABPTM9 = TOMOE DECANTER · SPARE PART · STSTS1303ABPTM9

Item Search 3 · Table Design (ทั้ง schema Orasa)

แบ่ง 4 กลุ่ม: รหัสอ้างอิง (ref_*) · สินค้าและการขาย · ชั้นค้นหา · platform core (ทุก skill ใช้ร่วม)

TableKeyคอลัมน์หลักที่มา
ref_brandbrand_code (2)brand_nameMASTER 4 digits
ref_product_typeproduct_code (2)product_nameMASTER 4 digits
ref_categorycategory_idcategory_name · product_group_no (1–9)Master R1 (ล้างชื่อซ้ำแล้ว)
ref_brand_productbrand_code + product_codeproduct_name_local · category_id · source (master / inferred)Master R1 + คู่ที่พบในการขาย
itemitem_codebrand_code · product_code · model_spec · part_number · description · detail · unit · product_group · status · code_validPRODUCTS + GF (1 แถวต่อ item)
sales_lineline_iditem_code · invoice_no · invoice_date · sale_order_no · qty · revenue · unitPRODUCTS (74,121 แถว)
item_customeritem_code + customer_codefirst_seenGF GRUNDFOS
item_search_termterm_iditem_code · term · term_type (code / part_no / model / synonym / customer_word)สร้างจาก item + เพิ่มจากการใช้งาน
embeddingentity_type + entity_id + model_namedomain_code · vector · text_hashvector ของทุก entity แยก domain (ใช้ร่วมทุก skill)
interaction_loglog_idskill_code · query · shown · chosen_ref · action · model_idทุก request ของทุก skill (ข้อมูลเทรน ML)
knowledge_domaindomain_codeproduct · sales · purchase · asset · service · documentความรู้แยกหมวด
skillskill_codedomain_code · statusOrasa ตอบได้หลายเรื่อง — item_search คือ skill แรก
model_registrymodel_idskill_code · version · metrics · statusactive ได้ทีละตัวต่อ skill
knowledgeknowledge_iddomain_code · kind · contentchunk เอกสาร · กฎ · FAQ

Item Search 4 · Relation

จากไปชนิดผ่าน
ref_brand_productref_brandN : 1brand_code
ref_brand_productref_product_typeN : 1product_code
ref_brand_productref_categoryN : 1category_id
itemref_brand_productN : 1brand_code + product_code
sales_lineitemN : 1item_code
item_customeritemN : 1item_code
item_search_termitemN : 1item_code
skill / embedding / knowledgeknowledge_domainN : 1domain_code
interaction_logskill · model_registryN : 1skill_code · model_id

ref_brand_product คือจุดที่ตัดสินหมวดของ item — item ชี้ไปที่คู่ (brand_code, product_code) แทนที่จะผูกหมวดกับ Product อย่างเดียว

Item Search 5 · Smart Search ทำงานอย่างไร

ค้นทุกชั้นพร้อมกัน แล้วรวมคะแนนเรียงผลเดียว

ชั้นวิธีตัวอย่างที่ค้นเจอ
1 · ตรงตัวรหัส / part number แบบตัดขีด-ช่องว่าง, ค้นบางส่วนได้"99884046" → GFSP-KIT99884046ROTA
2 · สะกดใกล้เคียงpg_trgm บน description + search_term"filtr papr" → FILTER PAPER
3 · ความหมายembedding (domain product) → pgvector"ใบกรอง" → FILTER PAPER · "ซ่อมเครื่องแยกกาก" → REPAIR WORK FOR PTM340V
4 · กรองตามรหัสจับ Brand/Product จากคำค้น"grundfos pump" → GF + PS ก่อน
5 · เรียงผลคะแนนความตรง + จำนวน order + ขายล่าสุด → ภายหลังใช้ Ranker จาก interaction_logitem ที่ขายบ่อยและล่าสุดขึ้นก่อน

Item Search 6 · ML ที่จะสร้าง

  • •โมเดล 1 · Ranker — เรียนจาก interaction_log ว่าคำค้นแบบนี้ ผู้ใช้เลือก item ไหน (learning-to-rank) แล้วใช้เรียงผลแทนสูตรตายตัว
  • •โมเดล 2 · Classifier — รับคำอธิบายสินค้าใหม่ แล้วเสนอ Brand / Product / Category / Item Code ที่ควรเป็น ช่วยคนตั้งรหัสใหม่ให้ถูกโครงสร้าง
  • •เริ่มเทรนได้ทันทีด้วยข้อมูลที่มี: คู่ (คำอธิบาย → item_code) 13,964 item + Part Number GF 2,608 ตัว เป็นชุดตั้งต้น ก่อนมี interaction_log จริง
  • •วัดผล: เปอร์เซ็นต์ที่ item ที่ถูกอยู่อันดับ 1 และใน 5 อันดับแรก (Hit@1 / Hit@5) จากชุดทดสอบที่แยกไว้

Item Search 7 · คุณภาพข้อมูลที่ต้องจัดการ

เรื่องจำนวนข้อเสนอ
หมวด = REVIEW - NOT IN MASTER4,083 แถวเก็บไว้ status = review รอคนยืนยัน
คู่ Brand+Product ไม่มีใน Master R1422 / 538 คู่เติม ref_brand_product ด้วย source = inferred
ชื่อหมวดซ้ำต่างตัวพิมพ์PROCESS EQUIPMENT / Process Equipmentรวมเป็นหมวดเดียวใน ref_category
product_group ค่าแปลกps · 0 · EA · 99 · DM (9 แถว)แก้ให้ตรงชุด IM / PP / SB / PS / ...
Item Code ไม่ครบ 20 ตัว23 แถวcode_valid = false รอแก้
Item เดียวอยู่หลายหมวด9 itemเลือกหมวดเดียวหลังตรวจ
ชื่อลูกค้าในชีตหลักว่าง 100%ใช้ลูกค้าได้เฉพาะ GF — ถ้าต้องการ ต้องดึงจาก invoice ใน SE DB

Item Search 8 · Model ที่ใช้

เลือก 7 ต.ค. 2026 จากการวัดกับสินค้าจริงของ SE ด้วยคำค้นไทย + อังกฤษ 16 คำ (ถูก = คำอธิบายของผลอันดับ 1 มีคำอังกฤษที่ตรง) · ลงทะเบียนใน "Orasa".model_registry (model_id 1, active)

ส่วนModelรายละเอียดผลวัด
Embedding (ใช้งานอยู่)bge-m3 · 1,024 มิติ · Ollama บน M6 (version 790764642607)ข้อความ = description | category · ครบ 16,572 item (domain product) · index HNSW embedding_hnsw_bge_m3 · ค้น ~16 msชุดทดสอบ 4,432 item: ถูกอันดับ 1 10/16 · P@5 0.49 — ทั้ง 16,572 item: 7/16
Embedding (ไม่เลือก)granite-embedding:278m · 768 มิติ (ตัวที่ Angela ใช้)ไม่รองรับภาษาไทย — "ใบกรอง" ได้น้ำยาถูพื้น · "วาล์วกันกลับ" ได้ใบมีดชุดทดสอบเดียวกัน: ถูกอันดับ 1 4/16 · P@5 0.26
ข้อความที่ embeddescription | category (ตัด brand / product ออก)ชื่อ product อย่าง "OUTSOURCE service Check/Repair/Report" ดึงคำค้น "วาล์วกันกลับ" ไปหางานบริการทั้ง 16,572 item: desc+category 7/16 · desc+brand+product+category 6/16 · desc อย่างเดียว 5/16
Classifierยังไม่เทรน — แผน: TF-IDF char n-gram + Logistic Regressionเสนอ Brand / Product / Category ให้สินค้าใหม่รอที่รักตัดสินคำถาม 4 ข้อ
Rankerยังไม่เทรน — แผน: LightGBM LambdaRankเรียงผลจากทุกชั้นด้วยข้อมูล interaction_logต้องมีการค้นจริงก่อน — ดู Item Search 9 ชั้น 3

vector อย่างเดียวยังถูกอันดับ 1 ไม่ถึงครึ่ง เพราะใน 16,572 item มีงานบริการ / ค่าแรงปนเยอะ — Smart Search จึงต้องใช้ทุกชั้นร่วมกัน (รหัส · trigram · คำพ้องไทย→อังกฤษ ใน item_search_term · vector) แล้วให้ Ranker เรียนจาก interaction_log

Item Search 9 · Orasa เก่งขึ้นจากการใช้งาน

ออกแบบ 9 ต.ค. 2026 (ที่รัก: "เมื่อมีคนใช้เรื่อยๆ Orasa จะเก่งขึ้นได้ยังไง") — ทุกครั้งที่มีคนค้นแล้วเลือก = ครูสอน Orasa หนึ่งครั้ง · ทุกการค้นถูกบันทึกใน "Orasa".interaction_log (คำค้น · 10 อันดับที่โชว์ · ตัวที่เลือก · copy / insert / ไม่เจอ) · การค้นก่อน 9 ต.ค. 09:10 เป็นการทดลอง ติดป้าย is_test ไม่นำมาเรียน

ชั้นเรียนจากอะไรทำงานอย่างไรสถานะ
1 · จำทันทีคนที่ค้นคำเดียวกันแล้วเลือก item ไหน (copy / insert) + ปุ่ม "ไม่เจอที่ต้องการ?" ให้พิมพ์รหัสที่ถูก (นับ 2 เท่า)ช่องค้นที่ 5 ชื่อ learned อ่าน interaction_log ตรงๆ — การค้นครั้งถัดไปใช้ได้เลย ไม่ต้องรอ cron · จางลงเองถ้าไม่มีใครเลือก (90 วัน) · widget ขึ้น ★ "คนค้นคำนี้เลือกตัวนี้"✅ ทำแล้ว 9 ต.ค. (widget 0.4.0 · sql/007) — ทดสอบ: item อันดับ 30 สอนครั้งเดียวขึ้นอันดับ 1 · eval 19 คำยัง 17/19
2 · เรียนคำพ้องเองค้นคำไทยไม่เจอ แล้วพิมพ์ใหม่เป็นอังกฤษแล้วเลือกได้ (เช่น "ใบกรอง" → "FILTER")คู่ที่ ≥ 3 คนทำเหมือนกัน เข้าคิวให้ admin กด ✓ แล้วลง synonym (source = learned)✅ ทำแล้ว 10 ต.ค. (widget 0.5.0 · sql/008) — รอมีการใช้งานจริง
3 · Ranker เรียนน้ำหนักเองตัวที่เลือก = ถูก · ตัวที่โชว์อยู่เหนือแต่ถูกข้าม = ผิดLightGBM LambdaMART แทนสูตรมือ 50/40/10 — feature: คะแนนทั้ง 5 ช่อง · ขายดี · ประวัติผู้ใช้ · หน้าเว็บที่กรอก · สลับอันดับ 2–3 บางครั้งแก้ position biasเริ่มเมื่อมีการเลือก ~1,500 ครั้ง
4 · Fine-tune embeddingคู่ (คำค้น, item ที่เลือก) + ตัวที่ถูกข้ามเป็น hard negativeสอน bge-m3 ให้เข้าใจภาษา SE แล้ว embed สินค้าใหม่ทั้งชุด เทียบกับตัวเดิมบนชุดสอบรายเดือน ทำทีหลัง

ด่านกันพังทุกชั้น: ชุดสอบ held-out จาก log จริง (แยกไว้ไม่ใช้สอน) · โมเดลใหม่เข้า model_registry เป็น candidate รัน shadow คู่ตัวเดิม ขึ้น active เมื่อชนะเท่านั้น ย้อนกลับได้ทันที · 1 คนนับ 1 เสียงต่อวันต่อ item กันคนเดียวลากผล · ตัวเลขดูความก้าวหน้า: GET /api/learning/stats → อัตราการเลือก · อันดับเฉลี่ยของตัวที่เลือก · อัตรา "ไม่เจอ" + Hit@1 บนชุดสอบ

Open questions

  1. 1.แถวที่หมวดยังเป็น "REVIEW - NOT IN MASTER" (4,083 แถว) และรหัสผิดรูป (23 แถว) — เก็บไว้แบบ status = review หรือคัดออก?
  2. 2.คู่ Brand+Product ที่ขายจริงแต่ไม่มีใน Master R1 (422 จาก 538 คู่) — เติมเข้า ref_brand_product โดยติด source = inferred ได้ไหม?
  3. 3.หลัง Product แล้ว domain / skill ไหนควรทำต่อเป็นอันดับ 2 (Sales · Purchase · Asset · Document)?