451 lines
12 KiB
YAML
451 lines
12 KiB
YAML
openapi: 3.0.3
|
|
info:
|
|
title: Intent Classification API
|
|
description: API สำหรับ Intent Classification ตาม ADR-024 (Hybrid Pattern First → LLM Fallback)
|
|
version: 1.0.0
|
|
contact:
|
|
name: NAP-DMS Development Team
|
|
|
|
servers:
|
|
- url: http://localhost:3001/api
|
|
description: Local Development
|
|
- url: https://api.nap-dms.work/api
|
|
description: Production
|
|
|
|
tags:
|
|
- name: Intent Classification
|
|
description: แปลงคำถามธรรมชาติ → Server-side Intent
|
|
- name: Intent Management
|
|
description: Admin API สำหรับจัดการ Intent Definitions และ Patterns
|
|
|
|
paths:
|
|
# === Intent Classification ===
|
|
/ai/intent/classify:
|
|
post:
|
|
summary: Classify User Query
|
|
description: |
|
|
แปลงคำถามธรรมชาติจาก User เป็น Server-side Intent enum
|
|
ใช้ Hybrid Strategy: Pattern First → LLM Fallback
|
|
tags: [Intent Classification]
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ClassifyQueryRequest'
|
|
example:
|
|
query: "สรุปเอกสารนี้"
|
|
projectPublicId: "019505a1-7c3e-7000-8000-abc123def456"
|
|
responses:
|
|
'200':
|
|
description: Classification successful
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ClassificationResult'
|
|
examples:
|
|
pattern-match:
|
|
summary: Pattern Match (cache hit)
|
|
value:
|
|
intentCode: "SUMMARIZE_DOCUMENT"
|
|
confidence: 1.0
|
|
method: "pattern"
|
|
latencyMs: 8
|
|
llm-fallback:
|
|
summary: LLM Fallback
|
|
value:
|
|
intentCode: "GET_RFA"
|
|
confidence: 0.85
|
|
method: "llm_fallback"
|
|
params:
|
|
contractPublicId: "019505a1-7c3e-7000-8000-xyz789abc123"
|
|
latencyMs: 1250
|
|
fallback:
|
|
summary: No Match (FALLBACK)
|
|
value:
|
|
intentCode: "FALLBACK"
|
|
confidence: 0.0
|
|
method: "llm_fallback"
|
|
latencyMs: 2100
|
|
'400':
|
|
description: Invalid request (missing query)
|
|
'401':
|
|
description: Unauthorized
|
|
'429':
|
|
description: Too many requests (rate limit)
|
|
|
|
# === Intent Definitions (Admin) ===
|
|
/admin/ai/intent-definitions:
|
|
get:
|
|
summary: List Intent Definitions
|
|
description: ดึงรายการ Intent Definitions ทั้งหมด
|
|
tags: [Intent Management]
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: category
|
|
in: query
|
|
schema:
|
|
type: string
|
|
enum: [read, suggest, utility]
|
|
description: Filter by category
|
|
- name: isActive
|
|
in: query
|
|
schema:
|
|
type: boolean
|
|
description: Filter by active status
|
|
responses:
|
|
'200':
|
|
description: List of intent definitions
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/IntentDefinition'
|
|
|
|
post:
|
|
summary: Create Intent Definition
|
|
description: สร้าง Intent Definition ใหม่ (System Admin only)
|
|
tags: [Intent Management]
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreateIntentDefinitionRequest'
|
|
responses:
|
|
'201':
|
|
description: Created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/IntentDefinition'
|
|
'409':
|
|
description: Intent code already exists
|
|
|
|
/admin/ai/intent-definitions/{intentCode}:
|
|
parameters:
|
|
- name: intentCode
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
example: "GET_RFA"
|
|
|
|
get:
|
|
summary: Get Intent Definition
|
|
tags: [Intent Management]
|
|
security:
|
|
- bearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: Intent definition found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/IntentDefinition'
|
|
'404':
|
|
description: Intent not found
|
|
|
|
patch:
|
|
summary: Update Intent Definition
|
|
tags: [Intent Management]
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/UpdateIntentDefinitionRequest'
|
|
responses:
|
|
'200':
|
|
description: Updated
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/IntentDefinition'
|
|
|
|
# === Intent Patterns (Admin) ===
|
|
/admin/ai/intent-definitions/{intentCode}/patterns:
|
|
parameters:
|
|
- name: intentCode
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
|
|
get:
|
|
summary: List Patterns for Intent
|
|
tags: [Intent Management]
|
|
security:
|
|
- bearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: List of patterns
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/IntentPattern'
|
|
|
|
post:
|
|
summary: Create Pattern for Intent
|
|
description: เพิ่ม Pattern ใหม่สำหรับ Intent นี้
|
|
tags: [Intent Management]
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreateIntentPatternRequest'
|
|
responses:
|
|
'201':
|
|
description: Created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/IntentPattern'
|
|
'400':
|
|
description: Invalid regex pattern
|
|
|
|
/admin/ai/intent-patterns/{publicId}:
|
|
parameters:
|
|
- name: publicId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
|
|
get:
|
|
summary: Get Pattern
|
|
tags: [Intent Management]
|
|
security:
|
|
- bearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: Pattern found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/IntentPattern'
|
|
|
|
patch:
|
|
summary: Update Pattern
|
|
tags: [Intent Management]
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/UpdateIntentPatternRequest'
|
|
responses:
|
|
'200':
|
|
description: Updated
|
|
|
|
delete:
|
|
summary: Delete Pattern (soft delete)
|
|
tags: [Intent Management]
|
|
security:
|
|
- bearerAuth: []
|
|
responses:
|
|
'204':
|
|
description: Deleted
|
|
|
|
components:
|
|
securitySchemes:
|
|
bearerAuth:
|
|
type: http
|
|
scheme: bearer
|
|
bearerFormat: JWT
|
|
|
|
schemas:
|
|
# === Classification ===
|
|
ClassifyQueryRequest:
|
|
type: object
|
|
required: [query]
|
|
properties:
|
|
query:
|
|
type: string
|
|
maxLength: 200
|
|
description: คำถามจาก user (trim แล้ว)
|
|
example: "สรุปเอกสารนี้"
|
|
projectPublicId:
|
|
type: string
|
|
format: uuid
|
|
description: Context project
|
|
userPublicId:
|
|
type: string
|
|
format: uuid
|
|
description: Context user
|
|
currentDocumentId:
|
|
type: string
|
|
format: uuid
|
|
description: Document ที่เปิดอยู่ (ถ้ามี)
|
|
|
|
ClassificationResult:
|
|
type: object
|
|
properties:
|
|
intentCode:
|
|
type: string
|
|
description: Intent ที่จำแนกได้
|
|
example: "SUMMARIZE_DOCUMENT"
|
|
confidence:
|
|
type: number
|
|
minimum: 0
|
|
maximum: 1
|
|
description: ความมั่นใจ (1.0 = pattern match)
|
|
example: 1.0
|
|
method:
|
|
type: string
|
|
enum: [pattern, llm_fallback, semaphore_overflow, llm_error]
|
|
description: วิธีที่ใช้จำแนก
|
|
params:
|
|
type: object
|
|
additionalProperties: true
|
|
description: Parameters ที่สกัดได้ (optional)
|
|
latencyMs:
|
|
type: integer
|
|
description: เวลาที่ใช้ทั้งหมด (ms)
|
|
example: 8
|
|
|
|
# === Intent Definition ===
|
|
IntentDefinition:
|
|
type: object
|
|
properties:
|
|
publicId:
|
|
type: string
|
|
format: uuid
|
|
intentCode:
|
|
type: string
|
|
example: "GET_RFA"
|
|
descriptionTh:
|
|
type: string
|
|
example: "ดึง RFA ตาม filter"
|
|
descriptionEn:
|
|
type: string
|
|
example: "Get RFA by filters"
|
|
category:
|
|
type: string
|
|
enum: [read, suggest, utility]
|
|
isActive:
|
|
type: boolean
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
updatedAt:
|
|
type: string
|
|
format: date-time
|
|
|
|
CreateIntentDefinitionRequest:
|
|
type: object
|
|
required: [intentCode, descriptionTh, descriptionEn, category]
|
|
properties:
|
|
intentCode:
|
|
type: string
|
|
pattern: '^[A-Z][A-Z0-9_]*$'
|
|
example: "GET_CONTRACT"
|
|
descriptionTh:
|
|
type: string
|
|
maxLength: 255
|
|
descriptionEn:
|
|
type: string
|
|
maxLength: 255
|
|
category:
|
|
type: string
|
|
enum: [read, suggest, utility]
|
|
|
|
UpdateIntentDefinitionRequest:
|
|
type: object
|
|
properties:
|
|
descriptionTh:
|
|
type: string
|
|
maxLength: 255
|
|
descriptionEn:
|
|
type: string
|
|
maxLength: 255
|
|
isActive:
|
|
type: boolean
|
|
|
|
# === Intent Pattern ===
|
|
IntentPattern:
|
|
type: object
|
|
properties:
|
|
publicId:
|
|
type: string
|
|
format: uuid
|
|
intentCode:
|
|
type: string
|
|
language:
|
|
type: string
|
|
enum: [th, en, any]
|
|
patternType:
|
|
type: string
|
|
enum: [keyword, regex]
|
|
patternValue:
|
|
type: string
|
|
maxLength: 255
|
|
priority:
|
|
type: integer
|
|
description: ลำดับการตรวจสอบ (ต่ำ = ตรวจก่อน)
|
|
isActive:
|
|
type: boolean
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
updatedAt:
|
|
type: string
|
|
format: date-time
|
|
|
|
CreateIntentPatternRequest:
|
|
type: object
|
|
required: [patternType, patternValue]
|
|
properties:
|
|
language:
|
|
type: string
|
|
enum: [th, en, any]
|
|
default: any
|
|
patternType:
|
|
type: string
|
|
enum: [keyword, regex]
|
|
patternValue:
|
|
type: string
|
|
maxLength: 255
|
|
priority:
|
|
type: integer
|
|
default: 100
|
|
|
|
UpdateIntentPatternRequest:
|
|
type: object
|
|
properties:
|
|
language:
|
|
type: string
|
|
enum: [th, en, any]
|
|
patternType:
|
|
type: string
|
|
enum: [keyword, regex]
|
|
patternValue:
|
|
type: string
|
|
maxLength: 255
|
|
priority:
|
|
type: integer
|
|
isActive:
|
|
type: boolean
|