feat: backup architecture docs, source code, and scripts
This commit is contained in:
273
docs_v1.0/CHUNKING/CORE/CHUNKING_ARCHITECTURE.md
Normal file
273
docs_v1.0/CHUNKING/CORE/CHUNKING_ARCHITECTURE.md
Normal file
@@ -0,0 +1,273 @@
|
||||
---
|
||||
document_type: "architecture_design"
|
||||
service: "MOMENTRY_CORE"
|
||||
title: "Momentry Core 分片架構總綱 (Master Chunking Architecture) (v1.1)"
|
||||
date: "2026-04-22"
|
||||
version: "V1.0"
|
||||
status: "active"
|
||||
owner: "Warren"
|
||||
created_by: "OpenCode"
|
||||
tags:
|
||||
- "chunking"
|
||||
- "momentry"
|
||||
- "core"
|
||||
- "分片架構總綱"
|
||||
ai_query_hints:
|
||||
- "查詢 Momentry Core 分片架構總綱 (Master Chunking Architecture) (v1.1) 的內容"
|
||||
- "Momentry Core 分片架構總綱 (Master Chunking Architecture) (v1.1) 的主要目的是什麼?"
|
||||
- "如何操作或實施 Momentry Core 分片架構總綱 (Master Chunking Architecture) (v1.1)?"
|
||||
---
|
||||
|
||||
# Momentry Core 分片架構總綱 (Master Chunking Architecture) (v1.1)
|
||||
|
||||
| 項目 | 內容 |
|
||||
|------|------|
|
||||
| 建立者 | OpenCode |
|
||||
| 建立時間 | 2026-04-22 |
|
||||
| 最後更新 | 2026-04-22 |
|
||||
| 文件版本 | V1.1 |
|
||||
| **狀態** | **設計文檔(與實際實現有差異)** |
|
||||
|
||||
---
|
||||
|
||||
## 版本歷史
|
||||
|
||||
| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
|
||||
|------|------|------|--------|-----------|
|
||||
| V1.1 | 2026-04-22 | 術語標準化整合,添加參考文件連結 | OpenCode | OpenCode / deepseek-v3.2 |
|
||||
| V1.0 | 2026-04-22 | 整合分片規則、標記設計與實現差異 | OpenCode | OpenCode / Qwen3.6-Plus |
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 重要說明:設計與實現差異
|
||||
|
||||
本文檔描述的是**設計目標**,與**實際實現**存在差異。以下是主要差異點:
|
||||
|
||||
### 差異點 1: `chunk_type` 值
|
||||
| 設計文檔 | 實際實現 | 狀態 |
|
||||
|----------|----------|------|
|
||||
| `sentence` | `ChunkType::Sentence` | ✅ 一致 |
|
||||
| `visual` | 未實現 (設計值: visual) | ❌ 缺失 |
|
||||
| `scene` | `ChunkType::Cut` (設計值: scene) | ⚠️ 部分實現 |
|
||||
| `summary` | `ChunkType::Story` (設計值: summary) | ⚠️ 概念調整 |
|
||||
| - | `"time"` | 🔄 額外 |
|
||||
| - | `"cut"` | 🔄 額外 |
|
||||
| - | `"trace"` | 🔄 額外 |
|
||||
| - | `"story"` | 🔄 額外 |
|
||||
|
||||
### 差異點 2: 規則實現
|
||||
| 規則 | 設計描述 | 實際實現 |
|
||||
|------|----------|----------|
|
||||
| Rule 1 | 句子級檢索 | ✅ 已實現 (`rule1_ingest.rs`) |
|
||||
| Rule 2 | 視覺物件級檢索 | ❌ 未實現 |
|
||||
| Rule 3 | 場景級檢索 | ⚠️ 部分實現 (`rule3_ingest.rs`) |
|
||||
| Rule 4 | 摘要級檢索 | ❌ 未實現 |
|
||||
|
||||
---
|
||||
|
||||
## 0. 設計目標
|
||||
|
||||
**分片 (Chunking)** 是 Momentry Core 將連續影音轉化為**可檢索知識**的核心樞紐。本架構定義了如何將處理器產出的原始數據 (Pre-Chunk/Frame),依據標準規則組裝為多層級 Chunk,並透過關聯分析產出高價值摘要。
|
||||
|
||||
- **時間權威 (Frame-Based)**:所有時間計算以 `frame_number` 為唯一權威,秒數僅供參考 (`time = frame / fps`)。
|
||||
- **多模態融合 (Multimodal Fusion)**:每個 Chunk 聚合 ASR (聽覺)、Face (人物)、YOLO (物件) 特徵。
|
||||
- **分層檢索 (Hierarchical Retrieval)**:從微觀台詞 (Rule 1) 到宏觀劇情問答 (Rule 4)。
|
||||
- **自動知識萃取 (Auto-Enrichment)**:利用 LLM 聚合父子內容,自動生成 Summary 與 5W1H。
|
||||
|
||||
---
|
||||
|
||||
## 1. 通用分片結構 (Universal Chunk Schema)
|
||||
|
||||
無論是哪一種 Rule,所有 Chunk 皆遵循以下核心定義:
|
||||
|
||||
| 欄位 | 類型 | 說明 |
|
||||
|:---|:---|:---|
|
||||
| `chunk_id` | UUID | 分片唯一標識符 (PK) |
|
||||
| `asset_uuid` | UUID | 所屬影片資產 UUID |
|
||||
| `chunk_type` | ENUM | **設計值**:`sentence`, `visual`, `scene`, `summary`<br>**實際值**:`"time"` (`ChunkType::TimeBased`), `"sentence"` (`ChunkType::Sentence`), `"cut"` (`ChunkType::Cut`), `"trace"` (`ChunkType::Trace`), `"story"` (`ChunkType::Story`) |
|
||||
| `start_frame` | INT | **起始幀** (時間權威來源) |
|
||||
| `end_frame` | INT | **結束幀** (時間權威來源) |
|
||||
| `content` | TEXT | 主要檢索內容 (ASR 文本 / 物件描述 / 劇情摘要) |
|
||||
| `metadata` | JSONB | 關聯內容 (Speaker, Face IDs, Frame Objects) |
|
||||
|
||||
---
|
||||
|
||||
## 2. 分片規則路由 (Rule Routing Table)
|
||||
|
||||
系統依據規則將原始數據轉化為不同粒度的檢索單元,並寫入對應資料表。
|
||||
|
||||
| Rule | 粒度 | `chunk_type` | 內容來源 (Content) | 關聯內容 (Metadata) | 寫入資料表 | 實現狀態 |
|
||||
|:---|:---|:---|:---|:---|:---|:---|
|
||||
| **Rule 1** | 語句 | `ChunkType::Sentence` (設計值: `sentence`) | **ASR 文本** (單句文字) | Speaker ID, Face IDs (區間聚合) | `chunks_rule1` | ✅ 已實現 |
|
||||
| **Rule 2** | 畫面 | 未實現 (設計值: `visual`) | **物件標籤串** (e.g., "car, person") | YOLO Objects (>0.8), Faces, Speaker | `chunks_rule2` | ❌ 未實現 |
|
||||
| **Rule 3** | 場景 | `ChunkType::Cut` (設計值: `scene`) | **場景摘要** (聚合多個 Rule 1/2) | Aggregated Faces, Objects, Speakers | `chunks_rule3` | ⚠️ 部分實現 |
|
||||
| **Rule 4** | 摘要 | `ChunkType::Story` (設計值: `summary`) | **劇情描述 & 5W1H 分析** (LLM 生成) | 5W1H 結構化數據, 關聯 Rule 3 IDs | `chunks_rule4` | ⚠️ 概念調整 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 關聯與知識萃取流程 (Associative Enrichment Pipeline)
|
||||
|
||||
這是系統將「原始數據」轉化為「結構化知識」的核心機制。針對 **父 Chunk (Rule 3 Scene)**,系統會匯聚其下屬的所有子 Chunk、視覺物件與人物特徵,並透過 LLM 產出全新的敘事內容。
|
||||
|
||||
### 3.1 數據關聯架構 (Input Aggregation)
|
||||
|
||||
針對每一個 Parent Chunk `[start_frame, end_frame]`,系統提取:
|
||||
1. **子 Chunk (Rule 1)**: 提取對話 (`content`) 與說話者 (`speaker_id`)。
|
||||
2. **子 Chunk (Rule 2)**: 提取物件標籤 (`frame_objects`)。
|
||||
3. **身份解析**: 將 `face_id` 解析為真實人名 (e.g., `face_01` -> "Cary Grant")。
|
||||
|
||||
### 3.2 LLM 上下文構造 (Context Construction)
|
||||
|
||||
系統組裝 Prompt 提供給 Gemma4:
|
||||
```text
|
||||
### 場景數據
|
||||
**人物**: Cary Grant, Audrey Hepburn
|
||||
**物件**: car, street, gun
|
||||
**對話**: [Cary] "Look at that car!"
|
||||
|
||||
### 任務
|
||||
1. **New Content**: 融合所有資訊,生成一段詳細的繁體中文敘述。
|
||||
2. **Summary**: 一句話精簡摘要。
|
||||
3. **5W1H**: 結構化提取 (Who, What, Where, Why, How)。
|
||||
```
|
||||
|
||||
### 3.3 輸出與寫入 (Output & Ingestion)
|
||||
|
||||
LLM 返回的 JSON 將直接更新資料庫:
|
||||
```sql
|
||||
UPDATE chunks_rule3
|
||||
SET
|
||||
content = $new_content, -- 覆蓋為詳細敘述
|
||||
summary = $new_summary, -- 儲存精簡摘要
|
||||
analysis_5w1h = $json_5w1h -- 儲存結構化分析
|
||||
WHERE id = $chunk_id;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 實際實現狀態
|
||||
|
||||
### 4.1 已實現功能
|
||||
- **Rule 1 (Sentence Chunk)**: 完整實現,位於 `src/core/chunk/rule1_ingest.rs`
|
||||
- **Rule 3 (Scene Chunk)**: 部分實現,位於 `src/core/chunk/rule3_ingest.rs`
|
||||
- 目前基於 CUT 數據識別場景
|
||||
- 聚合 Rule 1 句子
|
||||
- 調用 LLM 生成 5W1H 摘要
|
||||
|
||||
### 4.2 未實現功能
|
||||
- **Rule 2 (Visual Chunk)**: 未實現
|
||||
- **Rule 4 (Summary Chunk)**: 未實現
|
||||
- **完整的場景分類**: 目前僅基於 CUT 數據,未集成 Places365 場景分類
|
||||
|
||||
### 4.3 實際數據庫結構
|
||||
```sql
|
||||
-- 實際的 chunks 表結構
|
||||
CREATE TABLE chunks (
|
||||
id SERIAL PRIMARY KEY,
|
||||
uuid VARCHAR(32) NOT NULL,
|
||||
chunk_id VARCHAR(64) NOT NULL,
|
||||
chunk_index INTEGER NOT NULL,
|
||||
chunk_type VARCHAR(32) NOT NULL, -- "time", "sentence", "cut", "trace", "story"
|
||||
start_time DOUBLE PRECISION NOT NULL,
|
||||
end_time DOUBLE PRECISION NOT NULL,
|
||||
fps DOUBLE PRECISION DEFAULT 24.0,
|
||||
start_frame BIGINT DEFAULT 0,
|
||||
end_frame BIGINT DEFAULT 0,
|
||||
content JSONB NOT NULL,
|
||||
metadata JSONB,
|
||||
vector_id VARCHAR(64),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(uuid, chunk_id)
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 遷移計劃建議
|
||||
|
||||
### 5.1 短期目標 (1-2個月)
|
||||
1. **實現 Rule 2 (Visual Chunk)**
|
||||
- 集成 YOLO 物件檢測結果
|
||||
- 創建 `chunks_rule2` 表
|
||||
- 實現 `rule2_ingest.rs`
|
||||
|
||||
2. **完善 Rule 3 (Scene Chunk)**
|
||||
- 集成 Places365 場景分類
|
||||
- 完善 LLM 摘要生成
|
||||
- 創建 `chunks_rule3` 表
|
||||
|
||||
### 5.2 中期目標 (3-6個月)
|
||||
1. **實現 Rule 4 (Summary Chunk)**
|
||||
- 跨場景劇情摘要
|
||||
- 創建 `chunks_rule4` 表
|
||||
|
||||
2. **統一 `chunk_type` 枚舉**
|
||||
- 更新 Rust 代碼中的 `ChunkType` 枚舉
|
||||
- 遷移現有數據
|
||||
|
||||
### 5.3 長期目標 (6-12個月)
|
||||
1. **動態分片規則**
|
||||
- 支持用戶自定義分片規則
|
||||
- 可配置的聚合策略
|
||||
|
||||
2. **實時分片處理**
|
||||
- On-the-fly 分片生成
|
||||
- 增量更新機制
|
||||
|
||||
---
|
||||
|
||||
## 6. 相關文件
|
||||
|
||||
| 文件 | 描述 | 狀態 |
|
||||
|------|------|------|
|
||||
| [CHUNK_RULE_1_SENTENCE.md](./CHUNK_RULE_1_SENTENCE.md) | Rule 1: 句子級檢索 | ✅ 與實現一致 |
|
||||
| [CHUNK_RULE_2_VISUAL.md](./CHUNK_RULE_2_VISUAL.md) | Rule 2: 視覺物件級檢索 | ⚠️ 設計文檔 |
|
||||
| [CHUNK_RULE_3_SCENE.md](./CHUNK_RULE_3_SCENE.md) | Rule 3: 場景級檢索 | ⚠️ 部分實現 |
|
||||
| [CHUNK_RULE_4_SUMMARY.md](./CHUNK_RULE_4_SUMMARY.md) | Rule 4: 摘要級檢索 | ⚠️ 設計文檔 |
|
||||
| [CHUNKING_SCHEMA_SPEC.md](./CHUNKING_SCHEMA_SPEC.md) | 數據庫結構規範 | ⚠️ 設計文檔 |
|
||||
| [CHUNKING_ENRICHMENT_PIPELINE.md](./CHUNKING_ENRICHMENT_PIPELINE.md) | 知識萃取流程 | ⚠️ 設計文檔 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 代碼引用
|
||||
|
||||
### 7.1 主要實現文件
|
||||
```rust
|
||||
// Rule 1 實現
|
||||
src/core/chunk/rule1_ingest.rs
|
||||
|
||||
// Rule 3 實現
|
||||
src/core/chunk/rule3_ingest.rs
|
||||
|
||||
// Chunk 類型定義
|
||||
src/core/chunk/types.rs
|
||||
|
||||
// Chunk 分割器
|
||||
src/core/chunk/splitter.rs
|
||||
```
|
||||
|
||||
### 7.2 數據庫操作
|
||||
```rust
|
||||
// 數據庫層的 chunk 處理
|
||||
src/core/db/postgres_db.rs
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 更新記錄
|
||||
|
||||
| 日期 | 版本 | 變更內容 | 操作人 |
|
||||
|------|------|----------|--------|
|
||||
| 2026-04-22 | V1.1 | 術語標準化整合,添加參考文件連結 | OpenCode |
|
||||
| 2026-04-22 | V1.0 | 創建整合文檔,標記設計與實現差異 | OpenCode |
|
||||
|
||||
---
|
||||
|
||||
## 參考文件
|
||||
|
||||
1. **[TERMINOLOGY_MAPPING.md](../../TERMINOLOGY_MAPPING.md)** - 完整術語對照表
|
||||
2. **[DESIGN_IMPLEMENTATION_GAP.md](../../DESIGN_IMPLEMENTATION_GAP.md)** - 設計與實現差異分析
|
||||
3. **[ARCHITECTURE_OVERVIEW.md](../../ARCHITECTURE_OVERVIEW.md)** - 架構總覽
|
||||
|
||||
**最後更新**: 2026-04-22
|
||||
177
docs_v1.0/CHUNKING/CORE/CHUNKING_ENRICHMENT_PIPELINE.md
Normal file
177
docs_v1.0/CHUNKING/CORE/CHUNKING_ENRICHMENT_PIPELINE.md
Normal file
@@ -0,0 +1,177 @@
|
||||
---
|
||||
document_type: "architecture_design"
|
||||
service: "MOMENTRY_CORE"
|
||||
title: "Momentry Core 分片關聯與內容生成架構 (Chunk Associative Enrichment) (v1.0)"
|
||||
date: "2026-04-21"
|
||||
version: "V1.0"
|
||||
status: "active"
|
||||
owner: "Warren"
|
||||
created_by: "OpenCode"
|
||||
tags:
|
||||
- "momentry"
|
||||
- "core"
|
||||
- "associative"
|
||||
- "分片關聯與內容生成架構"
|
||||
ai_query_hints:
|
||||
- "查詢 Momentry Core 分片關聯與內容生成架構 (Chunk Associative Enrichment) (v1.0) 的內容"
|
||||
- "Momentry Core 分片關聯與內容生成架構 (Chunk Associative Enrichment) (v1.0) 的主要目的是什麼?"
|
||||
- "如何操作或實施 Momentry Core 分片關聯與內容生成架構 (Chunk Associative Enrichment) (v1.0)?"
|
||||
---
|
||||
|
||||
# Momentry Core 分片關聯與內容生成架構 (Chunk Associative Enrichment) (v1.0)
|
||||
|
||||
| 項目 | 內容 |
|
||||
|------|------|
|
||||
| 建立者 | OpenCode |
|
||||
| 建立時間 | 2026-04-21 |
|
||||
| 文件版本 | V1.0 |
|
||||
|
||||
---
|
||||
|
||||
## 版本歷史
|
||||
|
||||
| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
|
||||
|------|------|------|--------|-----------|
|
||||
| V1.0 | 2026-04-21 | 定義基於多模態關聯 (Multimodal Association) 的內容生成流程 | OpenCode | OpenCode / Qwen3.6-Plus |
|
||||
|
||||
---
|
||||
|
||||
## 0. 設計目標
|
||||
|
||||
本規範定義了系統如何將**父 Chunk (Parent Chunk)** 與其關聯的視覺、聽覺、人物數據進行深度聚合,並利用 LLM **生成全新的敘事內容 (New Content)**、**摘要 (Summary)** 與 **結構化分析 (5W1H)**,將原始數據轉化為高價值的知識資產。
|
||||
|
||||
---
|
||||
|
||||
## 1. 關聯輸入架構 (Associative Input)
|
||||
|
||||
為了產出高品質內容,系統需聚合以下三層資訊:
|
||||
|
||||
### 1.1 核心數據源
|
||||
|
||||
| 數據源 | 欄位/內容 | 處理方式 |
|
||||
|:---|:---|:---|
|
||||
| **父 Chunk (Rule 3)** | `content` (場景初步描述), `[start_frame, end_frame]` | 作為上下文錨點。 |
|
||||
| **子 Chunk (Rule 1)** | `content` (ASR 對話), `speaker_id` | 提取「誰說了什麼」。 |
|
||||
| **子 Chunk (Rule 2)** | `frame_objects` (YOLO 物件) | 提取「場景中有什麼」。 |
|
||||
|
||||
### 1.2 知識庫解析 (Knowledge Resolution)
|
||||
|
||||
在送入 LLM 前,必須將機器 ID 轉換為人類可讀的名稱:
|
||||
- **Face Resolution**: `face_id_01` → 查詢 `face_identities` → `"Cary Grant"`。
|
||||
- **Object Normalization**: `"automobile"` → 映射為 `"car"` (選用)。
|
||||
|
||||
---
|
||||
|
||||
## 2. 內容生成策略 (Content Generation Strategy)
|
||||
|
||||
系統採用 **「多模態融合 (Multimodal Fusion)」** 策略,將離散的數據重組為連貫的敘事。
|
||||
|
||||
### 2.1 融合範例
|
||||
|
||||
**輸入數據**:
|
||||
- **Dialogue**: "Look at that car!" (Speaker: SPEAKER_00/Cary Grant)
|
||||
- **Objects**: `car`, `street`, `gun`
|
||||
- **Faces**: `Cary Grant`, `Audrey Hepburn`
|
||||
|
||||
**融合後的上下文 (Context)**:
|
||||
> 場景內出現人物:Cary Grant, Audrey Hepburn。
|
||||
> 視覺物件:car, street, gun。
|
||||
> 對話內容:[Cary Grant] "Look at that car!"
|
||||
|
||||
**LLM 輸出 (New Content)**:
|
||||
> "Cary Grant 和 Audrey Hepburn 站在街道上。Grant 注意到一輛車,並似乎對它有所警覺,周圍環境暗示可能存在危險(因為偵測到槍枝)。"
|
||||
|
||||
---
|
||||
|
||||
## 3. 處理流程 (Pipeline)
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Parent Chunk] -->|Time Range| B[Data Aggregator]
|
||||
C[Children Chunks] -->|Content| B
|
||||
D[Knowledge DB] -->|Identity Map| B
|
||||
|
||||
B -->|Context Prompt| E[LLM (Gemma4)]
|
||||
|
||||
E -->|Output 1| F[New Content (Narrative)]
|
||||
E -->|Output 2| G[Summary (Concise)]
|
||||
E -->|Output 3| H[5W1H (Structured)]
|
||||
|
||||
F & G & H --> I[Update DB (Rule 3/4)]
|
||||
```
|
||||
|
||||
### 3.1 提示詞設計 (Prompt Design)
|
||||
|
||||
為了確保輸出的結構化,提示詞必須明確要求 JSON 格式。
|
||||
|
||||
```text
|
||||
### 任務
|
||||
分析以下場景數據,生成結構化的劇情分析。
|
||||
|
||||
### 場景數據
|
||||
**時間**: {start_sec}s - {end_sec}s
|
||||
**人物**: {resolved_faces}
|
||||
**物件**: {objects}
|
||||
**對話片段**:
|
||||
{dialogue_snippets}
|
||||
|
||||
### 輸出要求
|
||||
請以 JSON 格式返回,包含以下欄位:
|
||||
1. **content**: 一段詳細的敘述性文字 (繁體中文),融合所有對話、人物動作與物件資訊。
|
||||
2. **summary**: 一句話的精簡摘要 (繁體中文)。
|
||||
3. **5w1h**:
|
||||
- who: 主要人物列表
|
||||
- what: 核心事件
|
||||
- where: 地點/環境
|
||||
- when: 時間/背景
|
||||
- why: 動機/原因
|
||||
- how: 方式/過程
|
||||
|
||||
### JSON 格式範例
|
||||
{
|
||||
"content": "...",
|
||||
"summary": "...",
|
||||
"5w1h": { "who": [], "what": [], ... }
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 輸出結構與儲存 (Output & Storage)
|
||||
|
||||
生成的內容將被寫入資料庫,通常是更新父 Chunk (Rule 3) 或生成新的 Rule 4 Chunk。
|
||||
|
||||
### 4.1 JSON 輸出範例
|
||||
|
||||
```json
|
||||
{
|
||||
"content": "彼得 (Cary Grant) 與雷吉娜 (Audrey Hepburn) 在夜間的街道上駕車行駛。彼得發現了那輛可疑的車子,並警告雷吉娜保持警惕。兩人似乎正在執行一項危險的任務,尋找藏有郵票的保險箱。",
|
||||
"summary": "彼得與雷吉娜夜間駕車尋找郵票,途中遭遇可疑車輛並保持警戒。",
|
||||
"5w1h": {
|
||||
"who": ["Cary Grant", "Audrey Hepburn"],
|
||||
"what": ["Driving", "Spotting suspicious car", "Searching for stamps"],
|
||||
"where": ["Street", "Car"],
|
||||
"when": "Night",
|
||||
"why": "To retrieve the stamps",
|
||||
"how": "By driving and observing surroundings"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 資料庫寫入 (SQL)
|
||||
|
||||
**更新 Rule 3 (Parent Chunk)**:
|
||||
```sql
|
||||
UPDATE chunks_rule3
|
||||
SET
|
||||
content = $new_content, -- 覆蓋或追加新的敘述內容
|
||||
summary = $new_summary, -- 儲存精簡摘要
|
||||
analysis_5w1h = $json_5w1h -- 儲存結構化分析
|
||||
WHERE id = $chunk_id;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 總結
|
||||
|
||||
透過**附加關聯**與**內容生成**,Momentry Core 實現了從「關鍵字匹配」到「語意理解」的跨越。系統不僅能告訴使用者「某個物件出現了」,還能解釋「**誰**在**哪裡**利用**什麼**做了**什麼**」,提供完整的場景認知。
|
||||
271
docs_v1.0/CHUNKING/CORE/CHUNKING_SCHEMA_SPEC.md
Normal file
271
docs_v1.0/CHUNKING/CORE/CHUNKING_SCHEMA_SPEC.md
Normal file
@@ -0,0 +1,271 @@
|
||||
---
|
||||
document_type: "architecture_design"
|
||||
service: "MOMENTRY_CORE"
|
||||
title: "Momentry Core 分片資料庫結構規範 (Chunking Schema Spec) (v1.1)"
|
||||
date: "2026-04-21"
|
||||
version: "V1.0"
|
||||
status: "active"
|
||||
owner: "Warren"
|
||||
created_by: "OpenCode"
|
||||
tags:
|
||||
- "schema"
|
||||
- "momentry"
|
||||
- "core"
|
||||
- "分片資料庫結構規範"
|
||||
ai_query_hints:
|
||||
- "查詢 Momentry Core 分片資料庫結構規範 (Chunking Schema Spec) (v1.1) 的內容"
|
||||
- "Momentry Core 分片資料庫結構規範 (Chunking Schema Spec) (v1.1) 的主要目的是什麼?"
|
||||
- "如何操作或實施 Momentry Core 分片資料庫結構規範 (Chunking Schema Spec) (v1.1)?"
|
||||
---
|
||||
|
||||
# Momentry Core 分片資料庫結構規範 (Chunking Schema Spec) (v1.1)
|
||||
|
||||
| 項目 | 內容 |
|
||||
|------|------|
|
||||
| 建立者 | OpenCode |
|
||||
| 建立時間 | 2026-04-21 |
|
||||
| 最後更新 | 2026-04-22 |
|
||||
| 文件版本 | V1.1 |
|
||||
| **狀態** | **設計文檔(與實際實現有差異)** |
|
||||
|
||||
---
|
||||
|
||||
## 版本歷史
|
||||
|
||||
| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
|
||||
|------|------|------|--------|-----------|
|
||||
| V1.1 | 2026-04-22 | 術語標準化:更新為實際實現的術語 | OpenCode | OpenCode / deepseek-v3.2 |
|
||||
| V1.0 | 2026-04-21 | 定義符合 Chunking Rule 的完整資料庫結構與欄位對齊 | OpenCode | OpenCode / Qwen3.6-Plus |
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 重要說明:術語標準化
|
||||
|
||||
本文檔已根據實際 Rust 代碼實現更新術語。**核心原則**:當設計與實現出現矛盾時,以實際的 Rust 代碼實現為最高權威。
|
||||
|
||||
### 術語對照表
|
||||
| 設計概念 | 設計值 | 實現值 | 實現狀態 |
|
||||
|----------|--------|--------|----------|
|
||||
| 時間基準分片 | `time` | `TimeBased` | ✅ 已實現 |
|
||||
| 句子級分片 | `sentence` | `Sentence` | ✅ 已實現 |
|
||||
| 場景級分片 | `scene` | `Cut` | ⚠️ 部分實現 |
|
||||
| 視覺物件級分片 | `visual` | (未實現) | ❌ 未實現 |
|
||||
| 摘要級分片 | `summary` | `Story` | ⚠️ 概念調整 |
|
||||
| 軌跡追蹤分片 | (未定義) | `Trace` | ✅ 已實現 |
|
||||
|
||||
**參考文件**:[TERMINOLOGY_MAPPING.md](../../TERMINOLOGY_MAPPING.md)
|
||||
|
||||
---
|
||||
|
||||
## 0. 設計原則
|
||||
|
||||
本規範確保所有資料庫表嚴格遵循 **Chunking Architecture** 定義的通用結構:
|
||||
|
||||
1. **時間權威 (Frame-Based)**:所有時間相關欄位以 `frame` 為核心,`timestamp` 為計算參考。
|
||||
2. **內容與元數據分離 (Content vs Metadata)**:`content` 用於全文檢索與向量嵌入,`metadata` (JSONB) 儲存關聯物件、Speaker、Faces 等結構化數據。
|
||||
3. **路由清晰 (Rule Routing)**:每個 Rule 對應獨立的資料表,透過 `chunk_type` 欄位輔助識別。
|
||||
|
||||
---
|
||||
|
||||
## 1. 通用基礎欄位 (Common Base Columns)
|
||||
|
||||
以下欄位為**所有 Rule 表**的標準配置:
|
||||
|
||||
| 欄位 | 類型 | 約束 | 說明 |
|
||||
|:---|:---|:---|:---|
|
||||
| `id` | UUID | PK | Chunk 唯一標識符 |
|
||||
| `asset_uuid` | UUID | FK, Not Null | 所屬影片資產 UUID |
|
||||
| `chunk_type` | VARCHAR(20) | Not Null | 分片類型標識 (`TimeBased`, `Sentence`, `Cut`, `Trace`, `Story`) |
|
||||
| `start_frame` | INT | Not Null | **起始幀** (時間基準) |
|
||||
| `end_frame` | INT | Not Null | **結束幀** (時間基準) |
|
||||
| `fps` | DOUBLE PRECISION | Not Null | 幀率 (用於換算秒數) |
|
||||
| `content` | TEXT | Not Null | 檢索主體內容 |
|
||||
| `created_at` | TIMESTAMPTZ | Default Now | 建立時間 |
|
||||
|
||||
---
|
||||
|
||||
## 2. Rule 1 結構:句子級 (Sentence)
|
||||
|
||||
對應 `CHUNK_RULE_1_SENTENCE.md`,用於 ASR 語句聚合。
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS chunks_rule1 (
|
||||
-- 通用基礎
|
||||
id UUID PRIMARY KEY,
|
||||
asset_uuid UUID NOT NULL REFERENCES assets(id),
|
||||
chunk_type VARCHAR(20) DEFAULT 'Sentence' NOT NULL,
|
||||
start_frame INT NOT NULL,
|
||||
end_frame INT NOT NULL,
|
||||
fps DOUBLE PRECISION NOT NULL,
|
||||
content TEXT NOT NULL, -- ASR 文本
|
||||
|
||||
-- 關聯元數據
|
||||
speaker_id VARCHAR(50), -- ASRX 說話者
|
||||
face_ids JSONB, -- 區間內出現的 Face ID 陣列
|
||||
face_confidence_map JSONB, -- 對應的臉部信心值 (可選)
|
||||
|
||||
-- 索引優化
|
||||
search_vector tsvector GENERATED ALWAYS AS (to_tsvector('simple', content)) STORED,
|
||||
embedding vector(768) -- nomic-embed-text-v2-moe
|
||||
);
|
||||
|
||||
-- 索引
|
||||
CREATE INDEX idx_r1_asset ON chunks_rule1(asset_uuid);
|
||||
CREATE INDEX idx_r1_speaker ON chunks_rule1(speaker_id);
|
||||
CREATE INDEX idx_r1_search ON chunks_rule1 USING gin(search_vector);
|
||||
CREATE INDEX idx_r1_faces ON chunks_rule1 USING gin(face_ids);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Rule 2 結構:畫面級 (Visual) ⚠️ 未實現
|
||||
|
||||
**注意**: Rule 2 在實際代碼中尚未實現。以下為設計概念。
|
||||
|
||||
對應 `CHUNK_RULE_2_VISUAL.md`,用於 YOLO/Face 幀聚合。
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS chunks_rule2 (
|
||||
-- 通用基礎
|
||||
id UUID PRIMARY KEY,
|
||||
asset_uuid UUID NOT NULL REFERENCES assets(id),
|
||||
chunk_type VARCHAR(20) DEFAULT 'Visual' NOT NULL, -- ⚠️ 設計值,未實現
|
||||
start_frame INT NOT NULL,
|
||||
end_frame INT NOT NULL,
|
||||
fps DOUBLE PRECISION NOT NULL,
|
||||
content TEXT NOT NULL, -- 物件標籤串 (e.g., "car, person")
|
||||
|
||||
-- 關聯元數據
|
||||
frame_objects JSONB, -- 原始 YOLO 物件陣列 (含 BBox, Confidence)
|
||||
face_ids JSONB, -- 區間內出現的 Face ID 陣列
|
||||
speaker_id VARCHAR(50), -- 當前說話者 (若無則為 Null)
|
||||
|
||||
-- 索引優化
|
||||
search_vector tsvector GENERATED ALWAYS AS (to_tsvector('simple', content)) STORED,
|
||||
embedding vector(768)
|
||||
);
|
||||
|
||||
-- 索引
|
||||
CREATE INDEX idx_r2_asset ON chunks_rule2(asset_uuid);
|
||||
CREATE INDEX idx_r2_objects ON chunks_rule2 USING gin(frame_objects);
|
||||
CREATE INDEX idx_r2_faces ON chunks_rule2 USING gin(face_ids);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Rule 3 結構:場景級 (Parent Scene)
|
||||
|
||||
對應 `CHUNK_RULE_3_SCENE.md`,作為 Parent Chunk,聚合多個 Rule 1/2。
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS chunks_rule3 (
|
||||
-- 通用基礎
|
||||
id UUID PRIMARY KEY,
|
||||
asset_uuid UUID NOT NULL REFERENCES assets(id),
|
||||
chunk_type VARCHAR(20) DEFAULT 'Cut' NOT NULL,
|
||||
start_frame INT NOT NULL,
|
||||
end_frame INT NOT NULL,
|
||||
fps DOUBLE PRECISION NOT NULL,
|
||||
content TEXT NOT NULL, -- 場景摘要 (Scene Summary)
|
||||
|
||||
-- 關聯元數據 (聚合自子 Chunk)
|
||||
faces JSONB, -- 場景內所有不重複 Face IDs
|
||||
speakers JSONB, -- 場景內所有不重複 Speaker IDs
|
||||
objects JSONB, -- 場景內重要物件統計
|
||||
|
||||
-- 索引優化
|
||||
search_vector tsvector GENERATED ALWAYS AS (to_tsvector('simple', content)) STORED,
|
||||
embedding vector(768)
|
||||
);
|
||||
|
||||
-- 索引
|
||||
CREATE INDEX idx_r3_asset ON chunks_rule3(asset_uuid);
|
||||
CREATE INDEX idx_r3_search ON chunks_rule3 USING gin(search_vector);
|
||||
CREATE INDEX idx_r3_faces ON chunks_rule3 USING gin(faces);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Rule 4 結構:敘事分析級 (Story 5W1H) ⚠️ 概念調整
|
||||
|
||||
**注意**: Rule 4 在實際代碼中實現為 `Story` 分片,而非設計中的 `summary`。
|
||||
|
||||
對應 `CHUNK_RULE_4_SUMMARY.md`,LLM 分析產出的頂層 Chunk。
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS chunks_rule4 (
|
||||
-- 通用基礎
|
||||
id UUID PRIMARY KEY,
|
||||
asset_uuid UUID NOT NULL REFERENCES assets(id),
|
||||
chunk_type VARCHAR(20) DEFAULT 'Story' NOT NULL, -- 🔄 實際實現值
|
||||
start_frame INT NOT NULL,
|
||||
end_frame INT NOT NULL,
|
||||
fps DOUBLE PRECISION NOT NULL,
|
||||
content TEXT NOT NULL, -- LLM 生成的流暢劇情摘要
|
||||
|
||||
-- 結構化分析
|
||||
analysis_5w1h JSONB NOT NULL, -- 完整的 5W1H JSON 結構
|
||||
rule3_chunk_ids UUID[], -- 組成此摘要的 Rule 3 ID 列表
|
||||
|
||||
-- 關聯元數據
|
||||
faces JSONB, -- 區塊內人物
|
||||
objects JSONB, -- 區塊內物件
|
||||
|
||||
-- 索引優化
|
||||
search_vector tsvector GENERATED ALWAYS AS (to_tsvector('simple', content)) STORED,
|
||||
embedding vector(768)
|
||||
);
|
||||
|
||||
-- 索引
|
||||
CREATE INDEX idx_r4_asset ON chunks_rule4(asset_uuid);
|
||||
CREATE INDEX idx_r4_5w1h_who ON chunks_rule4 USING gin((analysis_5w1h->'who'));
|
||||
CREATE INDEX idx_r4_5w1h_what ON chunks_rule4 USING gin((analysis_5w1h->'what'));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 父子關聯 (Parent-Child Mapping)
|
||||
|
||||
為了支援規則間的聚合(如 Rule 3 聚合 Rule 1/2),我們需要一個映射表或外鍵。
|
||||
|
||||
### 方案 A:子表增加 Parent 欄位 (推薦)
|
||||
|
||||
在 `chunks_rule1` 與 `chunks_rule2` 增加欄位指向 Rule 3 或 Rule 4。
|
||||
|
||||
```sql
|
||||
ALTER TABLE chunks_rule1 ADD COLUMN parent_rule3_id UUID REFERENCES chunks_rule3(id);
|
||||
ALTER TABLE chunks_rule2 ADD COLUMN parent_rule3_id UUID REFERENCES chunks_rule3(id);
|
||||
ALTER TABLE chunks_rule1 ADD COLUMN parent_rule4_id UUID REFERENCES chunks_rule4(id);
|
||||
ALTER TABLE chunks_rule2 ADD COLUMN parent_rule4_id UUID REFERENCES chunks_rule4(id);
|
||||
ALTER TABLE chunks_rule3 ADD COLUMN parent_rule4_id UUID REFERENCES chunks_rule4(id);
|
||||
```
|
||||
|
||||
### 方案 B:獨立映射表 (更靈活)
|
||||
|
||||
```sql
|
||||
CREATE TABLE chunk_relations (
|
||||
parent_id UUID NOT NULL,
|
||||
child_id UUID NOT NULL,
|
||||
relation_type VARCHAR(20), -- 'contains_sentence', 'contains_visual', 'aggregated_into_summary'
|
||||
PRIMARY KEY (parent_id, child_id)
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 時間換算函數 (Helper)
|
||||
|
||||
資料庫內建輔助函數,確保秒數計算的絕對一致性。
|
||||
|
||||
```sql
|
||||
CREATE OR REPLACE FUNCTION get_chunk_time(chunk_record ANYELEMENT)
|
||||
RETURNS TABLE(start_sec DOUBLE PRECISION, end_sec DOUBLE PRECISION) AS $$
|
||||
BEGIN
|
||||
RETURN QUERY SELECT
|
||||
chunk_record.start_frame::double precision / chunk_record.fps,
|
||||
chunk_record.end_frame::double precision / chunk_record.fps;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE;
|
||||
```
|
||||
|
||||
此設計確保了每一張表都完美對應 Chunking Architecture 的定義。
|
||||
398
docs_v1.0/CHUNKING/CORE/CHUNK_DATA_STRUCTURE.md
Normal file
398
docs_v1.0/CHUNKING/CORE/CHUNK_DATA_STRUCTURE.md
Normal file
@@ -0,0 +1,398 @@
|
||||
---
|
||||
document_type: "architecture_design"
|
||||
service: "MOMENTRY_CORE"
|
||||
title: "Momentry Chunk 資料結構說明"
|
||||
date: "2026-03-25"
|
||||
version: "V1.0"
|
||||
status: "active"
|
||||
owner: "Warren"
|
||||
created_by: "OpenCode"
|
||||
tags:
|
||||
- "momentry"
|
||||
- "chunk"
|
||||
- "資料結構說明"
|
||||
ai_query_hints:
|
||||
- "查詢 Momentry Chunk 資料結構說明 的內容"
|
||||
- "Momentry Chunk 資料結構說明 的主要目的是什麼?"
|
||||
- "如何操作或實施 Momentry Chunk 資料結構說明?"
|
||||
---
|
||||
|
||||
# Momentry Chunk 資料結構說明
|
||||
|
||||
> **對象**: marcom 團隊
|
||||
> **版本**: V1.0 | **日期**: 2026-03-25
|
||||
|
||||
---
|
||||
|
||||
## 1. 什麼是 Chunk?
|
||||
|
||||
Chunk(片段)是影片處理後的最小單位。當影片上傳後,系統會自動:
|
||||
|
||||
1. **分析** - 偵測場景、人臉、姿態
|
||||
2. **轉換** - 語音轉文字(ASR)
|
||||
3. **分段** - 將內容切割成可搜尋的片段
|
||||
4. **向量化** - 產生可搜尋的特徵向量
|
||||
|
||||
每個 Chunk 就是一個**可獨立搜尋的內容單位**。
|
||||
|
||||
---
|
||||
|
||||
## 2. Chunk 資料結構
|
||||
|
||||
### 2.1 主要欄位
|
||||
|
||||
| 欄位名 | 類型 | 說明 | 範例 |
|
||||
|--------|------|------|------|
|
||||
| `uuid` | 字串 (32) | 影片唯一識別碼 | `952f5854b9febad1` |
|
||||
| `chunk_id` | 字串 (64) | Chunk 唯一識別碼 | `asr_00001` |
|
||||
| `chunk_index` | 整數 | Chunk 順序號碼 | `1` |
|
||||
| `chunk_type` | 字串 (32) | Chunk 類型 | `sentence` |
|
||||
| `start_time` | 浮點數 | 開始時間(秒) | `12.5` |
|
||||
| `end_time` | 浮點數 | 結束時間(秒) | `18.3` |
|
||||
| `content` | JSONB | 詳細內容 | 見下方 |
|
||||
| `vector_id` | 字串 (64) | 向量 ID | `vec_12345` |
|
||||
| `text_content` | 文字 | 純文字內容 | `這是一段話` |
|
||||
| `fps` | 浮點數 | 影片幀率 | `24.0` |
|
||||
| `start_frame` | 整數 | 開始幀數 | `300` |
|
||||
| `end_frame` | 整數 | 結束幀數 | `439` |
|
||||
| `frame_count` | 整數 | 總幀數 | `139` |
|
||||
|
||||
### 2.2 Chunk 類型說明
|
||||
|
||||
| 類型 | ID | 說明 | 來源處理器 |
|
||||
|------|-----|------|-----------|
|
||||
| `sentence` | `sentence` | 語音轉文字片段 | ASR 處理 |
|
||||
| `time` | `time_based` | 固定時間分段 | 系統自動切割 |
|
||||
| `cut` | `cut` | 場景變化片段 | CUT 處理 |
|
||||
| `trace` | `trace` | 軌跡追蹤片段 | YOLO 追蹤處理 |
|
||||
| `story` | `story` | 故事線片段(父子區塊) | Story 分析處理 |
|
||||
|
||||
**父子區塊關係**:
|
||||
- `story` 是**父區塊**,可包含多個 `sentence`、`cut`、`trace` 子區塊
|
||||
- 透過 `parent_chunk_id` 和 `child_chunk_ids` 建立階層關係
|
||||
|
||||
---
|
||||
|
||||
## 3. Content JSON 結構
|
||||
|
||||
每個 Chunk 的 `content` 欄位包含詳細的處理結果:
|
||||
|
||||
### 3.1 ASR Chunk(語音轉文字)
|
||||
|
||||
```json
|
||||
{
|
||||
"text": "今天天氣非常好,我們去郊外踏青吧",
|
||||
"words": [
|
||||
{
|
||||
"word": "今天",
|
||||
"start": 12.5,
|
||||
"end": 12.8,
|
||||
"confidence": 0.95
|
||||
},
|
||||
{
|
||||
"word": "天氣",
|
||||
"start": 12.8,
|
||||
"end": 13.1,
|
||||
"confidence": 0.92
|
||||
}
|
||||
],
|
||||
"language": "zh-TW",
|
||||
"speaker": null
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 Cut Chunk(場景偵測)
|
||||
|
||||
```json
|
||||
{
|
||||
"scenes": [
|
||||
{
|
||||
"scene_id": "cut_001",
|
||||
"start_time": 12.5,
|
||||
"end_time": 45.2,
|
||||
"transition": "cut",
|
||||
"confidence": 0.98
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 Trace Chunk(軌跡追蹤)
|
||||
|
||||
```json
|
||||
{
|
||||
"track_id": "track_001",
|
||||
"object_class": "person",
|
||||
"frames": [
|
||||
{
|
||||
"frame": 300,
|
||||
"bbox": [120, 80, 200, 300],
|
||||
"confidence": 0.95
|
||||
},
|
||||
{
|
||||
"frame": 301,
|
||||
"bbox": [122, 82, 202, 302],
|
||||
"confidence": 0.94
|
||||
}
|
||||
],
|
||||
"total_frames": 180
|
||||
}
|
||||
```
|
||||
|
||||
### 3.4 Story Chunk(故事線)
|
||||
|
||||
```json
|
||||
{
|
||||
"story_id": "story_001",
|
||||
"title": "開場介紹",
|
||||
"summary": "主持人介紹節目主題",
|
||||
"child_chunk_ids": ["sentence_00001", "sentence_00002", "cut_00001"],
|
||||
"tags": ["intro", "host"]
|
||||
}
|
||||
```
|
||||
|
||||
### 3.5 Metadata(其他偵測資訊)
|
||||
|
||||
人臉(Face)、文字辨識(OCR)、姿態(Pose)等偵測結果會附加在 `metadata` 欄位:
|
||||
|
||||
```json
|
||||
{
|
||||
"metadata": {
|
||||
"faces": [
|
||||
{
|
||||
"bbox": [120, 80, 200, 180],
|
||||
"confidence": 0.87,
|
||||
"emotion": "neutral"
|
||||
}
|
||||
],
|
||||
"ocr": {
|
||||
"text": "MOMENTRY",
|
||||
"confidence": 0.96
|
||||
},
|
||||
"pose": {
|
||||
"keypoints": [
|
||||
{"name": "nose", "x": 192, "y": 85, "confidence": 0.95}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 時間格式說明
|
||||
|
||||
### 4.1 秒數格式(常用)
|
||||
|
||||
```
|
||||
格式: 秒.幀數
|
||||
範例: 1234.60 = 第 1234 秒 + 第 60 幀
|
||||
```
|
||||
|
||||
### 4.2 時間軸格式
|
||||
|
||||
```
|
||||
格式: HH:MM:SS.FF
|
||||
範例: 00:20:34.12 = 20分34秒12幀
|
||||
```
|
||||
|
||||
### 4.3 幀數計算
|
||||
|
||||
```
|
||||
幀數 = 秒數 × fps
|
||||
例如: 12.5秒 × 24fps = 300幀
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 實際資料範例
|
||||
|
||||
假設有一個影片,包含以下處理結果:
|
||||
|
||||
### 5.1 語音片段
|
||||
|
||||
```json
|
||||
{
|
||||
"uuid": "952f5854b9febad1",
|
||||
"chunk_id": "asr_00001",
|
||||
"chunk_type": "sentence",
|
||||
"start_time": 12.5,
|
||||
"end_time": 18.3,
|
||||
"content": {
|
||||
"text": "今天天氣非常好,我們去郊外踏青吧",
|
||||
"language": "zh-TW"
|
||||
},
|
||||
"text_content": "今天天氣非常好,我們去郊外踏青吧",
|
||||
"start_frame": 300,
|
||||
"end_frame": 439,
|
||||
"fps": 24.0
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 場景片段
|
||||
|
||||
```json
|
||||
{
|
||||
"uuid": "952f5854b9febad1",
|
||||
"chunk_id": "cut_00001",
|
||||
"chunk_type": "cut",
|
||||
"start_time": 45.0,
|
||||
"end_time": 120.5,
|
||||
"content": {
|
||||
"scenes": [{
|
||||
"scene_id": "cut_001",
|
||||
"transition": "cut",
|
||||
"confidence": 0.98
|
||||
}]
|
||||
},
|
||||
"start_frame": 1080,
|
||||
"end_frame": 2892,
|
||||
"fps": 24.0
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 如何使用 Chunk
|
||||
|
||||
### 6.1 API 取得 Chunk
|
||||
|
||||
使用搜尋 API 取得 Chunk:
|
||||
|
||||
```bash
|
||||
curl -X POST "https://api.momentry.ddns.net/api/v1/search" \
|
||||
-H "X-API-Key: YOUR_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"query": "關鍵字",
|
||||
"limit": 10
|
||||
}'
|
||||
```
|
||||
|
||||
**指定影片搜尋**:
|
||||
```bash
|
||||
curl -X POST "https://api.momentry.ddns.net/api/v1/search" \
|
||||
-H "X-API-Key: YOUR_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"query": "關鍵字",
|
||||
"uuid": "39567a0eb16f39fd",
|
||||
"limit": 5
|
||||
}'
|
||||
```
|
||||
|
||||
### 6.2 搜尋相關片段
|
||||
|
||||
當使用者搜尋「天氣」時,系統會:
|
||||
|
||||
1. 將「天氣」轉換為向量
|
||||
2. 在向量資料庫中搜尋相似向量
|
||||
3. 找到相關的 Chunk
|
||||
4. 返回時間軸和內容
|
||||
|
||||
### 6.3 播放指定片段
|
||||
|
||||
取得 Chunk 後可播放:
|
||||
|
||||
```
|
||||
開始時間: 12.5 秒
|
||||
結束時間: 18.3 秒
|
||||
影片 UUID: 39567a0eb16f39fd
|
||||
```
|
||||
|
||||
**播放器連結格式**:
|
||||
```
|
||||
/player?uuid={uuid}&start={start_time}&end={end_time}
|
||||
```
|
||||
|
||||
### 6.4 組合多個 Chunk
|
||||
|
||||
多個相關 Chunk 可以組合成一個章節或故事線。
|
||||
|
||||
### 6.5 Story Chunk(父子關係)
|
||||
|
||||
Story Chunk 可包含多個子 Chunk:
|
||||
|
||||
```json
|
||||
{
|
||||
"chunk_id": "story_001",
|
||||
"chunk_type": "story",
|
||||
"content": {
|
||||
"story_id": "story_001",
|
||||
"title": "開場介紹",
|
||||
"child_chunk_ids": ["sentence_00001", "sentence_00002", "cut_00001"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. API 回應格式
|
||||
|
||||
### /search 回應
|
||||
|
||||
```json
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"uuid": "39567a0eb16f39fd",
|
||||
"chunk_id": "sentence_1471",
|
||||
"chunk_type": "sentence",
|
||||
"start_time": 5309.08,
|
||||
"end_time": 5311.08,
|
||||
"text": "influenced by a vital way,",
|
||||
"score": 0.68
|
||||
}
|
||||
],
|
||||
"query": "關鍵字"
|
||||
}
|
||||
```
|
||||
|
||||
### /n8n/search 回應
|
||||
|
||||
```json
|
||||
{
|
||||
"query": "關鍵字",
|
||||
"count": 1,
|
||||
"hits": [
|
||||
{
|
||||
"id": "sentence_1471",
|
||||
"vid": "39567a0eb16f39fd",
|
||||
"start": 5309.08,
|
||||
"end": 5311.08,
|
||||
"title": "Chunk sentence_1471",
|
||||
"text": "influenced by a vital way,",
|
||||
"score": 0.68,
|
||||
"file_path": "/Users/accusys/momentry/var/sftpgo/data/demo/video.mp4"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
> **注意**: `file_path` 是影片的實際路徑,可用於本地播放。
|
||||
|
||||
---
|
||||
|
||||
## 8. 快速參考
|
||||
|
||||
| 項目 | 說明 |
|
||||
|------|------|
|
||||
| UUID | 影片唯一識別碼(16位 hex) |
|
||||
| Chunk ID | 片段識別碼(如 `sentence_00001`) |
|
||||
| chunk_type | 片段類型(sentence/time/cut/trace/story) |
|
||||
| start_time | 開始時間(秒) |
|
||||
| end_time | 結束時間(秒) |
|
||||
| text_content | 純文字內容 |
|
||||
| content | 詳細 JSON 結構 |
|
||||
| metadata | 人臉、OCR、姿態等偵測結果 |
|
||||
| parent_chunk_id | 父區塊 ID(用於 story 區塊) |
|
||||
| child_chunk_ids | 子區塊 ID 列表(story 區塊專用) | |
|
||||
|
||||
---
|
||||
|
||||
## 附錄:版本歷史
|
||||
|
||||
| 版本 | 日期 | 內容 | 操作人 |
|
||||
|------|------|------|--------|
|
||||
| V1.0 | 2026-03-25 | 初版建立 | OpenCode |
|
||||
| V1.1 | 2026-03-25 | 新增 API 取得 Chunk 方式、播放連結格式 | OpenCode |
|
||||
553
docs_v1.0/CHUNKING/CORE/CHUNK_DESIGN.md
Normal file
553
docs_v1.0/CHUNKING/CORE/CHUNK_DESIGN.md
Normal file
@@ -0,0 +1,553 @@
|
||||
---
|
||||
document_type: "architecture_design"
|
||||
service: "MOMENTRY_CORE"
|
||||
title: "Momentry Core 數據管理設計文檔 (v4)"
|
||||
date: "2026-03-17"
|
||||
version: "V1.0"
|
||||
status: "active"
|
||||
owner: "Warren"
|
||||
created_by: "OpenCode"
|
||||
tags:
|
||||
- "momentry"
|
||||
- "core"
|
||||
- "數據管理設計文檔"
|
||||
ai_query_hints:
|
||||
- "查詢 Momentry Core 數據管理設計文檔 (v4) 的內容"
|
||||
- "Momentry Core 數據管理設計文檔 (v4) 的主要目的是什麼?"
|
||||
- "如何操作或實施 Momentry Core 數據管理設計文檔 (v4)?"
|
||||
---
|
||||
|
||||
# Momentry Core 數據管理設計文檔 (v4)
|
||||
|
||||
| 項目 | 內容 |
|
||||
|------|------|
|
||||
| 建立者 | Warren |
|
||||
| 建立時間 | 2026-03-17 |
|
||||
| 文件版本 | V1.0 |
|
||||
|
||||
---
|
||||
|
||||
## 版本歷史
|
||||
|
||||
| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
|
||||
|------|------|------|--------|-----------|
|
||||
| V1.0 | 2026-03-17 | 創建文件 | Warren | OpenCode / MiniMax M2.5 |
|
||||
|
||||
---
|
||||
|
||||
## 0. 核心概念:雙 UUID 系統
|
||||
|
||||
為減少資料庫大小,在現有的 videos 表中增加內部 ID 映射:
|
||||
|
||||
### 0.1 設計原則
|
||||
|
||||
- **external_uuid**: 用戶可見的識別碼(如 UUID)
|
||||
- **id**: 資料庫自動產生的內部 ID (SERIAL),節省空間
|
||||
- **映射關係**: 透過 videos 表的 `id` 欄位關聯
|
||||
|
||||
### 0.2 videos 表 (檔案映射表)
|
||||
|
||||
現有結構,增加 `id` 作為內部 ID:
|
||||
|
||||
```sql
|
||||
-- 現有 videos 表結構
|
||||
CREATE TABLE videos (
|
||||
id SERIAL PRIMARY KEY, -- 內部 ID (自動產生)
|
||||
uuid VARCHAR(32) UNIQUE NOT NULL, -- 外部 UUID (用戶可見)
|
||||
file_name VARCHAR(255) NOT NULL,
|
||||
file_path TEXT,
|
||||
duration DOUBLE PRECISION,
|
||||
width INTEGER,
|
||||
height INTEGER,
|
||||
fps DOUBLE PRECISION,
|
||||
probe_json JSONB,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_videos_uuid ON videos(uuid);
|
||||
```
|
||||
|
||||
### 0.3 對照的好處
|
||||
|
||||
| 方式 | 儲存空間 (1000個視頻,每個1000個chunk) |
|
||||
|------|---------------------------------------|
|
||||
| 直接用 uuid (32字元) | ~32MB |
|
||||
| 使用 id (4字元) | ~4MB |
|
||||
|
||||
## 1. 數據流架構
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ 輸入階段 │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ 視頻文件 │→ │ ffprobe │ │ ASR │ │ YOLO │ │
|
||||
│ │ (.mp4) │→ │ (probe) │→ │ (asr) │→ │ (yolo) │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ ASRX │ │ CUT │ │ OCR │ │ FACE │ │
|
||||
│ │ (asrx) │→ │ (cut) │→ │ (ocr) │→ │ (face) │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Pre-Chunk / Frame 階段 │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ pre_chunks 表 │ │
|
||||
│ │ file_id → videos.id (FK) │ │
|
||||
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
|
||||
│ │ │ type=sentence │ from asr, asrx │ 句子邊界範圍 │ │ │
|
||||
│ │ │ type=cut │ from cut detection │ 場景切換範圍 │ │ │
|
||||
│ │ │ type=time │ from time split │ 固定時間範圍 (10s) │ │ │
|
||||
│ │ │ type=trace │ from yolo trace │ 物件追蹤範圍 │ │ │
|
||||
│ │ └─────────────────────────────────────────────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ frames 表 │ │
|
||||
│ │ file_id → videos.id (FK) │ │
|
||||
│ │ - yolo 每幀識別結果 │ │
|
||||
│ │ - ocr 每幀識別結果 │ │
|
||||
│ │ - face 每幀識別結果 (如需要) │ │
|
||||
│ │ - 單一圖像識別結果 → 直接入 frame │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Chunk 階段 │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ chunks 表 │ │
|
||||
│ │ file_id → videos.id (FK) │ │
|
||||
│ │ │ │
|
||||
│ │ 組合規則1: pre_chunk → chunk (直接轉換) │ │
|
||||
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
|
||||
│ │ │ sentence_pre_chunk → sentence_chunk │ │ │
|
||||
│ │ │ cut_pre_chunk → cut_chunk │ │ │
|
||||
│ │ │ time_pre_chunk → time_chunk │ │ │
|
||||
│ │ │ trace_pre_chunk → trace_chunk │ │ │
|
||||
│ │ └─────────────────────────────────────────────────────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ │ 組合規則2: pre_chunk + frame 內容 → chunk (集合內容) │ │
|
||||
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
|
||||
│ │ │ sentence_pre_chunk + 涵蓋範圍內的 frames → 豐富的 sentence_chunk │ │ │
|
||||
│ │ │ time_pre_chunk + 涵蓋範圍內的 frames → 豐富的 time_chunk │ │ │
|
||||
│ │ └─────────────────────────────────────────────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Vector 階段 │
|
||||
│ ┌──────────────────────┐ ┌──────────────────────┐ │
|
||||
│ │ PostgreSQL vectors │ │ Qdrant vectors │ │
|
||||
│ │ (chunk_vectors) │ │ (chunk_v3) │ │
|
||||
│ └──────────────────────┘ └──────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 2. Pre-Chunk 類型定義
|
||||
|
||||
### 2.1 Pre-Chunk 來源與類型對照表
|
||||
|
||||
| 來源類型 | source_type | 產出 Pre-Chunk Type | 說明 |
|
||||
|---------|-------------|---------------------|------|
|
||||
| ASR ( Whisper ) | asr | sentence | 句子邊界 |
|
||||
| ASRX ( with timestamps ) | asrx | sentence | 帶時間戳的句子 |
|
||||
| CUT (場景檢測) | cut | cut | 場景切換點 |
|
||||
| TIME (固定時間) | time | time | 每 10 秒 |
|
||||
| YOLO Trace | yolo_trace | trace | 物件追蹤軌跡 |
|
||||
| YOLO (單幀) | yolo | **→ frame** | 不入 pre_chunk |
|
||||
| OCR (單幀) | ocr | **→ frame** | 不入 pre_chunk |
|
||||
| FACE (單幀) | face | **→ frame** | 不入 pre_chunk |
|
||||
| PROBE | probe | metadata | 視頻元數據 |
|
||||
|
||||
### 2.2 Pre-Chunk Schema
|
||||
|
||||
```sql
|
||||
CREATE TABLE pre_chunks (
|
||||
id SERIAL PRIMARY KEY,
|
||||
|
||||
-- 檔案識別 (使用 videos 表的內部 ID 以節省空間)
|
||||
file_id INTEGER NOT NULL REFERENCES videos(id),
|
||||
|
||||
-- 來源識別
|
||||
source_type VARCHAR(32) NOT NULL, -- 'asr', 'asrx', 'cut', 'time', 'yolo_trace', 'probe'
|
||||
source_file TEXT, -- 原始 JSON 文件路徑
|
||||
|
||||
-- Chunk 類型
|
||||
chunk_type VARCHAR(32) NOT NULL, -- 'sentence' (ChunkType::Sentence), 'cut' (ChunkType::Cut), 'time' (ChunkType::TimeBased), 'trace' (ChunkType::Trace), 'story' (ChunkType::Story)
|
||||
|
||||
-- 時間範圍
|
||||
start_time DOUBLE PRECISION NOT NULL,
|
||||
end_time DOUBLE PRECISION NOT NULL,
|
||||
|
||||
-- Frame 範圍 (精確到 frame)
|
||||
start_frame INTEGER NOT NULL,
|
||||
end_frame INTEGER NOT NULL,
|
||||
|
||||
-- FPS (用於 frame 計算)
|
||||
fps DOUBLE PRECISION NOT NULL,
|
||||
|
||||
-- 原始 JSON 內容
|
||||
raw_json JSONB NOT NULL,
|
||||
|
||||
-- 解析後的文字內容 (如有)
|
||||
text_content TEXT,
|
||||
|
||||
-- 處理狀態
|
||||
processed BOOLEAN DEFAULT FALSE,
|
||||
chunk_id VARCHAR(64), -- 轉換後的 chunk_id
|
||||
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
UNIQUE(file_id, source_type, start_frame, end_frame)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_pre_chunks_file_id ON pre_chunks(file_id);
|
||||
CREATE INDEX idx_pre_chunks_type ON pre_chunks(file_id, chunk_type);
|
||||
CREATE INDEX idx_pre_chunks_time ON pre_chunks(file_id, start_time, end_time);
|
||||
CREATE INDEX idx_pre_chunks_frame ON pre_chunks(file_id, start_frame, end_frame);
|
||||
CREATE INDEX idx_pre_chunks_processed ON pre_chunks(file_id, processed);
|
||||
```
|
||||
|
||||
## 3. Frame 管理原則
|
||||
|
||||
### 3.1 哪些數據進入 Frame
|
||||
|
||||
只儲存**單一圖像識別**的結果:
|
||||
- YOLO 每幀檢測結果
|
||||
- OCR 每幀識別結果
|
||||
- FACE 每幀檢測結果
|
||||
|
||||
### 3.2 Frame Schema
|
||||
|
||||
```sql
|
||||
CREATE TABLE frames (
|
||||
id SERIAL PRIMARY KEY,
|
||||
|
||||
-- 檔案識別 (使用 videos 表的內部 ID 以節省空間)
|
||||
file_id INTEGER NOT NULL REFERENCES videos(id),
|
||||
|
||||
frame_number INTEGER NOT NULL,
|
||||
timestamp DOUBLE PRECISION NOT NULL,
|
||||
fps DOUBLE PRECISION NOT NULL,
|
||||
|
||||
-- YOLO 結果 (JSONB 陣列)
|
||||
yolo_objects JSONB,
|
||||
|
||||
-- OCR 結果 (JSONB 陣列)
|
||||
ocr_results JSONB,
|
||||
|
||||
-- Face 結果 (JSONB 陣列)
|
||||
face_results JSONB,
|
||||
|
||||
-- 原始幀圖像路徑 (可選)
|
||||
frame_path TEXT,
|
||||
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
UNIQUE(file_id, frame_number)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_frames_file_id ON frames(file_id);
|
||||
CREATE INDEX idx_frames_frame ON frames(file_id, frame_number);
|
||||
CREATE INDEX idx_frames_timestamp ON frames(file_id, timestamp);
|
||||
```
|
||||
|
||||
## 4. Chunk 組合規則
|
||||
|
||||
### 4.1 組合規則 1: 直接轉換 (rule_1)
|
||||
|
||||
將 pre_chunk 直接轉換為 chunk:
|
||||
|
||||
```
|
||||
sentence_pre_chunk → sentence_chunk (rule: "rule_1")
|
||||
cut_pre_chunk → cut_chunk (rule: "rule_1")
|
||||
time_pre_chunk → time_chunk (rule: "rule_1")
|
||||
trace_pre_chunk → trace_chunk (rule: "rule_1")
|
||||
```
|
||||
|
||||
### 4.2 組合規則 2: 集合內容 (rule_2)
|
||||
|
||||
將 pre_chunk 與其時間區間內的所有 frame 識別結果集合:
|
||||
|
||||
```
|
||||
sentence_pre_chunk + frames[在 start_time~end_time 範圍內] → 豐富的 sentence_chunk (rule: "rule_2")
|
||||
time_pre_chunk + frames[在 start_time~end_time 範圍內] → 豐富的 time_chunk (rule: "rule_2")
|
||||
```
|
||||
|
||||
### 4.3 Chunk Schema
|
||||
|
||||
```sql
|
||||
CREATE TABLE chunks (
|
||||
id SERIAL PRIMARY KEY,
|
||||
|
||||
-- 檔案識別 (使用 videos 表的內部 ID 以節省空間)
|
||||
file_id INTEGER NOT NULL REFERENCES videos(id),
|
||||
|
||||
chunk_id VARCHAR(64) NOT NULL,
|
||||
chunk_index INTEGER NOT NULL,
|
||||
chunk_type VARCHAR(32) NOT NULL, -- 'sentence' (ChunkType::Sentence), 'cut' (ChunkType::Cut), 'time' (ChunkType::TimeBased), 'trace' (ChunkType::Trace)
|
||||
|
||||
-- 組合規則 (payload 中記錄)
|
||||
-- rule: 'rule_1' = 直接轉換, 'rule_2' = 集合內容
|
||||
|
||||
-- 時間範圍
|
||||
start_time DOUBLE PRECISION NOT NULL,
|
||||
end_time DOUBLE PRECISION NOT NULL,
|
||||
|
||||
-- Frame 範圍 (精確到 frame)
|
||||
start_frame INTEGER NOT NULL,
|
||||
end_frame INTEGER NOT NULL,
|
||||
|
||||
-- FPS
|
||||
fps DOUBLE PRECISION NOT NULL,
|
||||
|
||||
-- 主要內容
|
||||
text_content TEXT,
|
||||
|
||||
-- 完整內容 (JSONB) - 包含 rule 欄位
|
||||
content JSONB NOT NULL,
|
||||
|
||||
-- 來源的 pre_chunk IDs
|
||||
pre_chunk_ids INTEGER[],
|
||||
|
||||
-- 包含的 frame 數量
|
||||
frame_count INTEGER DEFAULT 0,
|
||||
|
||||
-- 向量 ID
|
||||
vector_id VARCHAR(64),
|
||||
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
UNIQUE(file_id, chunk_id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_chunks_file_id ON chunks(file_id);
|
||||
CREATE INDEX idx_chunks_type ON chunks(file_id, chunk_type);
|
||||
CREATE INDEX idx_chunks_time ON chunks(file_id, start_time, end_time);
|
||||
CREATE INDEX idx_chunks_frame ON chunks(file_id, start_frame, end_frame);
|
||||
CREATE INDEX idx_chunks_vector ON chunks(vector_id);
|
||||
```
|
||||
|
||||
## 5. 處理流程範例
|
||||
|
||||
### 5.1 輸入數據
|
||||
|
||||
假設視頻長度 30 秒,fps=30:
|
||||
|
||||
| 來源 | 產出 |
|
||||
|------|------|
|
||||
| ASR | 3 個 sentence_pre_chunk (每句約 10s) |
|
||||
| CUT | 2 個 cut_pre_chunk (場景 1, 場景 2) |
|
||||
| TIME | 3 個 time_pre_chunk (0-10s, 10-20s, 20-30s) |
|
||||
| YOLO | 900 個 frame 記錄 (每幀) |
|
||||
| OCR | 依實際識別結果入 frame |
|
||||
|
||||
### 5.2 Chunk 產出
|
||||
|
||||
**使用規則 1 (直接轉換):**
|
||||
- rule: "rule_1"
|
||||
- 3 個 sentence_chunk
|
||||
- 2 個 cut_chunk
|
||||
- 3 個 time_chunk
|
||||
|
||||
**使用規則 2 (集合內容):**
|
||||
- rule: "rule_2"
|
||||
- 3 個 sentence_chunk (各含涵蓋時間範圍內的 yolo/ocr 結果)
|
||||
- 3 個 time_chunk (各含涵蓋時間範圍內的 yolo/ocr 結果)
|
||||
|
||||
## 8. 數據示例
|
||||
|
||||
### 8.1 videos 表 (檔案映射)
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"uuid": "abc123def456",
|
||||
"file_name": "video_001.mp4",
|
||||
"file_path": "/path/to/video_001.mp4",
|
||||
"duration": 300.5,
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"fps": 30.0
|
||||
}
|
||||
```
|
||||
|
||||
### 8.2 pre_chunks 表 (使用 file_id 關聯 videos)
|
||||
|
||||
```json
|
||||
{
|
||||
"file_id": 1,
|
||||
"source_type": "asr",
|
||||
"chunk_type": "sentence",
|
||||
"start_time": 0.0,
|
||||
"end_time": 5.5,
|
||||
"start_frame": 0,
|
||||
"end_frame": 165,
|
||||
"fps": 30.0,
|
||||
"raw_json": {...},
|
||||
"text_content": "This is the first sentence"
|
||||
}
|
||||
```
|
||||
|
||||
### 8.3 frames 表 (使用 file_id 關聯 videos)
|
||||
|
||||
```json
|
||||
{
|
||||
"file_id": 1,
|
||||
"frame_number": 300,
|
||||
"timestamp": 10.0,
|
||||
"fps": 30.0,
|
||||
"yolo_objects": [
|
||||
{"class": "person", "confidence": 0.9, "bbox": [100, 50, 200, 150]},
|
||||
{"class": "car", "confidence": 0.85, "bbox": [50, 100, 150, 180]}
|
||||
],
|
||||
"ocr_results": [],
|
||||
"face_results": []
|
||||
}
|
||||
```
|
||||
|
||||
### 8.4 chunks 表 (使用 file_id 關聯 videos)
|
||||
|
||||
```json
|
||||
{
|
||||
"file_id": 1,
|
||||
"chunk_id": "sentence_0001",
|
||||
"chunk_type": "sentence",
|
||||
"rule": "rule_2",
|
||||
"start_time": 10.0,
|
||||
"end_time": 15.5,
|
||||
"start_frame": 300,
|
||||
"end_frame": 465,
|
||||
"fps": 30.0,
|
||||
"text_content": "The second sentence from the audio",
|
||||
"content": {
|
||||
"rule": "rule_2",
|
||||
"asr_text": "The second sentence from the audio",
|
||||
"objects": [
|
||||
{"class": "person", "first_frame": 300, "last_frame": 450, "appears_in_frames": [300, 310, 320, ...]},
|
||||
{"class": "car", "first_frame": 350, "last_frame": 465, "appears_in_frames": [350, 360, ...]}
|
||||
],
|
||||
"ocr": [...],
|
||||
"faces": [...]
|
||||
},
|
||||
"pre_chunk_ids": [5],
|
||||
"frame_count": 301
|
||||
}
|
||||
```
|
||||
|
||||
### 8.5 chunk_vectors 表 (使用 file_id 關聯 videos)
|
||||
|
||||
```json
|
||||
{
|
||||
"file_id": 1,
|
||||
"chunk_id": "sentence_0001",
|
||||
"chunk_type": "sentence",
|
||||
"start_time": 10.0,
|
||||
"end_time": 15.5,
|
||||
"embedding": "[0.1, 0.2, ...]",
|
||||
"metadata": {"text": "The second sentence..."}
|
||||
}
|
||||
```
|
||||
|
||||
### 8.6 Qdrant Payload
|
||||
|
||||
```json
|
||||
{
|
||||
"file_uuid": "abc123def456",
|
||||
"chunk_id": "sentence_0001",
|
||||
"chunk_type": "sentence",
|
||||
"start_time": 10.0,
|
||||
"end_time": 15.5,
|
||||
"text": "The second sentence from the audio"
|
||||
}
|
||||
```
|
||||
|
||||
## 7. 向量管理原則
|
||||
|
||||
### 7.1 Vector Schema
|
||||
|
||||
```sql
|
||||
-- Chunk 向量表 (PostgreSQL)
|
||||
CREATE TABLE chunk_vectors (
|
||||
id SERIAL PRIMARY KEY,
|
||||
|
||||
-- 檔案識別 (使用 videos 表的內部 ID 以節省空間)
|
||||
file_id INTEGER NOT NULL REFERENCES videos(id),
|
||||
|
||||
chunk_id VARCHAR(64) NOT NULL,
|
||||
chunk_type VARCHAR(32) NOT NULL,
|
||||
|
||||
-- 向量數據
|
||||
embedding TEXT, -- JSON 格式的向量
|
||||
embedding_vector VECTOR(768), -- pgvector 類型 (如可用)
|
||||
|
||||
-- 時間範圍 (用於時間查詢)
|
||||
start_time DOUBLE PRECISION,
|
||||
end_time DOUBLE PRECISION,
|
||||
|
||||
-- Metadata
|
||||
metadata JSONB,
|
||||
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
UNIQUE(chunk_id)
|
||||
);
|
||||
|
||||
-- 索引
|
||||
CREATE INDEX idx_chunk_vectors_file_id ON chunk_vectors(file_id);
|
||||
```
|
||||
|
||||
### 7.2 Qdrant Collection
|
||||
|
||||
- Collection 名稱: `chunks_v3`
|
||||
- Vector 維度: 768 (nomic-embed-text)
|
||||
- Payload 包含: `file_uuid`, `chunk_id`, `chunk_type`, `start_time`, `end_time`, `text`
|
||||
|
||||
> **注意**: Qdrant 中仍使用 uuid (字串),因為需要可讀性和跨系統整合。PostgreSQL 內部使用 videos.id (整數) 以節省空間。
|
||||
|
||||
## 9. 設計原則總結
|
||||
|
||||
1. **單一圖像識別 → Frame**: yolo, ocr, face 等單幀識別結果直接入 frame 表
|
||||
2. **時間序列識別 → Pre-Chunk**: asr, asrx, cut, time, trace 等有時間範圍的結果入 pre_chunk 表
|
||||
3. **組合規則 1 (直接)**: pre_chunk → chunk (保持原有邊界)
|
||||
4. **組合規則 2 (集合)**: pre_chunk + frames → chunk (加入識別內容)
|
||||
5. **精確到 Frame**: 所有時間範圍都記錄 start_frame, end_frame
|
||||
6. **雙向量存儲**: 同時支持 PostgreSQL 和 Qdrant
|
||||
7. **跨視頻搜索**: 透過 videos 表的 uuid 進行搜索,內部使用 id 節省空間
|
||||
8. **空間優化**: 內部表使用 videos.id (4 bytes) 而非 uuid (32 bytes)
|
||||
|
||||
## 10. 查詢範例
|
||||
|
||||
### 10.1 跨視頻搜索所有 chunk
|
||||
|
||||
```sql
|
||||
-- 搜索所有視頻中包含 "hello" 的 chunk
|
||||
SELECT c.*, v.uuid, v.file_name
|
||||
FROM chunks c
|
||||
JOIN videos v ON c.file_id = v.id
|
||||
WHERE c.text_content ILIKE '%hello%';
|
||||
```
|
||||
|
||||
### 10.2 查詢特定視頻的 chunk
|
||||
|
||||
```sql
|
||||
-- 查詢 uuid 為 'abc123' 的視頻的所有 chunk
|
||||
SELECT c.*
|
||||
FROM chunks c
|
||||
JOIN videos v ON c.file_id = v.id
|
||||
WHERE v.uuid = 'abc123';
|
||||
```
|
||||
|
||||
### 10.3 按時間範圍搜索
|
||||
|
||||
```sql
|
||||
-- 搜索所有視頻在 10-20 秒範圍內的 chunk
|
||||
SELECT c.*, v.uuid
|
||||
FROM chunks c
|
||||
JOIN videos v ON c.file_id = v.id
|
||||
WHERE c.start_time >= 10.0 AND c.end_time <= 20.0;
|
||||
```
|
||||
185
docs_v1.0/CHUNKING/CORE/CHUNK_RULES_SPEC.md
Normal file
185
docs_v1.0/CHUNKING/CORE/CHUNK_RULES_SPEC.md
Normal file
@@ -0,0 +1,185 @@
|
||||
---
|
||||
document_type: "reference_doc"
|
||||
service: "MOMENTRY_CORE"
|
||||
title: "Unknown"
|
||||
date: "2026-03-28"
|
||||
version: "V1.0"
|
||||
status: "active"
|
||||
owner: "Warren"
|
||||
created_by: "OpenCode"
|
||||
tags:
|
||||
- "unknown"
|
||||
ai_query_hints:
|
||||
- "查詢 Unknown 的內容"
|
||||
- "Unknown 的主要目的是什麼?"
|
||||
- "如何操作或實施 Unknown?"
|
||||
---
|
||||
|
||||
---
|
||||
title: Chunk Rules 規範總覽
|
||||
description: Momentry Core Chunk 組合規則規範與 Collection 對應
|
||||
version: 1.0
|
||||
created: 2026-03-28
|
||||
updated: 2026-03-28
|
||||
service: MOMENTRY_CORE
|
||||
topic: chunk_rules
|
||||
document_type: spec
|
||||
ai_agent_friendly: true
|
||||
---
|
||||
|
||||
# Chunk Rules 規範總覽
|
||||
|
||||
| 項目 | 內容 |
|
||||
|------|------|
|
||||
| 建立者 | OpenCode |
|
||||
| 建立時間 | 2026-03-28 |
|
||||
| 文件版本 | V1.0 |
|
||||
|
||||
---
|
||||
|
||||
## 版本歷史
|
||||
|
||||
| 版本 | 日期 | 目的 | 操作人 |
|
||||
|------|------|------|--------|
|
||||
| V1.0 | 2026-03-28 | 創建 Chunk Rules 規範總覽 | OpenCode |
|
||||
|
||||
---
|
||||
|
||||
## 概述
|
||||
|
||||
本文檔定義 Momentry Core 系統中 Chunk 向量入庫的組合規則。每個規則對應一個獨立的 Qdrant Collection。
|
||||
|
||||
---
|
||||
|
||||
## 規則總覽
|
||||
|
||||
| Rule | 名稱 | 說明 | Collection | 嵌入模型 |
|
||||
|------|------|------|------------|----------|
|
||||
| **Rule 1** | Simple | 直接轉換,無父子關係,無 frame objects | `momentry_rule1` | `nomic-embed-text-v2-moe:latest` |
|
||||
| **Rule 2** | Frame Objects | 涵蓋 frames,conf > 0.8 的物件加入字串 | `momentry_rule2` | `nomic-embed-text-v2-moe:latest` |
|
||||
| **Rule 3** | Composite | 父子關係 + frame_objects | `momentry_rule3` | `nomic-embed-text-v2-moe:latest` |
|
||||
|
||||
---
|
||||
|
||||
## Collection 對應
|
||||
|
||||
### 命名規範
|
||||
|
||||
```
|
||||
momentry_rule{rule_id}
|
||||
```
|
||||
|
||||
### Collection 列表
|
||||
|
||||
| Collection | Rule | 向量維度 | Distance | 嵌入模型 | 多語言支持 |
|
||||
|------------|------|----------|----------|----------|------------|
|
||||
| `momentry_rule1` | Rule 1 | 768 | Cosine | `nomic-embed-text-v2-moe:latest` | ✅ |
|
||||
| `momentry_rule2` | Rule 2 | 768 | Cosine | `nomic-embed-text-v2-moe:latest` | ✅ |
|
||||
| `momentry_rule3` | Rule 3 | 768 | Cosine | `nomic-embed-text-v2-moe:latest` | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## Payload 欄位說明
|
||||
|
||||
### 共同欄位
|
||||
|
||||
| 欄位 | 類型 | 說明 |
|
||||
|------|------|------|
|
||||
| `uuid` | String | 影片 UUID |
|
||||
| `chunk_id` | String | Chunk 唯一 ID |
|
||||
| `chunk_type` | String | 類型:sentence/cut/time_based |
|
||||
| `chunk_index` | u32 | Chunk 索引 |
|
||||
| `start_frame` | i64 | 開始幀編號 |
|
||||
| `end_frame` | i64 | 結束幀編號 |
|
||||
| `fps` | f64 | 幀率 |
|
||||
| `original_text` | String | 產生 vector 的原始文字 (ASR) |
|
||||
|
||||
### Rule 2+ 專有欄位
|
||||
|
||||
| 欄位 | 類型 | 說明 |
|
||||
|------|------|------|
|
||||
| `frame_objects` | String | 涵蓋 frames 的物件描述 (conf > 0.8) |
|
||||
|
||||
### Rule 3 專有欄位
|
||||
|
||||
| 欄位 | 類型 | 說明 |
|
||||
|------|------|------|
|
||||
| `parent_chunk_id` | Option<String> | 父 Chunk ID |
|
||||
| `child_chunk_ids` | Vec<String> | 子 Chunk IDs |
|
||||
|
||||
---
|
||||
|
||||
## Payload 對照表
|
||||
|
||||
| 欄位 | Rule 1 | Rule 2 | Rule 3 |
|
||||
|------|--------|--------|--------|
|
||||
| uuid | ✅ | ✅ | ✅ |
|
||||
| chunk_id | ✅ | ✅ | ✅ |
|
||||
| chunk_type | ✅ | ✅ | ✅ |
|
||||
| chunk_index | ✅ | ✅ | ✅ |
|
||||
| start_frame | ✅ | ✅ | ✅ |
|
||||
| end_frame | ✅ | ✅ | ✅ |
|
||||
| fps | ✅ | ✅ | ✅ |
|
||||
| original_text | ✅ | ✅ | ✅ |
|
||||
| frame_objects | - | ✅ | ✅ |
|
||||
| parent_chunk_id | - | - | ✅ |
|
||||
| child_chunk_ids | - | - | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## 時間計算
|
||||
|
||||
### Frame 轉時間
|
||||
|
||||
```
|
||||
start_time = start_frame / fps
|
||||
end_time = end_frame / fps
|
||||
```
|
||||
|
||||
### 範例
|
||||
|
||||
```
|
||||
- fps = 24.0
|
||||
- start_frame = 252
|
||||
- end_frame = 378
|
||||
- start_time = 252 / 24.0 = 10.5 秒
|
||||
- end_time = 378 / 24.0 = 15.75 秒
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 選擇標準
|
||||
|
||||
### Rule 1 (Simple)
|
||||
|
||||
- 用途:最基本的向量搜尋
|
||||
- 場景:僅需要 ASR 文字內容進行語義搜尋
|
||||
- 優點:資料量最小,搜尋速度最快
|
||||
|
||||
### Rule 2 (Frame Objects)
|
||||
|
||||
- 用途:需要物體識別結果輔助搜尋
|
||||
- 場景:需要根據影片中的物件(人、車、動物)進行搜尋
|
||||
- 優點:結合 ASR + 物件辨識結果
|
||||
|
||||
### Rule 3 (Composite)
|
||||
|
||||
- 用途:需要父子層級關係和完整資訊
|
||||
- 場景:需要跨層級搜尋、父子關係分析
|
||||
- 優點:最完整的資訊,但資料量最大
|
||||
|
||||
---
|
||||
|
||||
## 相關文件
|
||||
|
||||
| 文件 | 用途 |
|
||||
|------|------|
|
||||
| CHUNK_RULE_1_SIMPLE.md | Rule 1 詳細規範 |
|
||||
| CHUNK_RULE_2_FRAME_OBJECTS.md | Rule 2 詳細規範 |
|
||||
| CHUNK_RULE_3_COMPOSITE.md | Rule 3 詳細規範 |
|
||||
| CHUNK_SPEC.md | Chunk 基礎規範 |
|
||||
| CHUNK_DESIGN.md | Chunk 設計架構 |
|
||||
|
||||
---
|
||||
|
||||
**文件結束**
|
||||
1132
docs_v1.0/CHUNKING/CORE/CHUNK_SPEC.md
Normal file
1132
docs_v1.0/CHUNKING/CORE/CHUNK_SPEC.md
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user