Files
lcbp3/specs/200-fullstacks/233-ai-model-ocr-runner-management/spec.md
T
admin bc754e66fd
CI / CD Pipeline / build (push) Successful in 4m52s
CI / CD Pipeline / deploy (push) Successful in 17m39s
690602:0957 ADR-033-233 #01
2026-06-02 09:57:48 +07:00

13 KiB

Feature Specification: AI Model & OCR Runner Management

Feature Branch: 233-ai-model-ocr-runner-management
Created: 2026-06-02
Status: Draft
Input: Refactor and fix issues in AI Model Management & OCR Sandbox Runner (ADR-033 compliant).


Overview

เอกสารข้อกำหนดคุณสมบัติ (Feature Specification) นี้ครอบคลุมการปรับปรุงระบบความปลอดภัย ประสิทธิภาพ และการทำงานของ AI Admin Console และ OCR Sandbox Runner ตามสถาปัตยกรรม ADR-033 เพื่อแก้ไขปัญหา:

  1. การตรวจสอบและยืนยันการโหลดโมเดลภาษาขนาดใหญ่ (LLM) ในระบบ Ollama บนเครื่อง Desk-5439 ในลักษณะ Synchronous และป้องกันการตอบกลับผลลัพธ์สำเร็จล่วงหน้า
  2. การปรับปรุง VRAM Monitor (OOM Guard Fallback) ให้มีความทนทาน (Resilience) ไม่บล็อกผู้ใช้งานเมื่อระบบเช็คข้อมูลไม่ได้
  3. การสลับและปรับลำดับการทำวิจัย OCR Sandbox Runner ในแท็บแผงควบคุมให้ถูกต้องเหมาะสมตามจริง และสลับมาแสดงเป็นหน้าแรก
  4. การแมปตัวเลือกโมเดล Typhoon OCR ทั้ง 2 เวอร์ชัน (v1.0 7.5GB และ v1.5 3.2GB) ไปยังโมเดลจริงของ Ollama และการเพิ่ม API endpoints ที่ตกหล่นใน Controller ของฝั่ง Backend

User Scenarios & Testing (mandatory)

User Story 1 - Ollama Real-time Model Loading & Pre-verification (Priority: P1)

ในฐานะ Superadmin เมื่อฉันทำการเปลี่ยน "โมเดล AI ที่ใช้งานอยู่ (Global)" ผ่าน AI Model Management Dropdown ฉันต้องการให้ระบบทำการติดต่อ Ollama เพื่อยืนยันว่าโมเดลนั้นได้รับการดาวน์โหลดแล้วจริงในเครื่อง Desk-5439 และจะสั่งประมวลผลโหลดเข้าหน่วยความจำ GPU (keep_alive: -1) ทันทีก่อนบันทึกสำเร็จลงฐานข้อมูล หากพบว่าไม่มีโมเดล หรือไม่สามารถโหลดขึ้น GPU ได้สำเร็จ (เช่น VRAM OOM หรือ Timeout 30s) ระบบจะต้องปฏิเสธคำขอและแสดงข้อผิดพลาดที่ชัดเจน ไม่เขียนทับสถานะใน DB

Why this priority: เป็นคุณสมบัติสำคัญที่สุดในการรักษาสถานะความสอดคล้องระหว่างแอปพลิเคชันและ Ollama (Data Integrity) ป้องกันข้อผิดพลาดตอนรันจริง

Independent Test: สามารถทดสอบโดยการสลับโมเดล AI ในระบบ และตรวจสอบว่า Ollama ps มีโมเดลแสดงอยู่จริงและไม่สามารถเลือกเปลี่ยนเป็นโมเดลที่ยังไม่ได้ดาวน์โหลดได้

