# Momentry Core 多維度自然語言搜尋設計文檔

**版本**: V1.0
**日期**: 2026-04-10
**狀態**: 設計階段

---

## 1. 概述

本設計文檔旨在定義 Momentry Core 的**多維度自然語言搜尋 (Multi-Dimensional Semantic Search)** 系統架構與實施規範。該系統旨在突破傳統關鍵詞匹配的限制，通過解析用戶的「人事時地物」(5W1H) 意圖，結合多模態數據 (ASR, YOLO, Pose, Scene, Face)，實現高精度的語義檢索。

### 1.1 設計原則
1. **模組化 (Modularity)**: 搜尋功能作為獨立的 `Search Processor` 模塊，依賴但不侵入其他數據生產模塊 (如 Pose, ASR)。
2. **多模態融合 (Multi-Modal Fusion)**: 結合結構化數據 (SQL 過濾) 與非結構化向量數據 (Vector 檢索)。
3. **本地優先 (Local First)**: 核心解析與檢索邏輯盡可能在本地完成，僅 LLM 意圖解析可調用雲端或本地 LLM。

---

## 2. 搜尋維度定義 (5W1H Schema)

我們將用戶的自然語言查詢解析為以下結構化維度：

### 2.1 人 (Person / Who)
基於 `person_identities` 表及 `face` / `pose` / `asrx` 分析結果擴展。

| 屬性 | 數據類型 | 獲取來源 | 示例值 | 備註 |
| :--- | :--- | :--- | :--- | :--- |
| **性別** | `Enum` | VLM / 推斷 | `male`, `female` | |
| **年齡段** | `Enum` | VLM / 推斷 | `child`, `teen`, `young`, `middle`, `senior` | |
| **體型** | `Enum` | Pose (骨架寬高比) | `slim`, `average`, `muscular`, `heavy` | |
| **五官特徵** | `String[]` | VLM / Face | `["glasses", "beard", "long_hair"]` | |
| **表情** | `String[]` | Face / VLM | `["smiling", "angry", "crying"]` | |
| **服裝** | `String[]` | YOLO / VLM | `["red_shirt", "suit", "helmet"]` | |
| **動作/手勢** | `String[]` | **Pose Analyzer** | `["waving", "pointing", "hands_up", "fighting"]` | 核心新增 |
| **戲內角色** | `String` | 元數據 / 手動 | "Detective", "Doctor" | |
| **演員/真實身份** | `String` | 註冊資料庫 | "Tom Hanks", "User_001" | |
| **聲紋特徵** | `Enum` | ASRX | `deep_male`, `high_female` | |

### 2.2 事 (Event / Action / What)
基於 `ASR` (語音語義) 和 `Pose Analyzer` (行為語義)。

* **語音內容**: "他在解釋量子力學" -> 向量檢索 ASR 文本。
* **視覺行為**: "他在跑步", "兩人在擁抱" -> 檢索 `pose_analysis` 標籤或向量。

### 2.3 時 (Time / When)
基於 `chunks` 的時間戳。

* **絕對時間**: `10:05 - 10:15`。
* **相對時間**: "最後 5 分鐘", "剛開始"。

### 2.4 地 (Location / Where)
基於 `Scene` (Places365) 分類結果。

* **標籤**: "beach", "office", "living_room"。
* **映射**: 用戶說 "戶外" -> 映射為 `["beach", "forest", "street", ...]`。

### 2.5 物 (Object / Which)
基於 `YOLO` (物件檢測) 和 `OCR` (文字識別)。

* **物件**: `car`, `dog`, `knife`。
* **文字**: 路牌、標題中的關鍵詞。

---

## 3. 系統架構

### 3.1 數據流向圖

```mermaid
graph TD
    User[用戶自然語言查詢] --> API[API Gateway]
    API --> SearchProc[Search Processor]
    
    subgraph "Search Processor (Python)"
        Parser[Intent Parser (LLM)]
        Translator[Query Translator]
        Executor[Search Executor]
        
        Parser -->|JSON 結構化| Translator
        Translator -->|SQL + Vector Query| Executor
    end

    Executor -->|Filter: Who, Where, Object| PG[(PostgreSQL)]
    Executor -->|Search: Event (Text/Action)| Vec[(Qdrant / pgvector)]
    
    subgraph "Data Producers"
        PoseProc[Pose Analyzer Processor] -.->|Pose Tags| PG
        FaceProc[Face Processor] -.->|Face Attributes| PG
        ASRProc[ASR Processor] -.->|Transcript| PG
    end
    
    PG -->|Results| Executor
    Vec -->|Results| Executor
    Executor -->|Aggregated JSON| API
```

### 3.2 模組職責
1. **Pose Analyzer Processor**: 負責讀取 Pose 座標與 YOLO 數據，生成行為標籤 (Tags)，寫入數據庫。
2. **Search Processor**: 負責將自然語言轉為查詢語句並執行檢索。

---

## 4. 資料庫 Schema 擴展

為支持多維度搜尋，需擴展現有表結構。

### 4.1 擴展 `person_identities` (增加屬性 JSONB)
```sql
ALTER TABLE person_identities 
ADD COLUMN IF NOT EXISTS attributes JSONB DEFAULT '{}';

-- 建立 GIN 索引加速屬性搜索
CREATE INDEX IF NOT EXISTS idx_person_attrs ON person_identities USING GIN (attributes);
```
*示例數據*: `{"gender": "male", "age": "middle", "clothing": ["suit"], "pose_action": ["standing"]}`

