我完全理解 AI 工程師的痛點!讓我用實際情境來解釋這些挑戰和解決方法:
---
## **挑戰一:標注資料太少**
### **實際情況**
想像你要訓練 AI 辨識「柴油發票」:
**理想狀況**:需要 1000+ 張已標注的發票
- 中油格式 300 張
- 台塑格式 200 張
- 各家加油站格式 500 張
**現實狀況**:客戶只給你 50 張
- 而且可能都是同一家加油站
- 新客戶的發票格式又完全不同
- 每次遇到新格式 AI 就傻眼
### **為什麼會這樣?**
查證公司說:「我們以前都人工做,哪有時間標注資料?而且每個客戶的發票長得都不一樣,我們根本不知道要標注到什麼程度才夠。」
### **解決方法**
**方法 1:主動學習(Active Learning)策略**
不要一次要求客戶標注 1000 筆,改用滾動式標注:
```
第一輪:標注 50 筆 → 訓練初版模型
↓
第二輪:模型跑 500 筆未標注資料
→ AI 挑出「最不確定」的 30 筆
→ 請客戶只標注這 30 筆(針對性補強)
↓
第三輪:模型準確度提升 → 再挑 20 筆最難的
↓
重複直到準確度達標
```
**實際對話範例**:
工程師:「王經理,你先幫我標這 50 張就好,我先訓練一版出來。」
(一週後)
工程師:「我的 AI 跑了你們 500 張發票,這 30 張它最沒把握,你幫我看一下這些對不對就好。」
查證員:「才 30 張?這我今天就能標完!」
**方法 2:少樣本學習(Few-shot Learning)**
使用預訓練的 OCR 模型(如 GPT-4V、Claude with Vision):
```python
# 不需要大量訓練資料
# 只需要給 AI 「幾個範例」就能舉一反三
提示詞範例:
"""
我會給你發票圖片,請提取:
1. 日期
2. 品名(燃料類型)
3. 數量
4. 單位
參考範例 1:
[顯示一張標準中油發票]
正確提取結果:{"日期": "2023-10-13", "品名": "超級柴油", ...}
參考範例 2:
[顯示一張台塑發票]
正確提取結果:...
現在請處理這張新發票:
[上傳新圖片]
"""
```
**實際效果**:只需要 5-10 個範例就能有 80% 準確率
**方法 3:合成資料(Synthetic Data)**
當真實資料不夠,自己生成:
```
收集 10 種發票模板
↓
用程式自動生成 1000 張「假發票」
(日期隨機、數量隨機、但格式符合真實發票)
↓
用合成資料預訓練
↓
再用 50 張真實資料微調
```
---
## **挑戰二:標注規則不明確且一直變**
### **實際情況**
**情境一:「柴油」到底算不算匹配?**
工程師標注規則:
```
清單寫「柴油」
發票寫「超級柴油」
→ 算匹配 ✓
```
查證員 A:「對,這當然算!」
查證員 B:「不對,我們公司規定要完全一樣才算!」
查證員 C:「要看客戶,有些客戶很嚴格,有些客戶 OK...」
**情境二:數值比對的「誤差容許度」爭議**
```
清單:18.5 公秉
發票:18.50 公秉
→ 完全相等,當然匹配 ✓
清單:18.5 公秉
發票:18.49 公秉
→ 這算不算匹配?
查證員:「0.01 的差異可能是四捨五入,應該算匹配」
工程師:「那 0.1 呢?0.5 呢?界線在哪?」
查證員:「這個... 要看情況...」
```
**情境三:日期比對的模糊地帶**
```
清單:2023-10 月(月度加總)
發票 1:2023-10-05 15 公秉
發票 2:2023-10-18 20 公秉
發票 3:2023-11-01 10 公秉 ← 這張算不算 10 月?
查證員:「11/1 的應該算 10 月的使用量,因為是月底加油隔天才開發票」
工程師:「那 11/2、11/3 呢?切點在哪?」
查證員:「這個要問客戶當時怎麼記帳...」
```
### **為什麼會這樣?**
查證工作本質上就是「專業判斷」,很多規則在人類腦中是「看情況」,但 AI 需要明確的 if-else。
### **解決方法**
**方法 1:多層級驗證機制**
不要讓 AI 直接判「對」或「錯」,改用信心度分級:
```
┌─────────────────────────────────────┐
│ AI 信心度分級系統 │
├─────────────────────────────────────┤
│ 信心度 95-100% → 自動通過 ✓ │
│ (完全匹配,無需人工) │
│ │
│ 信心度 70-94% → 待人工確認 ? │
│ (有小差異,需查證員判斷) │
│ │
│ 信心度 0-69% → 不匹配 ✗ │
│ (差異太大,標記為錯誤) │
└─────────────────────────────────────┘
```
**實際應用**:
```json
{
"feedstock_match": {
"清單": "柴油",
"發票": "超級柴油",
"信心度": 85,
"判定": "待人工確認",
"原因": "語意相近但用詞不同"
}
}
```
這樣查證員只需要看「85 分」這些灰色地帶,100 分的自動過,0 分的自動擋。
**方法 2:可配置的規則引擎**
讓客戶自己定義規則,不要寫死在程式碼裡:
```yaml
# 客戶 A 的配置檔
matching_rules:
feedstock:
method: "semantic" # 語意匹配
synonyms:
- ["柴油", "超級柴油", "diesel"]
- ["汽油", "92無鉛", "95無鉛"]
value:
method: "tolerance" # 容許誤差
absolute_error: 0.1 # 絕對誤差 ±0.1
percentage_error: 2% # 或百分比誤差 ±2%
date:
method: "fuzzy"
grace_period: 3 # 月初前3天算上月
```
```yaml
# 客戶 B 的配置檔(更嚴格)
matching_rules:
feedstock:
method: "exact" # 必須完全一樣
value:
method: "exact" # 不允許任何誤差
date:
method: "exact" # 必須在同一月
```
**實際對話**:
工程師:「王經理,你們對於數值誤差的容許度是多少?」
查證員:「這個... 我們通常 0.1 以內都接受」
工程師:「好,我在你們的設定檔寫 0.1,之後你們可以自己調整,不用改程式碼」
**方法 3:決策樹可視化**
把複雜規則畫成圖,讓客戶自己檢視邏輯:
```
柴油 vs 超級柴油
↓
┌─────────┴─────────┐
用語意匹配? 用精確匹配?
↓ ↓
查詞庫 ┌──────────┴──────────┐
↓ 完全一樣? 不一樣?
有同義詞? ↓ ↓
↙ ↘ 匹配 ✓ 不匹配 ✗
有 ✓ 沒有 ?
```
給客戶看:「你們現在的邏輯是這樣,覺得 OK 嗎?」
---
## **挑戰三:數值用等於 vs 誤差值的困擾**
### **實際情況**
AI 工程師的疑惑:
```python
# 數值比對
清單值 = 18.5
發票值 = 18.50
# 方法 1:用等於
if 清單值 == 發票值:
return "匹配"
# 問題:18.5 和 18.50 是同一個數,但字串比對會失敗
# 方法 2:轉浮點數再等於
if float(清單值) == float(發票值):
return "匹配"
# 問題:浮點數精度問題,18.499999999 != 18.5
# 方法 3:用誤差範圍
if abs(float(清單值) - float(發票值)) < 0.01:
return "匹配"
# 問題:那 18.4 和 18.5 也會算匹配?
# 方法 4:百分比誤差
誤差率 = abs(清單值 - 發票值) / 清單值
if 誤差率 < 0.02: # 2%
return "匹配"
# 問題:小數值時誤差被放大(0.1 vs 0.11 = 10% 誤差)
```
### **真實案例的複雜性**
**案例一:月度加總 vs 多筆小額**
```
清單:10 月柴油用量 = 55.0 公秉
發票實際狀況:
10/5 18.5 公秉
10/12 18.3 公秉
10/25 18.2 公秉
-----
合計 55.0 公秉 ✓ 完美匹配
但如果是:
10/5 18.5 公秉
10/12 18.3 公秉
10/25 18.1 公秉 ← 少了 0.1
-----
合計 54.9 公秉
這算匹配嗎?
```
**案例二:單位換算的誤差**
```
清單:1000 公升
發票:1.02 公秉(1 公秉 = 1000 公升)
實際值:1020 公升
誤差:20 公升(2%)
查證員:「可能是溫度膨脹,柴油有體積膨脹係數」
工程師:「那我要設多少容許誤差?1%?3%?5%?」
查證員:「這個... 要看溫差...」
```
### **解決方法**
**方法 1:分級比對策略(推薦)**
```python
def match_number(清單值, 發票值, 數據類型):
差異 = abs(清單值 - 發票值)
百分比差異 = 差異 / 清單值 * 100
# Level 1: 完全相等(考慮浮點數精度)
if 差異 < 0.001:
return {"匹配": True, "信心度": 100, "原因": "完全相等"}
# Level 2: 微小差異(可能是四捨五入)
if 差異 <= 0.1 and 百分比差異 < 1%:
return {"匹配": True, "信心度": 95, "原因": "微小差異(四捨五入)"}
# Level 3: 小誤差(可能是抄寫、計量誤差)
if 數據類型 == "燃料用量":
if 差異 <= 0.5 or 百分比差異 < 2%:
return {"匹配": "待確認", "信心度": 75, "原因": "小誤差,建議人工確認"}
# Level 4: 單位換算誤差
if 數據類型 == "燃料用量":
# 檢查是否為單位換算問題(公秉 vs 公升)
if abs(清單值 - 發票值*1000) < 1:
return {"匹配": "待確認", "信心度": 80, "原因": "可能有單位換算問題"}
# Level 5: 明顯不匹配
return {"匹配": False, "信心度": 0, "原因": f"差異過大:{差異}"}
```
**實際輸出**:
```json
{
"清單": 18.5,
"發票": 18.49,
"匹配": true,
"信心度": 95,
"原因": "微小差異(四捨五入)",
"需人工確認": false
}
```
**方法 2:統計學習誤差容許度**
不要靠猜,讓資料說話:
```python
# 收集歷史上「查證員認為匹配」的資料
歷史匹配案例 = [
{"清單": 18.5, "發票": 18.49, "查證員判定": "匹配"},
{"清單": 18.5, "發票": 18.3, "查證員判定": "不匹配"},
{"清單": 100, "發票": 99.8, "查證員判定": "匹配"},
# ... 收集 100+ 筆
]
# 統計分析
匹配的平均誤差 = 計算平均值
匹配的最大誤差 = 計算最大值
不匹配的最小誤差 = 計算最小值
# 自動設定閾值
建議閾值 = (匹配的最大誤差 + 不匹配的最小誤差) / 2
```
**實際對話**:
工程師:「王經理,我分析了你們過去 200 筆判定,發現你們通常接受 ±0.3 的誤差,但超過 0.5 就會標記為錯誤。我用 0.4 當閾值可以嗎?」
查證員:「對!這就是我們的經驗法則!」
---
## **挑戰四:Edge Case 太多且規則矛盾**
### **實際情況**
**客戶需求清單(看似合理,實則矛盾)**:
```
Rule 1: 日期必須完全在同一月份內
Rule 2: 月底最後 3 天的發票可以算下個月
Rule 3: 如果是預付款,要看實際使用日期
Rule 4: 如果發票日期模糊,以送貨單為準
Rule 5: 某些特殊客戶用發票日期,某些用入帳日期
```
**工程師的困擾**:
「這些規則根本無法同時滿足!」
```
例子:
發票日期:10/31
送貨日期:11/1
入帳日期:11/5
實際使用:10/15(預付款)
按 Rule 1 → 應該算 10 月(發票在 10 月)
按 Rule 2 → 應該算 11 月(10/31 是月底)
按 Rule 3 → 應該算 10 月(實際使用在 10 月)
按 Rule 4 → 應該算 11 月(送貨單在 11 月)
到底算哪個月???
```
### **為什麼會這樣?**
因為客戶在描述需求時,想到什麼就說什麼,沒有考慮整體邏輯一致性。
### **解決方法**
**方法 1:優先級決策樹**
強迫客戶定義「規則優先順序」:
```
與客戶討論:
工程師:「當這些規則衝突時,哪個優先?」
決策樹:
有送貨單嗎?
↙ ↘
有 沒有
↓ ↓
以送貨單為準 有實際使用日期嗎?
↙ ↘
有 沒有
↓ ↓
以實際使用為準 以發票日期為準
↓
月底 3 天例外處理
```
寫成配置檔:
```yaml
date_matching_priority:
1. 送貨單日期(如果有)
2. 實際使用日期(如果是預付款)
3. 發票日期
- 例外:月底 3 天視為下月
4. 入帳日期(最後選項)
```
**方法 2:情境分類法**
不要用一套規則處理所有情況,根據情境切換規則:
```python
def 判斷日期匹配(發票資訊, 清單月份):
# 情境 1:預付款
if 發票資訊.is_預付款:
return 比對實際使用日期(發票資訊.實際使用日期, 清單月份)
# 情境 2:有送貨單
elif 發票資訊.has_送貨單:
return 比對送貨日期(發票資訊.送貨日期, 清單月份)
# 情境 3:一般情況
else:
return 比對發票日期_with_月底例外(發票資訊.發票日期, 清單月份)
```
**方法 3:邊界案例資料庫 + 人工審核**
把所有「規則衝突」的案例記錄下來:
```json
{
"edge_cases": [
{
"id": "EC001",
"情況": "月底發票但送貨單在下月",
"發票日期": "2023-10-31",
"送貨日期": "2023-11-01",
"清單月份": "2023-10",
"AI判定": "不匹配",
"查證員判定": "匹配",
"判定理由": "以送貨日期為準,視為 10 月底送達",
"修正規則": "月底±3天的送貨單視為同月"
}
]
}
```
每次遇到邊界案例:
1. AI 暫時標記「待人工確認」
2. 查證員判定後記錄在資料庫
3. 累積 20+ 個類似案例後,更新規則
**實際對話**:
工程師:「王經理,你看這 20 筆月底發票,有 15 筆你判定算當月,5 筆算下月。我發現差異在於『送貨日期是否在 3 天內』。我幫你加一條規則:送貨在發票後 3 天內算同月。這樣對嗎?」
查證員:「對!就是這個邏輯!」
**方法 4:雙軌制(漸進式自動化)**
不要一步到位,而是逐步減少人工:
```
第一階段(上線初期):
- AI 處理 70% 明確案例(信心度 >90%)
- 30% 邊界案例全部人工
第二階段(3 個月後):
- 分析這 30% 案例,提煉 10 條新規則
- AI 處理 85% 案例
- 15% 邊界案例人工
第三階段(6 個月後):
- AI 處理 95% 案例
- 5% 極端邊界案例人工
永遠保留 5% 人工審核
```
---
## **具體實施路徑**
### **階段一:先求有再求好**
```
目標:60% 自動化率就上線
策略:
1. 只處理「完全匹配」的案例
2. 任何有疑慮的都丟給人工
3. 記錄所有人工判定結果
```
**實際效果**:
- 雖然只有 60% 自動化
- 但已經節省查證員 60% 時間
- 客戶會很滿意
### **階段二:滾動優化**
```
每週開會檢討:
工程師:「上週 AI 送了 100 筆給你們人工確認,我發現其中 60 筆都是『單位不一致』問題」
查證員:「對,公秉和公升的轉換我們每次都要算」
工程師:「那我這週加一個單位自動轉換功能,下週應該只剩 40 筆」
(下週)
工程師:「這週剩下的 40 筆,發現 30 筆是日期問題...」
```
### **階段三:規則沉澱**
6 個月後,累積足夠案例,可以整理出:
```
標準操作規則(SOP):
1. 數值比對:±0.1 或 ±1% 容許
2. 日期比對:同月或月底 ±3 天
3. 燃料名稱:使用同義詞庫(50 組)
4. 單位換算:自動轉換(20 種單位)
5. 特殊情況:10 種 edge case 處理邏輯
```
這時候準確率可以達到 90%+。
---
## **給 AI 工程師的心態建議**
**不要追求完美**:
- 不是要取代查證員,而是「讓查證員只處理困難的 10%」
- 90% 準確率就很好了,不要追求 99%(最後的 9% 成本極高)
**擁抱不確定性**:
- 用「信心度」而非「對錯」
- 灰色地帶就交給人類
**與客戶一起成長**:
- 不是「我做好了你來用」
- 而是「我們一起定義什麼叫『好』」
**用數據說話**:
- 客戶說「這個規則很重要」→ 記錄實際遇到頻率
- 如果 1000 筆只出現 1 次,優先級就很低
最終目標:**讓 AI 處理枯燥重複的工作,讓查證員專注在專業判斷上**。這才是真正的價值!