Acceptance Scenarios:

  1. Given ระบบทำงานปกติ และมีโมเดล gemma4:e4b ติดตั้งอยู่, When แอดมินกดเลือกเปลี่ยนโมเดลหลักเป็น gemma4:e4b, Then ระบบ NestJS backend จะติดต่อ Ollama /api/generate เพื่อ pre-load โมเดล เมื่อสำเร็จจะบันทึกสถานะเปลี่ยนโมเดลลง DB และแจ้งเตือนแอดมินว่าสำเร็จ
  2. Given มีความจุ VRAM ไม่พอ หรือโมเดลที่เลือกไม่มีติดตั้งอยู่ใน Ollama, When แอดมินพยายามกดเปลี่ยนโมเดลหลัก, Then ระบบจะปฏิเสธคำขอ สปริงข้อผิดพลาด (BadRequestException / BusinessException) และแจ้งแอดมินบนหน้าเว็บโดยไม่มีการเปลี่ยนการตั้งค่าในฐานข้อมูล

User Story 2 - OCR Engine Dynamic Sandbox Run with Precise Visual Labels (Priority: P1)

ในฐานะ Superadmin เมื่อฉันเข้าสู่หน้า OCR Sandbox Runner ฉันต้องการให้แท็บการทำงานนี้แสดงขึ้นเป็นตัวเลือกแรกสุดตามลำดับการทำงานจริง (แสดงก่อน Prompt Editor) และมี dropdown ตัวเลือก OCR Engine ที่ถูกต้องตามขนาด:

  • Auto (Current Baseline)
  • Tesseract OCR
  • typhoon-ocr1.5-3b 3.2GB
  • typhoon-ocr-3b 7.5GB และเมื่อฉันอัปโหลดไฟล์ PDF ระบบจะสามารถส่งคำขอและเรียกโมเดล Ollama ได้ถูกต้องตามชื่อโมเดลจริง (scb10x/typhoon-ocr1.5-3b หรือ scb10x/typhoon-ocr-3b)

Why this priority: มีผลโดยตรงต่อการทดสอบและวิจัย OCR ของแอดมิน เพื่อความสอดคล้องและความถูกต้องของผลลัพธ์

Independent Test: Superadmin สามารถอัปโหลด PDF เลือก typhoon-ocr1.5-3b 3.2GB หรือ typhoon-ocr-3b 7.5GB และดูข้อความที่สกัดออกมาได้ โดยตรวจสอบ log ในฝั่ง sidecar ว่าโหลดโมเดลถูกตัว

Acceptance Scenarios:

  1. Given ผู้ใช้เปิดแท็บ OCR Sandbox, When ดูที่เมนู, Then แท็บ OCR Sandbox Runner จะต้องแสดงขึ้นมาก่อนและเป็น default แทน Prompt Editor
  2. Given แอดมินเลือกเอนจิน typhoon-ocr-3b 7.5GB, When กดรัน Step 1, Then ฝั่ง backend จะเรียก sidecar API /ocr-upload และระบุ engine = typhoon-ocr-3b ซึ่ง sidecar จะเรียก Ollama ด้วยโมเดล scb10x/typhoon-ocr-3b

User Story 3 - Resilient VRAM OOM Guard Fallback (Priority: P2)

ในฐานะ Superadmin เมื่อฉันตรวจสอบสถานะสุขภาพในหน้า Overview & Health และ Ollama API ทำการแจ้งผลลัพธ์ปกติแต่ไม่สามารถเข้าถึง /api/ps ได้ (เช่น รุ่นไม่รองรับ) ฉันต้องการให้ระบบ VRAM GPU Monitor ไม่แครชหรือแจ้งสถานะ OOM Guard ตลอดเวลา และสามารถทำงานสืบค้น RAG Sandbox ต่อได้

Why this priority: เพิ่มความทนทานต่อการขัดข้องทางเครือข่ายและการเข้าถึง API ในเวอร์ชันที่แตกต่างกัน

Independent Test: จำลองให้ endpoint /api/ps คืนค่า 404 และตรวจสอบว่าแผงควบคุม VRAM Monitor ยังคงรายงานสถานะพร้อมโหลดโมเดลได้ (มี Free VRAM สมมติ)

