Tool: read_image — OCR ด้วย Apple Vision แล้วส่งภาพให้โมเดลดูจริงในรอบถัดไป

ภาพประกอบ: Tool: read_image — OCR ด้วย Apple Vision แล้วส่งภาพให้โมเดลดูจริงในรอบถัดไป

หลังจาก Tool: web_search ที่ใช้ค้นข้อมูลภายนอก บทความนี้ปิดชุดด้วย read_image ซึ่งเป็น tool สำหรับอ่านข้อมูลจากภาพโดยตรง

Tool นี้คืออะไร

อ่านไฟล์ภาพแล้วทำ 2 อย่างพร้อมกัน: (1) OCR ดึงข้อความในภาพออกมาทันที และ (2) คิวภาพไว้ให้ vision model เห็นจริงในการตอบรอบถัดไป — ไม่ใช่แค่ “อธิบายภาพเป็นข้อความ” เฉยๆ

ทำไมไม่ต้องเรียกโมเดล vision แยกต่างหาก

จุดสำคัญที่สุดของ tool นี้: Qwen3.5-2B-OptiQ-4bit ที่ AGENT LITE ใช้อยู่แล้วเป็น VLM (Vision-Language Model) ในตัว ไม่ต้องโหลดโมเดลแยกสำหรับดูภาพต่างหาก (ต่างจาก fork อื่นของโปรเจกต์ต้นทางที่มีบางเวอร์ชันเรียก small-VLM ผ่าน HTTP แยก) — read_image แค่คิว path ของภาพที่เตรียมไว้แล้ว ให้ agent.py ดึงไปแนบเป็น image= kwarg ในการเรียกโมเดลรอบถัดไป โมเดลตัวเดียวกันที่กำลังคุยกับผู้ใช้อยู่จึง “เห็น” ภาพนั้นในเทิร์นถัดไปเลย ไม่ต้องส่งไปมาระหว่างสองโมเดล

ทำไมต้อง OCR ด้วย ทั้งที่โมเดลดูภาพเองได้

เหตุผลตรงไปตรงมา: OCR (ผ่าน Apple Vision framework, ไม่ใช้ LLM เลย) ให้ข้อความที่แม่นยำกว่าการให้โมเดลขนาดเล็ก “อ่าน” ตัวอักษรในภาพด้วยสายตา โมเดล VLM ขนาดเล็กมักอ่านตัวเลข/ตัวอักษรผิดพลาดได้ง่ายกว่าเครื่องมือ OCR เฉพาะทาง — ระบบจึงรัน OCR เสมอเป็นค่าเริ่มต้น (เร็ว, แม่น, ไม่มีต้นทุนเพิ่มจากโมเดล) แล้วให้โมเดล VLM มาช่วยดูภาพรวม/บริบทที่ OCR ให้ไม่ได้ (เช่น “รูปนี้คือใบเสร็จร้านอะไร ดูจากโลโก้”) — สองอย่างเสริมกัน ไม่ใช่แข่งกัน

ลำดับการทำงาน: ตรวจสอบก่อนถึงจะยอมส่งภาพให้โมเดลเห็น

ตัว run() ออกแบบเป็นลำดับที่ตั้งใจมาก (คอมเมนต์ในซอร์สระบุว่าเป็นการแก้ตามแผน PLAN.md §9.3 โดยเฉพาะ): normalize/crop ภาพก่อน → OCR + ตรวจ QR บนสำเนาที่ normalize แล้ว → ปล่อยหน่วยความจำภาพความละเอียดเต็ม → แล้วค่อยเสียเวลา/หน่วยความจำ tiling และ encode เป็น frame สำหรับ VLM ทีหลังสุด

เหตุผลของลำดับนี้: ถ้า OCR หรือ QR ตรวจพบสิ่งที่ต้องบล็อก (ดูหัวข้อถัดไป) ระบบจะหยุดทันทีก่อนเสียทรัพยากรไป tiling/encode ภาพซึ่งเป็นขั้นตอนที่กินหน่วยความจำมากที่สุด — ตรวจสอบเรื่องความปลอดภัยก่อนเสมอ ก่อนลงทุนทรัพยากรกับงานหนัก

ป้องกันข้อมูลลับหลุดผ่านภาพ — สแกนทั้ง OCR และ QR

จุดที่คนมักมองข้าม: QR code สามารถมี access token ซ่อนอยู่ในตัวได้ แม้ OCR จะไม่เห็นตัวอักษรอะไรเลยในภาพนั้น ระบบจึงตรวจทั้งสองทาง แยกจากกัน:

  • ข้อความจาก OCR ผ่าน contains_secret_content() — ถ้าเจอ pattern คล้าย credential/token จะบล็อกไม่ส่งภาพต่อให้ vision model เลย
  • Payload ที่ decode ได้จาก QR code (ผ่าน cv2.QRCodeDetector) ก็ผ่านการตรวจแบบเดียวกันแยกต่างหาก

