結論先講
AI 客服最大的風險不是答錯,是該轉真人的時候沒轉。
答錯了,使用者會再問一次;沒轉真人,使用者會直接去社群抱怨。
所以設計順序應該是反過來的:先定義「什麼情況一定要交給人」,再設計 AI 要回答什麼。
第一步:意圖分類切成五類
不要一開始就切二十類。從這五類開始:
| 意圖 | 判斷依據 | 處置 |
|---|---|---|
| 一般詢問 | 營業時間、地址、政策等 | AI 直接回答 |
| 產品問題 | 規格、庫存、比較 | AI 回答 + 附產品連結 |
| 抱怨/投訴 | 負面情緒、爭議 | 立刻轉真人 + 發警報 |
| 要求人工 | 明確說「我要找真人」 | 立刻轉真人 |
| 無法判斷 | 信心度低於門檻 | 轉真人,不要猜 |
為什麼是五類而不是二十類
分類錯誤的代價比分類粗略大得多。
切二十類時,準確率會明顯下降,而「抱怨被分到一般詢問」這種錯誤,後果是實質的。五類的每一類都有明確且不同的處置,這才是分類的意義。
先跑三個月,看實際對話的分佈,再決定要不要細分。
第二步:轉真人的四個門檻
這四條要寫成規則,不要交給模型自由判斷:
| 門檻 | 條件 | 為什麼 |
|---|---|---|
| 1. 明確要求 | 使用者說要找真人 | 這是底線,沒有例外 |
| 2. 意圖為抱怨 | 分類結果是抱怨或投訴 | AI 處理抱怨幾乎只會惡化 |
| 3. 信心度過低 | 分類信心低於設定值 | 不確定就不要猜 |
| 4. 重複詢問 | 同一問題問超過兩次 | 代表前面沒解決 |
第四條最容易被忽略
使用者重複問同一件事,代表前面的回答沒解決問題。 繼續讓 AI 回,只會累積不滿。
這一條不需要任何 AI 判斷,純粹是計數邏輯——但它擋掉的挫折感,比前三條加起來還多。
非上班時間的兜底流程
這是最常被漏掉的一段。最糟的設計是靜默轉單——使用者以為沒人理他,實際上是排隊中。
正確流程:
- 判定需轉真人 → 立刻告知使用者「已轉專人,將於某個時間內回覆」
- 同時發通知到內部管道(讓人知道有單)
- 在資料庫標記待處理狀態(讓單子不會消失)
三件事要同時做。少了第一件,體驗最差;少了第三件,單子會漏掉。
第三步:讓模型輸出結構化結果
不要讓模型回一段自由文字然後自己解析。要求它輸出固定欄位:
{
"intent": "complaint",
"sentiment": "negative",
"confidence": 0.92,
"need_human": true,
"reply_draft": "很抱歉造成您的不便,我已經將您的問題轉給專人處理…"
}
這樣做的好處:
need_human是布林值,程式可以直接判斷,不用理解語意confidence讓你可以調門檻,而不是改提示詞reply_draft就算要轉真人,也給客服一個起草稿
關鍵是 need_human 要由模型與規則「雙重判定」——模型說不用轉,但規則命中(例如重複詢問三次),仍然要轉。規則優先於模型。
資料表設計:對話記錄要存什麼
| 欄位 | 用途 |
|---|---|
user_id | 關聯同一個人的多輪對話 |
message | 使用者說了什麼 |
intent | 分類結果 |
sentiment | 情緒判定 |
need_human | 是否已轉真人 |
created_at | 時間戳,用來算重複次數 |
need_human 這個欄位不只是紀錄,它是待處理清單的來源。有了它,客服可以直接查「所有還沒處理的轉單」。
最容易做錯的一個安全設定
這一節單獨拉出來,因為它是實務上最常見、後果也最嚴重的錯誤。
很多教學會叫你關掉資料列層級安全性
為了「教學環境簡化」,很多步驟會寫:建表時取消勾選 Enable Row Level Security(RLS)。
在對話記錄這張表上,這是不能接受的。
理由很直接:這張表存了 user_id 與對話內容——那是個資。關掉 RLS 之後,只要有人拿到公開金鑰,就能讀取整張表的全部內容。
正確做法:啟用 RLS 並寫政策
建表時勾選啟用,然後加上政策。以對話記錄為例:
-- 啟用資料列層級安全性
ALTER TABLE conversation_memory ENABLE ROW LEVEL SECURITY;
-- 前端一律不得直接讀寫(對話由後端服務寫入)
CREATE POLICY "no_client_access"
ON conversation_memory
FOR ALL
USING (false);
如果前端確實需要讓使用者看自己的對話紀錄,改成:
CREATE POLICY "users_read_own_conversations"
ON conversation_memory
FOR SELECT
USING (auth.uid()::text = user_id);
兩種金鑰要分清楚
| 金鑰 | 可以放哪 | 特性 |
|---|---|---|
| 公開金鑰(anon) | 前端 | 受 RLS 保護 |
| 服務金鑰(service role) | 只在後端 | 繞過所有安全規則 |
服務金鑰繞過 RLS——這是它的設計目的,也是它絕對不能出現在前端程式碼或版控裡的原因。
如果服務金鑰外流,RLS 寫得再好都沒有用。
情緒分析不要當成唯一依據
情緒分析可以當訊號,但中文的反諷、客套與間接抱怨判斷不穩。
「還真是謝謝你喔」——很可能被判成正面。
建議做法:把情緒當成加權因素之一,跟意圖分類、信心度、重複次數一起看。而且任何一條規則都能單獨觸發轉真人,不需要多條同時成立。
寧可多轉幾個,不要漏掉一個真正生氣的客戶。
上線前的檢查清單
- 四個轉真人門檻都實作了,而且規則優先於模型判斷
- 非上班時間有兜底:告知使用者 + 內部通知 + 資料庫標記
- 模型輸出是結構化欄位,不是自由文字
- 對話記錄表啟用了 RLS 並寫了政策
- 服務金鑰不在前端、不在版控
- 有辦法查詢「所有未處理的轉單」
最後一項如果做不到,前面五項的價值都會打折——因為你不知道有多少人在等。
常見問題
AI 客服的意圖分類要切多細?
從四到五類開始,不要一開始就切二十類。實務上「一般詢問、產品問題、抱怨、要求人工、無法判斷」這五類就能涵蓋大部分情境,而且每一類都有明確且不同的處置方式。切太細的問題是分類準確率下降,而分類錯誤的代價比分類粗略大得多。
什麼情況一定要轉真人?
四種:使用者明確要求、判定為抱怨或投訴、模型信心度低於門檻、同一個問題重複問超過兩次。第四種最容易被忽略——使用者重複問代表前面的回答沒解決問題,繼續讓 AI 回只會累積不滿。這四條要寫成規則,不要交給模型自由判斷。
轉真人之後,非上班時間怎麼辦?
要有明確的兜底流程,這是最常被漏掉的一段。做法是:判定需轉真人時立刻告知使用者「已轉專人,將於某個時間內回覆」,同時發通知到內部管道並在資料庫標記待處理。最糟的設計是靜默轉單——使用者以為沒人理他,實際上是排隊中。
對話記錄存在雲端資料庫,安全上要注意什麼?
最關鍵的一項是啟用資料列層級安全性(RLS)並寫好政策。很多教學為了簡化會叫你把它關掉,但對話記錄含使用者識別碼與談話內容,那是個資——關掉之後只要金鑰外流,整張表就能被任意讀取。另外要分清前端可用的公開金鑰與後端專用的服務金鑰,後者絕對不能出現在前端程式碼。
情緒分析的結果可以直接用來決定要不要轉真人嗎?
可以當其中一個訊號,但不要當唯一依據。情緒分析對中文的反諷、客套與間接抱怨判斷不穩,「還真是謝謝你喔」可能被判成正面。建議把情緒當成加權因素之一,跟意圖分類、信心度、重複次數一起看,並且讓任何一條規則都能單獨觸發轉真人。