10 KiB
10 KiB
Data Model: Intent Classification System
Feature: 224-intent-classification
Date: 2026-05-19
Spec: spec.md | Research: research.md
Entity Overview
┌─────────────────────┐ ┌─────────────────────┐
│ IntentDefinition │ 1:N │ IntentPattern │
├─────────────────────┤ ├─────────────────────┤
│ publicId (UUID) │──────▶│ publicId (UUID) │
│ intentCode (PK) │ │ intentCode (FK) │
│ description_th │ │ patternType │
│ description_en │ │ patternValue │
│ category │ │ language │
│ isActive │ │ priority │
│ createdAt │ │ isActive │
│ updatedAt │ │ createdAt │
└─────────────────────┘ │ updatedAt │
└─────────────────────┘
Entity: IntentDefinition
Table: ai_intent_definitions
Purpose: เก็บข้อมูล Intent หลักที่ระบบรองรับ
Attributes
| Attribute | Type | Constraints | Description |
|---|---|---|---|
| id | INT | PK, AUTO_INCREMENT | Internal ID (ไม่ expose) |
| publicId | UUID | NOT NULL, DEFAULT UUID() | Public UUIDv7 (API response) |
| intentCode | VARCHAR(50) | NOT NULL, UNIQUE | เช่น RAG_QUERY, GET_RFA, FALLBACK |
| descriptionTh | VARCHAR(255) | NOT NULL | คำอธิบายภาษาไทย |
| descriptionEn | VARCHAR(255) | NOT NULL | คำอธิบายภาษาอังกฤษ |
| category | ENUM | NOT NULL | read, suggest, utility |
| isActive | BOOLEAN | NOT NULL, DEFAULT TRUE | เปิดใช้งานหรือไม่ |
| createdAt | TIMESTAMP | NOT NULL, DEFAULT CURRENT_TIMESTAMP | |
| updatedAt | TIMESTAMP | NOT NULL, DEFAULT CURRENT_TIMESTAMP ON UPDATE |
Indexes
PRIMARY KEY (id)
UNIQUE KEY uk_intent_code (intentCode)
INDEX idx_intent_active (isActive, category)
Validation Rules
intentCode: ตัวพิมพ์ใหญ่, underscore, ตัวเลข — format:[A-Z][A-Z0-9_]*category: ต้องเป็นread,suggest, หรือutilitydescriptionThและdescriptionEn: ห้ามว่าง
Entity: IntentPattern
Table: ai_intent_patterns
Purpose: เก็บ Pattern (keyword/regex) สำหรับ Pattern Matching Layer
Attributes
| Attribute | Type | Constraints | Description |
|---|---|---|---|
| id | INT | PK, AUTO_INCREMENT | Internal ID (ไม่ expose) |
| publicId | UUID | NOT NULL, DEFAULT UUID() | Public UUIDv7 (API response) |
| intentCode | VARCHAR(50) | NOT NULL, FK | อ้างอิง IntentDefinition |
| language | ENUM | NOT NULL, DEFAULT 'any' | th, en, any |
| patternType | ENUM | NOT NULL, DEFAULT 'keyword' | keyword, regex |
| patternValue | VARCHAR(255) | NOT NULL | ค่า pattern (keyword หรือ regex) |
| priority | INT | NOT NULL, DEFAULT 100 | ลำดับการตรวจสอบ (ต่ำ = ตรวจก่อน) |
| isActive | BOOLEAN | NOT NULL, DEFAULT TRUE | เปิดใช้งานหรือไม่ |
| createdAt | TIMESTAMP | NOT NULL, DEFAULT CURRENT_TIMESTAMP | |
| updatedAt | TIMESTAMP | NOT NULL, DEFAULT CURRENT_TIMESTAMP ON UPDATE |
Indexes
PRIMARY KEY (id)
UNIQUE KEY uk_pattern_public_id (publicId)
INDEX idx_intent_code (intentCode)
INDEX idx_intent_active_priority (isActive, priority ASC)
CONSTRAINT fk_intent_pattern_definition
FOREIGN KEY (intentCode) REFERENCES ai_intent_definitions(intentCode)
ON UPDATE CASCADE ON DELETE RESTRICT
Validation Rules
patternType=regex→ ต้อง validate ว่าเป็น regex ที่ valid (ใช้new RegExp()ใน try-catch)priority: ต่ำ = สำคัญกว่า (ตรวจก่อน) — แนะนำให้ใช้ 10, 20, 50, 100language:th: ใช้กับคำถามภาษาไทยเท่านั้นen: ใช้กับคำถามภาษาอังกฤษเท่านั้นany: ใช้กับทุกภาษา
Value Objects / DTOs
ClassificationResult (Response)
interface ClassificationResult {
intentCode: string; // เช่น 'RAG_QUERY', 'GET_RFA'
confidence: number; // 0.0 - 1.0
method: 'pattern' | 'llm_fallback' | 'semaphore_overflow' | 'llm_error';
params?: Record<string, any>; // Optional extracted params
latencyMs: number; // รวมทั้งหมด
}
ClassificationInput (Request)
interface ClassificationInput {
query: string; // คำถามจาก user (trim, max 200 chars)
projectPublicId?: string; // Context project (optional)
userPublicId?: string; // Context user (optional)
currentDocumentId?: string; // Context document ที่เปิดอยู่ (optional)
}
Enums
IntentCategory
enum IntentCategory {
READ = 'read', // ดึงข้อมูล: RAG_QUERY, GET_RFA, etc.
SUGGEST = 'suggest', // แนะนำ: SUGGEST_METADATA, SUGGEST_ACTION
UTILITY = 'utility' // อื่น ๆ: FALLBACK
}
PatternType
enum PatternType {
KEYWORD = 'keyword', // case-insensitive includes()
REGEX = 'regex' // RegExp.test()
}
PatternLanguage
enum PatternLanguage {
TH = 'th', // ภาษาไทย
EN = 'en', // ภาษาอังกฤษ
ANY = 'any' // ทุกภาษา
}
SQL Schema Delta (ADR-009)
ไฟล์: specs/03-Data-and-Storage/deltas/03-add-intent-classification.sql
-- Delta 03: Add Intent Classification Tables (ADR-024)
-- Created: 2026-05-19
-- Feature: 224-intent-classification
-- Intent Definitions Table
CREATE TABLE IF NOT EXISTS ai_intent_definitions (
id INT AUTO_INCREMENT PRIMARY KEY,
public_id UUID NOT NULL DEFAULT UUID(),
intent_code VARCHAR(50) NOT NULL,
description_th VARCHAR(255) NOT NULL,
description_en VARCHAR(255) NOT NULL,
category ENUM('read', 'suggest', 'utility') NOT NULL,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_intent_code (intent_code),
INDEX idx_intent_active (is_active, category)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Intent Patterns Table
CREATE TABLE IF NOT EXISTS ai_intent_patterns (
id INT AUTO_INCREMENT PRIMARY KEY,
public_id UUID NOT NULL DEFAULT UUID(),
intent_code VARCHAR(50) NOT NULL,
language ENUM('th', 'en', 'any') NOT NULL DEFAULT 'any',
pattern_type ENUM('keyword', 'regex') NOT NULL DEFAULT 'keyword',
pattern_value VARCHAR(255) NOT NULL,
priority INT NOT NULL DEFAULT 100,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_pattern_public_id (public_id),
INDEX idx_intent_code (intent_code),
INDEX idx_intent_active_priority (is_active, priority ASC),
CONSTRAINT fk_intent_pattern_definition
FOREIGN KEY (intent_code) REFERENCES ai_intent_definitions(intent_code)
ON UPDATE CASCADE ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Seed Data (12 Intent Definitions)
-- Seed Intent Definitions (v1)
INSERT INTO ai_intent_definitions (intent_code, description_th, description_en, category) VALUES
-- Read Intents
('RAG_QUERY', 'ถามคำถามธรรมชาติ ตอบจาก vector + doc context', 'Natural language query from vector DB + document context', 'read'),
('GET_RFA', 'ดึง RFA ตาม filter', 'Get RFA by filters', 'read'),
('GET_DRAWING', 'ดึง Drawing revision', 'Get Drawing revision', 'read'),
('GET_TRANSMITTAL', 'ดึง Transmittal', 'Get Transmittal', 'read'),
('GET_CORRESPONDENCE', 'ดึง Correspondence ทั่วไป', 'Get Correspondence', 'read'),
('GET_CIRCULATION', 'ดึง Circulation', 'Get Circulation', 'read'),
('GET_RFA_DRAWINGS', 'ดึง Drawings ที่ผูกกับ RFA', 'Get Drawings linked to RFA', 'read'),
('SUMMARIZE_DOCUMENT', 'สรุปเอกสารที่เปิดอยู่', 'Summarize current document', 'read'),
('LIST_OVERDUE', 'รายการ cross-entity ที่เกินกำหนด', 'List overdue items across entities', 'read'),
-- Suggest Intents
('SUGGEST_METADATA', 'แนะนำ metadata สำหรับเอกสารที่อัปโหลด', 'Suggest metadata for uploaded document', 'suggest'),
('SUGGEST_ACTION', 'แจ้งเตือนว่าควรทำอะไรต่อ', 'Suggest next actions', 'suggest'),
-- Utility Intents
('FALLBACK', 'ไม่เข้า intent ไหน / ไม่เกี่ยวกับระบบ', 'No matching intent / unrelated to system', 'utility');
Relationships Summary
| Relationship | Type | Description |
|---|---|---|
| IntentDefinition → IntentPattern | 1:N | Intent หนึ่งรายการมีได้หลาย Patterns |
| IntentPattern → IntentDefinition | N:1 | Pattern อ้างอิง Intent หนึ่งรายการ (FK) |
Performance Considerations
- Query Pattern หลัก:
SELECT * FROM ai_intent_patterns WHERE is_active = TRUE ORDER BY priority ASC→ ใช้ Indexidx_intent_active_priority - Cache Strategy: Redis เก็บผล Query ข้างต้น → ลด DB Load 70-80%
- Size Estimation:
- Intent Definitions: ~20 rows (v1 มี 12, อนาคตเพิ่มได้)
- Intent Patterns: ~100-500 rows (depends on Admin configuration)
- Cache Size: < 100KB JSON