Acceptance Scenarios:

  1. Given ระบบไม่สามารถดึง /api/ps ได้, When ระบบคำนวณสถานะสุขภาพ AI, Then ระบบจะคืนค่า free VRAM สมมติและตั้ง hasCapacity = true พร้อมทั้งมี log warning เพื่อเตือนแต่ไม่ล็อกระบบ

Edge Cases

  • Ollama Timeout: เกิดขึ้นเมื่อ Ollama โหลดโมเดลช้าเกิน 30 วินาที -> ระบบจะทำการโยน GatewayTimeout หรือ SystemException และให้ผู้ใช้สลับเอนจินหรือโหลดใหม่อีกครั้ง
  • Model Name Mismatch: หากโมเดลใน DB กับโมเดลที่เรียกใช้ใน Ollama พิมพ์แตกต่างกันเล็กน้อย (เช่น ตัวพิมพ์เล็ก/ใหญ่ หรือเวอร์ชันย่อย) -> ระบบจะใช้วิธีเช็ค prefix ใน /api/tags ในการแก้ปัญหา

Requirements (mandatory)

Functional Requirements

  • FR-001: ระบบ MUST ให้ผู้ใช้เลือกและจัดการ OCR Engine หลักผ่าน API GET /ai/ocr-engines และ POST /ai/ocr-engines/:engineId/select โดยแผงควบคุมจะดึงข้อมูลได้สมบูรณ์และแสดงผลในเมนู
  • FR-002: ระบบ MUST ทำการตรวจสอบความพร้อมของโมเดลก่อนเปลี่ยนโมเดลหลัก (Global Active Model) โดยทำการ Synchronous Pre-loading ใน Ollama และคืนสถานะข้อผิดพลาดหากไม่พบโมเดล
  • FR-003: ระบบ MUST ปรับปรุง /api/ps fallback ใน VramMonitorService ให้กู้คืนสถานะเป็น hasCapacity = true เสมอเมื่อเรียก API ตรวจสอบไม่ได้ เพื่อไม่ให้เกิดภาวะ OOM Guard ค้างถาวร
  • FR-004: ระบบ MUST ดึงข้อมูลโมเดลที่โหลดอยู่บนหน่วยความจำ GPU จริง ๆ ผ่าน /api/ps ไปแสดงผลบนแผงควบคุม Ollama AI Engine "โมเดลที่โหลดอยู่"
  • FR-005: ระบบ MUST ปรับเมนู OCR Sandbox ให้แท็บ "OCR Sandbox" แสดงและเริ่มทำงานเป็นแท็บแรกแทน "Prompt Editor"
  • FR-006: ระบบ MUST ให้ตัวเลือกเอนจิน OCR Sandbox มีชื่อตัวเลือกดังนี้:
    • Auto (Current Baseline)
    • Tesseract OCR
    • typhoon-ocr1.5-3b 3.2GB
    • typhoon-ocr-3b 7.5GB
  • FR-007: ระบบ MUST แมปเอนจิน typhoon-ocr1.5-3b ไปยังโมเดลจริง scb10x/typhoon-ocr1.5-3b และ typhoon-ocr-3b ไปยัง scb10x/typhoon-ocr-3b ใน sidecar app.py

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: แอดมินสามารถสลับ OCR Engine และดึงข้อมูลสถานะได้สำเร็จโดยไม่เกิดข้อผิดพลาด 404
  • SC-002: การตรวจสอบโมเดลที่โหลดอยู่จริงของ Ollama ทำงานได้ถูกต้องตามผลลัพธ์ของ ollama ps ในแบบเรียลไทม์
  • SC-003: ระบบ VRAM Monitor มี Uptime 100% โดยไม่มีข้อผิดพลาด OOM Guard ค้างเมื่อ Ollama ทำงานปกติ
  • SC-004: การเรียงลำดับ sub-tabs และการแสดงผล OCR Sandbox และ Dropdown ทำงานได้ตามลำดับจริงที่ถูกต้อง