# Export/Import Identity Merge 分析

**作者**：M5  
**日期**：2026-05-07  

---

## 情境

```
M5 Pipeline 完成 (Charade)
  → export package (含 face_detections, identities, identity_bindings)
  → import 到 M4
  → M4 已有自己的 identities (來自之前處理的影片)
```

## Identity 衝突類型

### Case A：完全相同的 person（同名）
```
export:  identity_uuid = "550e8400-e29b-..."  name = "Audrey Hepburn"
target:  identity_uuid = "6ba7b810-9dad-..."  name = "Audrey Hepburn"
```
**處理：merge — 將 export 的 binding 指到 target 的 identity**

### Case B：同人不同名
```
export:  identity_uuid = "550e..."  name = "Cary Grant"  
target:  identity_uuid = "6ba7..."  name = "Mr. Grant"
```
**處理：合併或新增 alias**

### Case C：新人物（target 無）
```
export:  identity_uuid = "550e..."  name = "Walter Matthau"
target:  不存在
```
**處理：直接匯入**

### Case D：UUID 碰撞（不同人同一 UUID，機率低但可能）
```
export:  identity_uuid = "550e..."  name = "Walter Matthau"
target:  identity_uuid = "550e..."  name = "Someone Else"
```
**處理：remap UUID**

### Case E：跨語言同人（name-based 完全無法處理）⭐
```
韓文系統 export → 英文系統 import

export:  identity_uuid = "550e..."  name = "오드리 헵번"  (Audrey Hepburn)
         face_embedding: [0.12, -0.34, 0.56, ...]

target:  identity_uuid = "6ba7..."  name = "Audrey Hepburn"
         face_embedding: [0.11, -0.33, 0.57, ...]
                            ↑ cosine similarity = 0.98
```

```
export:  identity_uuid = "551e..."  name = "오드리 헵번"  (Audrey Hepburn)
         face_embedding: [0.12, -0.34, 0.56, ...]

target:  identity_uuid = "6ba8..."  name = "Audrey Hepburn (配音)"
         face_embedding: [0.42, -0.11, 0.23, ...]
                            ↑ cosine similarity = 0.45 → 同名不同人，不 merge
```

**name-based merge 在此案例完全失效**：
| 方法 | 오드리 헵번 → Audrey Hepburn | 오드리 헵번 → Audrey Hepburn (配音) |
|------|-----------------------------|-----------------------------------|
| name exact match | ❌ 失敗 | ❌ 失敗 |
| name fuzzy match | ❌ 失敗 | ❌ 失敗 |
| **向量比對** | **✅ 0.98 → merge** | **✅ 0.45 → 不 merge** |

## Merge 策略

### 策略 1：完全自動（by name）
```
1. 比對 export.identities[].name == target.identities[].name
2. 匹配 → binding 改指向 target identity
3. 不匹配 → 新增 identity
```

**優點**：簡單  
**缺點**：同名不同人會誤合、同人不同名會重複

### 策略 2：半自動（by name + 人工確認）
```
1. 比對 export.identities[].name
2. 模糊匹配（Levenshtein distance < 3）→ 標記為候選
3. 完全匹配 → 自動 merge
4. 無匹配 → 新增
5. 輸出 merge 報告供人工審閱
```

**優點**：安全  
**缺點**：需人工介入

### 策略 3：向量比對（by face embedding）
```
1. 對 export 每個 identity 取 reference face embedding
2. 與 target 所有 identity 的 face_embedding 做 cosine similarity
3. similarity > 0.85 → 自動 merge
4. 0.70–0.85 → 標記為候選
5. < 0.70 → 新增
```

**優點**：最準確（跨命名差異）  
**缺點**：需有 reference embedding、效能開銷

## 建議方案

**第一版：向量比對（by face embedding）+ UUID remapping**

```
import流程:
1. 讀取 export package
2. 對 export 每個 identity 取 reference face_embedding
3. 與 target 所有 identity 的 face_embedding 做 cosine similarity
4. 建立 remap table (export_uuid → target_uuid)
   - similarity > 0.85 → merge (指到 target uuid)
   - 0.70–0.85 → 標記候選，輸出 report
   - < 0.70 → 生成新 uuid
   - 無 face_embedding 的 identity → fallback to name match
5. 用 remap table 更新所有 binding reference
6. 匯入 face_detections, chunks 等（remap uuid）
7. 匯入 Qdrant vectors（更新 payload 中的 uuid）
```

```
remap.json 範例:
{
  "550e8400-e29b-41d4-a716-446655440000": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",  ← merge (vector 0.98)
  "6ba7b810-9dad-11d1-80b4-00c04fd430c9": "NEW_generated_uuid_1",                       ← new
  "550e8400-e29b-41d4-a716-446655440001": "550e8400-e29b-41d4-a716-446655440001"         ← same (no conflict)
}
```

**第二版：策略 3（向量比對）+ 人工確認 UI**