มีรายละเอียดที่ระมัดระวังเป็นพิเศษ: ถ้า QR detectorตรวจพบว่ามี QR code ในภาพ แต่ decode ค่าออกมาไม่ได้ ระบบจะถือว่าปลอดภัยไม่ได้เลย และบล็อกทันที แทนที่จะปล่อยผ่านเพราะ “อ่านไม่ออกก็ไม่รู้ว่ามีอะไร” — QR ที่ตรวจเจอแต่ decode ไม่ได้อาจเก็บ credential ที่ detector อ่านไม่สำเร็จก็ได้ ความเสี่ยงจึงต้องได้รับการปฏิบัติเหมือนกับเจอจริง

Path ต้องเป็น snapshot ที่ตรวจสอบแล้ว ไม่ใช่ path ต้นฉบับซ้ำ

ระบบอ่าน byte ของภาพเป็น snapshot ครั้งเดียวตอนต้น (ก่อน OCR) เพื่อป้องกันสถานการณ์ที่ไฟล์ต้นทางถูกแทนที่ระหว่างขั้นตอนการประมวลผล (เช่นไฟล์ถูกเขียนทับหลังผ่านการเช็คขนาด/ประเภทไปแล้ว) — สิ่งที่ถูกคิวไว้ให้ VLM เห็นจริงๆ คือสำเนาที่ผ่านการ OCR/QR-scan แล้วเท่านั้น ไม่ใช่ path ต้นฉบับที่อาจเปลี่ยนแปลงไปแล้วตอนโมเดลอ่านจริงในรอบถัดไป — และภาพที่คิวไว้เป็นแบบ per-turn เท่านั้น ถ้า session ขาดตอนกลางทาง ภาพเก่าจะไม่ถูกนำไปแนบผิดคำถามในรอบถัดไปโดยไม่ตั้งใจ (มีการล้าง snapshot ที่ค้างเกิน 1 ชั่วโมงด้วย)

Zoom และ region: ดูรายละเอียดเล็กในภาพได้

ถ้าข้อความในภาพเล็กเกินไป (เช่นตัวเลขในใบเสร็จ) โมเดลเรียก read_image ซ้ำได้พร้อมระบุ region (เช่น top-right, center) และ zoom (1-4 เท่า) เพื่อ crop เฉพาะส่วนนั้นมาขยายดู — reminder ที่แนบมากับผลลัพธ์ครั้งแรกจะบอกโมเดลตรงๆ ว่าให้เรียกซ้ำแบบนี้เฉพาะเมื่อข้อความอ่านไม่ชัดจริงๆ ไม่ใช่เรียกพร่ำเพรื่อ

Bonus: reconstruct ตารางจาก OCR โดยไม่ต้องพึ่งโมเดล

ถ้า OCR เจอกล่องข้อความที่จัดเรียงเป็นแถว/คอลัมน์ชัดเจน (เช่นใบเสร็จ, สเปรดชีต) ระบบจะพยายามประกอบกลับเป็นตาราง Markdown อัตโนมัติจากตำแหน่งของแต่ละกล่องข้อความ (จัดกลุ่มเป็นแถวตามตำแหน่งแนวตั้งที่ใกล้กัน, จัดคอลัมน์ตามช่วงแนวนอนที่ทับซ้อนกัน) มีเงื่อนไขระมัดระวังไม่ให้ทึกทักผิด เช่น เนื้อหาที่ดูเหมือนย่อหน้าเรียงข้างกัน (ไม่ใช่ตารางจริง) จะถูกปฏิเสธไม่ประกอบเป็นตาราง — ผลลัพธ์นี้แม่นยำกว่าให้โมเดลขนาดเล็กพยายาม “อ่านตาราง” จากภาพเองล้วนๆ

ทำไมเรื่องนี้ถึงสำคัญ

read_image แสดงให้เห็นวิธีคิดที่สอดคล้องกับ tool อื่นๆ ทั้งหมดของ AGENT LITE: ใช้เครื่องมือเฉพาะทางที่แม่นยำกว่า (OCR, QR detector) แทนที่จะพึ่งโมเดลขนาดเล็กทำทุกอย่างเอง และตรวจสอบความปลอดภัยก่อนเสมอ ก่อนจะลงทุนทรัพยากรหรือปล่อยข้อมูลออกไป — เป็นแพทเทิร์นเดียวกับที่เห็นซ้ำในทุก tool ของ AGENT LITE ตลอดทั้งชุดบทความนี้

อ่านเพิ่มเติม

ความคิดเห็น

กำลังโหลดความคิดเห็น...