Multimodal + OCR — เปลี่ยนภาพ/เอกสารเป็น JSON ที่เชื่อถือได้
หมวดนี้รวม 2 กลุ่มที่เกี่ยวกัน: OCR (ดึงข้อมูลจากเอกสาร/ภาพ) และ Multimodal (โมเดลที่รับได้ทั้งภาพ/วิดีโอ/เสียง ไม่ใช่แค่ข้อความ) pattern หัวใจของทั้งหมวดคือสิ่งเดียว: เปลี่ยนของที่ "ไม่มีโครงสร้าง" (ภาพถ่ายใบเสร็จ, PDF, ใบสั่งยา) ให้กลายเป็นข้อมูลมีโครงสร้างที่โค้ดใช้ต่อได้ — ซึ่งตรงกับงาน backend ของคุณเป๊ะ (แนะนำเข้าใจ HO-0 เรื่อง structured output มาก่อน)
OCR แบบเก่า vs Structured Visual Extraction
OCR สมัยก่อนให้ "ก้อนข้อความดิบ" กลับมา แล้วคุณต้องเขียน regex ไล่แกะเอาเอง —
เปราะและพังทันทีถ้า layout เปลี่ยน โปรเจกต์ image_to_structured_data อธิบายการก้าวข้ามนี้ไว้ตรง ๆ:
"move beyond raw text OCR to Structured Visual Extraction" โดยใช้ library
Instructor
บังคับให้ VLM (Vision Language Model) ตอบเป็น JSON ตาม schema โดยตรง
นี่คือ pattern เดียวกับ "structured output" ใน HO-0 — แค่ input เป็นภาพแทนข้อความ:
# image_to_structured_data (แนวจริง) — บังคับ VLM ตอบตาม Pydantic schema
class Receipt(BaseModel):
merchant: str
date: str
total: float
items: list[Item]
# ส่งรูป + schema → ได้ object ที่ validate แล้ว (ไม่ใช่ข้อความมั่ว ๆ)
receipt = client.chat.completions.create(response_model=Receipt, messages=[img])
3 pattern ที่ควรถอดจากหมวดนี้
① Preprocessing ก่อนเข้าโมเดล = คุณภาพพุ่ง
receipt_expense_tracker ทำงาน offline ทั้งหมด (ไม่ต้องมี API key)
และมีจุดที่ควรจำ: มันใช้ Pillow ปรับ contrast/ความคมชัดก่อน ส่งภาพเข้าโมเดล
README บอกว่าช่วย "significantly with low-light photos and bleached thermal paper" —
บทเรียน: อย่าโยนภาพดิบเข้าโมเดลตรง ๆ เตรียมภาพให้ดีก่อน ผลลัพธ์ต่างกันมาก
② ชั้น validate ภายนอก — อย่าเชื่อ LLM ล้วน ๆ
medical_prescription_digitizer ใช้ Mistral Large 3 อ่านลายมือหมอ (ยากมาก) แต่จุดสำคัญคือ
มันไม่เชื่อผล LLM ตรง ๆ — เอาชื่อยาที่สกัดได้ไปตรวจกับฐานข้อมูลยาจริง (RxNorm)
ยาที่ผ่าน = เขียว, ยาที่ไม่รู้จัก/น่าสงสัย = แดง
pattern พกพา (สำคัญมากในงานจริง): LLM/VLM อาจ hallucinate ค่าที่ดูสมเหตุสมผลแต่ผิด — งานที่เดิมพันสูง (การเงิน, การแพทย์) ต้องมี ชั้น validate ด้วยกฎ/ฐานข้อมูลจริง เสมอ ใน NestJS คือ pipe validation + business rule check หลังได้ JSON กลับมา
③ Multimodal = ขยาย modality ของ RAG
multimodal_rag ต่อยอดจาก HO-2 โดยตรง: รับ input 6 แบบ
(text, URL, PDF, ภาพ, เสียง, วิดีโอ) เข้า ChromaDB เดียวกัน แล้วตอนถาม
ส่งไฟล์ต้นฉบับให้ Gemini อ่านสด ๆ ส่วน video_understanding_agent ให้ Gemini
"reads the video natively" — ไม่ต้องดาวน์โหลด/ถอดเสียงก่อน โมเดลรุ่นใหม่ดูวิดีโอได้เลย
| โปรเจกต์ | เปลี่ยนอะไร → เป็นอะไร |
|---|---|
image_to_structured_data | ภาพ → JSON ตาม schema (Instructor) |
receipt_expense_tracker | ใบเสร็จ → รายการค่าใช้จ่าย (offline + preprocess) |
medical_prescription_digitizer | ใบสั่งยา → ข้อมูลยา (validate กับ RxNorm) |
multimodal_rag | 6 modality → คำตอบพร้อม citation |
video_understanding_agent | YouTube URL → สรุป/chapter/action items |
map ลงงาน NestJS ของคุณ
- Structured extraction = pattern เดิมที่คุณทำอยู่แล้ว — กำหนด DTO/Zod schema ส่งไปกับ vision API แล้ว validate ผลลัพธ์ (เหมือน validate request body)
- Preprocessing = ขั้นเตรียมข้อมูลก่อน pipeline (resize/ปรับ contrast) — ทำใน worker ก่อนเรียกโมเดล
- ชั้น validate = business rule / lookup กับ DB จริง (เช่น เช็ครหัสสินค้ามีจริงไหม) หลังได้ JSON — อย่าข้าม
- เก็บผล = JSON ที่ validate แล้วลง PostgreSQL ได้ตรง ๆ (คอลัมน์
jsonbหรือแตกเป็นตาราง)
ระวัง: vision model แพงกว่า text model (คิดตามจำนวน/ขนาดภาพ) — resize ภาพให้พอดีก่อนส่ง และงานที่ความถูกต้องสำคัญ ต้องมีทางให้คน review ผลที่โมเดลไม่มั่นใจ (เหมือน prescription ที่ไฮไลต์แดง) ไม่ใช่ปล่อยผ่านอัตโนมัติทั้งหมด
-
เปิด README ของ
OCR/image_to_structured_data/แล้วตอบว่า "ใช้ Instructor แทนการเขียน regex เอง ได้ประโยชน์อะไร 2 ข้อ" -
medical_prescription_digitizerทำไมต้องเช็คกับ RxNorm ทั้งที่ LLM อ่านออกแล้ว — เขียนอธิบายเชื่อมกับคำว่า hallucination - นึกงานจริงในบริษัทคุณที่ต้องแปลงเอกสารเป็นข้อมูล (เช่น ใบกำกับภาษี, ใบสมัคร) แล้วออกแบบ DTO/Zod schema คร่าว ๆ + บอกว่าจะมี "ชั้น validate ภายนอก" อะไรบ้าง
เมื่อทำเสร็จ พิมพ์ /quiz HO-3 เพื่อทดสอบความเข้าใจ