docs: update docs_v1.0/ documentation

- Fix markdown lint issues (MD030, MD047, MD051, MD028, MD005)
- Update AI agents, architecture, implementation docs
- Add new identity, face recognition, and API documentation
- Remove deprecated face/person API guides
This commit is contained in:
Warren
2026-04-30 15:10:41 +08:00
parent 8f05a7c188
commit 4d75b2e251
185 changed files with 21071 additions and 1605 deletions
@@ -12,13 +12,13 @@
### 1.1 目前行為
目前系統的 Processor (如 YOLO, Face, OCR) **不支援高效續傳**
* **中斷處理**: 若處理過程因主動 (使用者取消) 或被動 (OOM, Crash) 中斷,重新執行時通常會**從頭開始 (Frame 0)**。
* **效能瓶頸**: 對於長影片,中斷後重新解碼和運算前 90% 的幀是巨大的資源浪費。
* **中斷處理**: 若處理過程因主動 (使用者取消) 或被動 (OOM, Crash) 中斷,重新執行時通常會**從頭開始 (Frame 0)**。
* **效能瓶頸**: 對於長影片,中斷後重新解碼和運算前 90% 的幀是巨大的資源浪費。
### 1.2 缺失環節
* **缺乏狀態記錄**: 處理器未記錄「已處理到第幾幀」。
* **缺乏增量寫入**: 輸出檔案通常為全量 JSON,無法在尾部追加新數據而不破壞格式。
* **缺乏跳轉指令**: Worker 啟動腳本時未傳遞 `--start-frame` 參數。
* **缺乏狀態記錄**: 處理器未記錄「已處理到第幾幀」。
* **缺乏增量寫入**: 輸出檔案通常為全量 JSON,無法在尾部追加新數據而不破壞格式。
* **缺乏跳轉指令**: Worker 啟動腳本時未傳遞 `--start-frame` 參數。
---
@@ -26,9 +26,9 @@
設計目標:**Checkpoints (檢查點) + Append Mode (追加模式)**
* **Checkpoint**: 定期將當前進度 (`current_frame`) 寫入獨立檔案或 Redis。
* **Seek**: 啟動時若發現進度記錄,使用 OpenCV `set(CAP_PROP_POS_FRAMES)` 快速跳轉。
* **Append**: 結果輸出採用 **JSON Lines (.jsonl)** 格式,避免中斷導致 JSON 結構損壞,且支援尾部追加。
* **Checkpoint**: 定期將當前進度 (`current_frame`) 寫入獨立檔案或 Redis。
* **Seek**: 啟動時若發現進度記錄,使用 OpenCV `set(CAP_PROP_POS_FRAMES)` 快速跳轉。
* **Append**: 結果輸出採用 **JSON Lines (.jsonl)** 格式,避免中斷導致 JSON 結構損壞,且支援尾部追加。
---
@@ -48,7 +48,7 @@ output/vid_001/
### 3.2 yolo_progress.json 結構
```json
{
"video_uuid": "vid_001",
"file_uuid": "vid_001",
"processor": "yolo",
"last_frame_index": 12500,
"last_timestamp": 416.66,
@@ -174,7 +174,7 @@ if is_resume {
#### B. 後處理 (Post-Processing)
Processor 完成後,若輸出為 `.jsonl`,需轉換為系統預期的 `.json` (List of Objects) 以便存入 DB。
* *Optimization*: 可以在 Rust 端直接 `BufRead` 解析 JSONL 並批次 Insert DB,無需轉換檔案。
* *Optimization*: 可以在 Rust 端直接 `BufRead` 解析 JSONL 並批次 Insert DB,無需轉換檔案。
---
@@ -182,21 +182,21 @@ Processor 完成後,若輸出為 `.jsonl`,需轉換為系統預期的 `.json
目前的 `monitor_jobs``processor_results` 表需支援**部分完成**的語意。
* **新增欄位**: `processed_frames` (BIGINT) 於 `processor_results``jobs` 表。
* **用途**: Worker 定期讀取 `progress.json` 並更新此欄位,以便前端顯示「處理進度 25%」。
* **新增欄位**: `processed_frames` (BIGINT) 於 `processor_results``jobs` 表。
* **用途**: Worker 定期讀取 `progress.json` 並更新此欄位,以便前端顯示「處理進度 25%」。
---
## 6. 優勢分析
1. **容錯性**: 即使伺服器斷電,重啟後僅損失最近 30 幀 (約 1 秒) 的運算結果。
2. **I/O 效率**: 採用 Append 寫入,避免每次都重寫巨大的 JSON 檔案。
3. **資源節約**: OpenCV 的 `seek` 操作比重新解碼快數百倍。
4. **靈活性**: 支援主動暫停 (Pause),只需發送 `SIGINT` 讓腳本安全退出即可。
1. **容錯性**: 即使伺服器斷電,重啟後僅損失最近 30 幀 (約 1 秒) 的運算結果。
2. **I/O 效率**: 採用 Append 寫入,避免每次都重寫巨大的 JSON 檔案。
3. **資源節約**: OpenCV 的 `seek` 操作比重新解碼快數百倍。
4. **靈活性**: 支援主動暫停 (Pause),只需發送 `SIGINT` 讓腳本安全退出即可。
---
## 版本資訊
- 版本: V1.0
- 建立日期: 2026-04-25
* 版本: V1.0
* 建立日期: 2026-04-25
@@ -0,0 +1,321 @@
---
document_type: "reference_doc"
service: "MOMENTRY_CORE"
title: "Processor 升級分析報告"
date: "2026-04-27"
version: "V1.0"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "processor"
- "agent"
- "upgrade"
- "identity-agent"
- "三層架構"
ai_query_hints:
- "查詢 Processor 升級分析報告的內容"
- "Processor 是否需要升級到 Agent"
- "Identity Agent 設計方案"
- "三層架構 Processor 分析"
- "Face Clustering 升級建議"
- "ASRX 升級建議"
related_documents:
- "AI_AGENTS/CORE/AGENT_SPEC.md"
- "AI_AGENTS/IDENTITY/FACE_SPEAKER_PERSON_WORKFLOW.md"
- "PROCESSORS/_CORE/PROCESSOR_RESUME_STRATEGY.md"
---
# Processor 升級分析報告
| 項目 | 內容 |
|------|------|
| 建立者 | OpenCode |
| 建立時間 | 2026-04-27 |
| 文件版本 | V1.0 |
---
## 版本歷史
| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
|------|------|------|--------|-----------|
| V1.0 | 2026-04-27 | 分析 Processor 是否需要迭代或升級到 Agent | OpenCode | GLM-5 |
---
## 概述
本文檔分析 Momentry Core 系統中所有 Processor 的架構定位,判斷是否需要迭代或升級為 Agent。
---
## 當前狀態
| 項目 | 狀態 |
|------|------|
| Processor 總數 | 17 個 |
| 總代碼行數 | 4947 行 |
| 已添加 Resume 支持 | YOLO, OCR, Face |
| 待添加 Resume 支持 | Pose, CUT, ASRX |
---
## 1. Processor 三層架構分類
根據 `AGENT_SPEC.md` 定義的三層架構:
| 層次 | 名稱 | 特性 | 範例 |
|------|------|------|------|
| **L1** | **Processor (處理器)** | **確定性 (Deterministic)**<br>輸入 A 必得輸出 B | FFmpeg, Whisper, YOLO |
| **L2** | **Rule (規則)** | **邏輯性 (Logic)**<br>基於明確條件、正則表達式、時間軸聚合 | 語句切分,時間重疊計算 |
| **L3** | **Agent (智能體)** | **推論性 (Probabilistic)**<br>依賴 LLM 進行語義理解、決策或生成 | 5W1H 推論,身份解析 |
---
## 2. Processor 分類分析表
| Processor | 文件行數 | 當前層級 | 特性分析 | 是否需要升級 |
|-----------|----------|----------|----------|--------------|
| **asr_processor.py** | 126 | L1 (Processor) | 確定性:Whisper 模型,輸入音頻→輸出文本 | ❌ 不需要升級 |
| **asrx_processor.py** | 124 | L1 (Processor) | 確定性:WhisperX,輸入音頻→輸出 speaker segments | ⚠️ 需與 Identity Agent 結合 |
| **yolo_processor.py** | 483 | L1 (Processor) | 確定性:YOLOv8,輸入帧→輸出檢測結果(已支持 Resume) | ❌ 不需要升級 |
| **ocr_processor.py** | 245 | L1 (Processor) | 確定性:EasyOCR,輸入帧→輸出文字(已支持 Resume) | ❌ 不需要升級 |
| **face_processor.py** | 297 | L1 (Processor) | 確定性:InsightFace,輸入帧→輸出人脸(已支持 Resume) | ❌ 不需要升級 |
| **pose_processor.py** | 178 | L1 (Processor) | 確定性:YOLOv8 Pose,輸入帧→輸出姿态 | ❌ 不需要升級 |
| **cut_processor.py** | 106 | L1 (Processor) | 確定性:PySceneDetect,輸入视频→輸出场景 | ❌ 不需要升級 |
| **face_clustering_processor.py** | 282 | **L2 (Rule)** | 邏輯性:聚类算法,將 Face ID→Person ID | ⚠️ 建議升級到 Identity Agent |
| **face_recognition_processor.py** | 648 | **L2 (Rule)** | 邏輯性:人脸匹配,將 Face→Database Person | ⚠️ 建議升級到 Identity Agent |
| **fast_face_clustering_processor.py** | 334 | L2 (Rule) | 邏輯性:快速聚类版本 | ⚠️ 建議升級到 Identity Agent |
| **story_processor.py** | 325 | **L3 (Agent)** | 推論性:需要 LLM 分析故事结构 | ✅ 已經是 Agent |
| **caption_processor.py** | 291 | L1 (Processor) | 確定性:字幕提取 | ❌ 不需要升級 |
| **lip_processor.py** | 351 | L1 (Processor) | 確定性:唇语识别 | ❌ 不需要升級 |
| **visual_chunk_processor.py** | 431 | L2 (Rule) | 邏輯性:视觉分塊邏輯 | ❌ 不需要升級 |
| **music_segmentation_processor.py** | 138 | L1 (Processor) | 確定性:音乐分割 | ❌ 不需要升級 |
| **audio_taxonomy_processor.py** | 137 | L1 (Processor) | 確定性:音频分类 | ❌ 不需要升級 |
| **unified_synonym_processor.py** | 451 | L2 (Rule) | 邏輯性:同义词扩展 | ❌ 不需要升級 |
---
## 3. 需要迭代的 Processor
### 3.1 Face Clustering Processor
| 項目 | 說明 |
|------|------|
| **當前問題** | 純聚类算法,無法處理跨場景身份識別 |
| **局限** | 1. 無法處理 Speaker 與 Face 的關聯<br>2. 無法處理時間重叠推理<br>3. 無法處理模糊、遮擋情況 |
| **迭代建議** | 升級到 **Identity Agent**Face+Speaker→Person |
| **優先級** | High |
---
### 3.2 Face Recognition Processor
| 队目 | 說明 |
|------|------|
| **當前問題** | 簡單匹配,無法處理模糊、遮擋、跨年齡識別 |
| **局限** | 1. 純 embedding 匹配,置信度低<br>2. 無法處理多證據推理<br>3. 無法處理跨場景身份關聯 |
| **迭代建議** | 升級到 **Identity Agent**(多證據推理) |
| **優先級** | High |
---
### 3.3 ASRX Processor
| 队目 | 說明 |
|------|------|
| **當前問題** | Speaker ID 與 Face ID 未關聯 |
| **局限** | 輸出 speaker segments,但無法與 Person ID 绑定 |
| **迭代建議** | 需與 **Identity Agent** 結合 |
| **優先級** | Medium |
---
## 4. 建議升級到 Agent 的 Processor
### 4.1 Identity Agent(核心建議)
| 特性 | 說明 |
|------|------|
| **目的** | 綜合多證據(Face + Speaker + 時間重叠)推論 Person Identity |
| **層級** | L3 (Agent) - 需要推理和决策 |
| **觸發條件** | Face Clustering + ASRX 完成 |
| **輸入** | pre_chunks(face), pre_chunks(asrx), face_clusters, person表 |
| **輸出** | identity 表(person_id → identity_id 映射) |
| **核心邏輯** | 1. 時間重叠匹配(Speaker segment vs Face frames<br>2. Embedding 相似度計算<br>3. 多證據置信度融合<br>4. LLM 推論(處理模糊情況) |
---
### 4.2 Identity Agent 設計方案
#### 4.2.1 Agent 目標
從多個 processor 的輸出中,推論出「誰是誰」(Who is Who):
- **Face Processor**: 輸出每一帧的人脸位置和 embedding
- **ASRX Processor**:輸出每個 speaker 的時間段落
- **Face Clustering**: 輸出 Person ID(聚合後的人脸群)
- **Identity Agent**: 推論 Person ID → Identity Name(全局身份)
---
#### 4.2.2 輸入數據
```json
{
"file_uuid": "384b0ff44aaaa1f14cb2cd63b3fea966",
"person_id": "Person_17",
"face_frames": [100, 200, 300, ...],
"face_embeddings": [emb1, emb2, emb3, ...],
"speaker_segments": [
{"start": 10.5, "end": 15.2, "speaker": "SPEAKER_01"},
{"start": 20.3, "end": 25.1, "speaker": "SPEAKER_02"}
],
"face_clusters": {
"Person_17": {"frames": [100, 200, ...], "avg_embedding": emb_avg},
"Person_25": {"frames": [400, 500, ...], "avg_embedding": emb_avg}
}
}
```
---
#### 4.2.3 核心邏輯
**Step 1: 時間重叠匹配**
```python
def match_speaker_to_person(speaker_segments, person_frames, fps):
overlaps = []
for segment in speaker_segments:
start_frame = int(segment["start"] * fps)
end_frame = int(segment["end"] * fps)
overlap_frames = [f for f in person_frames if start_frame <= f <= end_frame]
overlap_ratio = len(overlap_frames) / len(person_frames)
if overlap_ratio > 0.5:
overlaps.append({
"speaker": segment["speaker"],
"person_id": person_id,
"overlap_ratio": overlap_ratio
})
return overlaps
```
**Step 2: Embedding 相似度計算**
```python
def calculate_similarity(face_emb, speaker_voice_emb):
cosine_sim = cosine_similarity(face_emb, speaker_voice_emb)
return cosine_sim
```
**Step 3: 多證據置信度融合**
```python
def fuse_evidence(face_conf, speaker_conf, time_overlap):
weighted_conf = 0.4 * face_conf + 0.3 * speaker_conf + 0.3 * time_overlap
return weighted_conf
```
**Step 4: LLM 推論(處理模糊情況)**
```python
def llm_identity_inference(evidence):
prompt = f"""
Given the following evidence:
- Face similarity: {evidence['face_sim']}
- Speaker overlap: {evidence['speaker_overlap']}
- Time overlap: {evidence['time_overlap']}
Should Person_17 and SPEAKER_01 be the same identity?
Provide confidence score and reasoning.
"""
response = llm.generate(prompt)
return response
```
---
#### 4.2.4 輸出格式
```json
{
"identity_id": "audrey_hepburn_001",
"identity_name": "Audrey Hepburn",
"person_ids": ["Person_17", "Person_25"],
"speaker_ids": ["SPEAKER_01"],
"confidence": 0.92,
"evidence": {
"face_similarity": 0.85,
"speaker_overlap": 0.78,
"time_overlap": 0.90,
"llm_reasoning": "High overlap in face and speaker segments..."
}
}
```
---
## 5. 實施計畫
### 5.1 Phase 1: Resume 功能補全(已完成部分)
| 任務 | 状态 | 預估工時 |
|------|------|----------|
| Pose Processor 添加 Resume | ⏳ 待處理 | 1h |
| CUT Processor 添加 Resume | ⏳ 待處理 | 1h |
---
### 5.2 Phase 2: Identity Agent 設計與實作
| 任務 | 預估工時 |
|------|----------|
| Identity Agent 設計文檔更新 | 2h |
| Identity Agent API 實作(Rust | 6h |
| Identity Agent 核心邏輯實作(Python | 4h |
| Identity Agent LLM 推論模塊 | 3h |
| Identity Agent 測試與驗證 | 2h |
**總計**: 17 小時
---
### 5.3 Phase 3: Processor 整合
| 任務 | 預估工時 |
|------|----------|
| Face Clustering → Identity Agent 輸出調整 | 2h |
| ASRX → Identity Agent 數據流調整 | 2h |
| Face Recognition → Identity Agent 整合 | 3h |
**總計**: 7 小時
---
## 6. 相關文件
| 文件 | 說明 |
|------|------|
| `AGENT_SPEC.md` | Agent 三層架構定義 |
| `FACE_SPEAKER_PERSON_WORKFLOW.md` | Identity Workflow 流程 |
| `PROCESSOR_RESUME_STRATEGY.md` | Resume 功能設計 |
| `JOB_WORKER_IMPLEMENTATION_PLAN.md` | Worker 數據流向修正計畫 |
---
## 7. 檔案位置
| 類型 | 路徑 |
|------|------|
| Processor 目錄 | `/scripts/*_processor.py` |
| Agent 設計文檔 | `/docs_v1.0/AI_AGENTS/` |
| Resume Framework | `/scripts/resume_framework.py` |
---
## 版本資訊
- 版本: V1.0
- 建立日期: 2026-04-27
@@ -81,7 +81,7 @@ Job Worker 根據此配置決定何時觸發 Rule。
```
**觸發邏輯**:
* `dependencies` 中列出的所有項目狀態變為 `completed` 時,觸發該 Rule。
*`dependencies` 中列出的所有項目狀態變為 `completed` 時,觸發該 Rule。
---
@@ -89,47 +89,47 @@ Job Worker 根據此配置決定何時觸發 Rule。
### 3.1 Rule 1: Sentence (語句聚合)
* **用途**: 將 ASR 的逐字/逐句輸出聚合為可搜尋的文本 Chunk。
* **Input**: `pre_chunks` 表中 `processor_type = 'asr'` 的紀錄。
* **Logic**:
1. 按時間順序讀取 ASR segments。
2. (可選) 結合物件標籤 (YOLO) 豐富 metadata。
3. 生成 `ChunkType::Sentence`
* **Output**: 寫入 `chunks` 表。
* **用途**: 將 ASR 的逐字/逐句輸出聚合為可搜尋的文本 Chunk。
* **Input**: `pre_chunks` 表中 `processor_type = 'asr'` 的紀錄。
* **Logic**:
1. 按時間順序讀取 ASR segments。
2. (可選) 結合物件標籤 (YOLO) 豐富 metadata。
3. 生成 `ChunkType::Sentence`
* **Output**: 寫入 `chunks` 表。
### 3.2 Rule 2: Visual (視覺聚合)
* **用途**: 將零散的 Frame 聚合為有意義的視覺事件 (例如:「某人出現在畫面中 5 秒」)。
* **Input**:
* `pre_chunks` 表中 `processor_type = 'yolo'` 的紀錄。
* `pre_chunks` 表中 `processor_type = 'face'` 的紀錄。
* **Logic**:
1. **滑動視窗**: 若連續 N 幀都偵測到同一 Identity,視為一個 Visual Chunk。
2. **事件過濾**: 忽略低於信心度閾值的偵測。
3. 生成 `ChunkType::Visual`
* **Output**: 寫入 `chunks` 表。
* **用途**: 將零散的 Frame 聚合為有意義的視覺事件 (例如:「某人出現在畫面中 5 秒」)。
* **Input**:
* `pre_chunks` 表中 `processor_type = 'yolo'` 的紀錄。
* `pre_chunks` 表中 `processor_type = 'face'` 的紀錄。
* **Logic**:
1. **滑動視窗**: 若連續 N 幀都偵測到同一 Identity,視為一個 Visual Chunk。
2. **事件過濾**: 忽略低於信心度閾值的偵測。
3. 生成 `ChunkType::Visual`
* **Output**: 寫入 `chunks` 表。
### 3.3 Rule 3: Scene (場景聚合)
* **用途**: 基於鏡頭切換 (CUT) 與語音內容,定義場景邊界。
* **Input**:
* `pre_chunks` 表中 `processor_type = 'cut'` 的紀錄。
* `chunks` 表中 Rule 1 產生的 Sentence Chunks (用於填充場景內容)。
* **Logic**:
1. 讀取 CUT 偵測到的 Scene 邊界。
2. 將該時間段內的所有 Rule 1 Chunks 關聯到此 Scene。
3. 生成 `ChunkType::Scene`
* **Output**: 寫入 `chunks` 表。
* **用途**: 基於鏡頭切換 (CUT) 與語音內容,定義場景邊界。
* **Input**:
* `pre_chunks` 表中 `processor_type = 'cut'` 的紀錄。
* `chunks` 表中 Rule 1 產生的 Sentence Chunks (用於填充場景內容)。
* **Logic**:
1. 讀取 CUT 偵測到的 Scene 邊界。
2. 將該時間段內的所有 Rule 1 Chunks 關聯到此 Scene。
3. 生成 `ChunkType::Scene`
* **Output**: 寫入 `chunks` 表。
### 3.4 Rule 4: Summary / Agent (AI 摘要)
* **用途**: 利用 LLM 生成場景或影片的摘要、5W1H 標籤。
* **Input**: `chunks` 表中已完成的 Scene/Sentence Chunks。
* **Logic**:
1. 收集 Chunk 的文本、視覺標籤。
2. 調用 **Translation/Summary Agent**
3. 將生成的摘要與標籤更新回 `chunks` 表的 `metadata` 欄位。
* **Output**: 更新 `chunks` 表 (In-place Update)。
* **用途**: 利用 LLM 生成場景或影片的摘要、5W1H 標籤。
* **Input**: `chunks` 表中已完成的 Scene/Sentence Chunks。
* **Logic**:
1. 收集 Chunk 的文本、視覺標籤。
2. 調用 **Translation/Summary Agent**
3. 將生成的摘要與標籤更新回 `chunks` 表的 `metadata` 欄位。
* **Output**: 更新 `chunks` 表 (In-place Update)。
---
@@ -137,8 +137,8 @@ Job Worker 根據此配置決定何時觸發 Rule。
AI Agent 不再是獨立的「黑盒子」,而是作為 Rule 的執行引擎之一。
* **Prompt Injection**: Rule 負責組裝 Context (Input Chunks),注入預定義的 Prompt Template。
* **Structured Output**: Agent 必須輸出符合 Schema 的 JSON,以便 Rust 寫入資料庫。
* **Prompt Injection**: Rule 負責組裝 Context (Input Chunks),注入預定義的 Prompt Template。
* **Structured Output**: Agent 必須輸出符合 Schema 的 JSON,以便 Rust 寫入資料庫。
**範例 (Rule 4 摘要)**:
> "You are a movie analyst. Based on the following dialogue and visual tags, summarize the scene in 50 words and extract the 5W1H entities."
@@ -147,5 +147,5 @@ AI Agent 不再是獨立的「黑盒子」,而是作為 Rule 的執行引擎
## 版本資訊
- 版本: V1.0
- 建立日期: 2026-04-25
* 版本: V1.0
* 建立日期: 2026-04-25