### 4.2 擴展 `chunks` (增加行為標籤與語義向量)
```sql
ALTER TABLE chunks 
ADD COLUMN IF NOT EXISTS action_tags TEXT[] DEFAULT '{}',
ADD COLUMN IF NOT EXISTS scene_tags TEXT[] DEFAULT '{}',
ADD COLUMN IF NOT EXISTS object_tags TEXT[] DEFAULT '{}';

-- 使用數組索引加速標籤查詢
CREATE INDEX IF NOT EXISTS idx_chunk_actions ON chunks USING GIN (action_tags);
```

### 4.3 新增 `pose_analytics` 表 (可選，用於存儲詳細分析)
如果 `chunks` 存儲標籤不夠，可存儲詳細的動作序列。
```sql
CREATE TABLE pose_analytics (
    id SERIAL PRIMARY KEY,
    uuid TEXT NOT NULL,
    chunk_id TEXT REFERENCES chunks(chunk_id),
    person_id INTEGER, -- 關聯 person_identities
    start_time FLOAT,
    end_time FLOAT,
    action_label TEXT, -- 如 "waving"
    action_score FLOAT,
    keypoints_snapshot JSONB -- 關鍵幀骨架 (用於 Debug)
);
```

---

## 5. 查詢解析機制 (LLM Intent Parser)

### 5.1 Prompt 設計
System Prompt 將指示 LLM 輸出標準化的 JSON 格式，映射到上述維度。

### 5.2 JSON 輸出示例
用戶輸入："找一下昨天在辦公室，那個戴眼鏡穿西裝，正在生氣地罵人的男人。"

```json
{
  "who": {
    "gender": "male",
    "facial_features": ["glasses"],
    "clothing": ["suit"],
    "expression": "angry",
    "action": ["shouting", "arguing"] 
  },
  "where": ["office"],
  "when": { "relative": "yesterday" },
  "what": "shouting at someone",
  "limit": 10
}
```

---

## 6. 搜索執行器邏輯 (Query Translator)

Translator 將上述 JSON 轉換為混合查詢 (Hybrid Query)。

### 6.1 結構化過濾 (SQL)
針對精確匹配字段使用 SQL `WHERE` 子句。
```sql
SELECT c.* FROM chunks c
JOIN person_identities pi ON ...
WHERE 
  pi.attributes->>'gender' = 'male'
  AND pi.attributes->'facial_features' ? 'glasses'
  AND c.scene_tags @> ARRAY['office']
  AND c.start_time >= :yesterday_start;
```

### 6.2 語義檢索 (Vector)
針對模糊描述 (What) 使用向量相似度。
* 將 "shouting at someone" 編碼為向量。
* 在 Qdrant 中檢索與此向量相似的 `chunks` (基於 ASR 語義) 或 `pose_events` (基於動作語義)。

### 6.3 結果融合 (Re-ranking)
* 取 SQL 過濾結果與 Vector 檢索結果的交集。
* 若無交集，優先展示滿足 Filter (Who/Where) 的結果，按 Vector 分數排序。

---

## 7. Pose Analyzer Processor 實施細節

這是支持「事 (Event)」和「人 (Person Action)」維度的核心前置模塊。

### 7.1 處理流程
1. **輸入**: 原始 `pose.json` (座標) + `yolo.json` (物體框)。
2. **特徵工程**:
    * 計算關節角度 (Angle): 手肘、膝蓋。
    * 計算速度 (Velocity): 手腕、身體中心點位移。
    * 計算交互 (Interaction): 人手框與 YOLO 物體框 IoU。
3. **規則分類 (Rule-based)**:
    * 手部高於頭頂 -> `hands_up`。
    * 雙手交叉於胸前 -> `arms_crossed`。
    * 快速靠近另一人 -> `approaching`。
4. **輸出**: 更新 `chunks` 表的 `action_tags` 和 `person_identities` 表的 `attributes`。

---

## 8. 實施路線圖

### Phase 1: 基礎設施 (Day 1-2)
* [ ] 更新數據庫 Schema (增加 `attributes`, `action_tags` 等字段與索引)。
* [ ] 創建 `scripts/pose_analyzer_processor.py` (基礎規則版：站/坐/臥/手勢)。
* [ ] 運行 Pose Analyzer 對現有數據進行標記。

### Phase 2: 搜尋解析器 (Day 3-4)
* [ ] 創建 `scripts/search_processor.py`。
* [ ] 實現 LLM Intent Parser (Qwen3.6-plus)。
* [ ] 實現 Query Translator (生成動態 SQL)。

### Phase 3: 執行與整合 (Day 5-6)
* [ ] 實現 Search Executor (PostgreSQL 查詢邏輯)。
* [ ] 開發 `POST /api/v1/search/smart` API。
* [ ] 前端對接與測試。

### Phase 4: 優化 (Day 7+)
* [ ] 引入向量檢索 (Vector Search) 支持模糊語義。
* [ ] 優化 Pose 分析算法 (引入 ST-GCN 等輕量模型)。

---

## 9. 風險與對策

| 風險 | 影響 | 對策 |
| :--- | :--- | :--- |
| **LLM 解析不穩定** | 提取的屬性錯誤 (如把 "蘋果" 當作物體而非公司名) | 在 Prompt 中增加 Context (提供當前視頻的 YOLO/Scene 標籤列表供 LLM 選擇)。 |
| **Pose 標籤稀疏** | 複雜動作無法識別 (如 "打太極") | 初期僅支持基礎動作庫；複雜動作依賴語義向量搜索 (ASR 內容補充)。 |
| **查詢性能** | 多條件 JOIN 與 JSONB 查詢慢 | 嚴格要求 GIN 索引；限制搜尋範圍 (如先過濾 Video UUID 和 Time)。 |
