專案管理那篇的開頭,是客服接到一封客訴,要交給工程師處理。那篇講的是工程師那一側。這篇往前一步,看客服那一側:客人的信寄到哪裡、誰回、回到哪了。
客服信箱如果是一個大家共用的 email 帳號,很快就會出問題:
- 兩個客服同時回同一封信,客人收到兩個不同的答案。
- 一封信沒人回,因為每個人都以為別人回了。
- 客人第三次來信,接手的客服不知道前兩次講了什麼。
客服工單系統要解的就是這件事:客人的每一串來信變成一張工單,誰負責、狀態到哪、之前講過什麼,都在同一個地方。
核心的東西:信箱、工單、客人
以 open source 的 FreeScout(AGPL-3.0)為例:
- 信箱:客服對外的 email 地址,例如 support@。系統用 IMAP 去這個信箱收信,用 SMTP 寄回信。
- 工單:一串往來的信件。FreeScout 叫它 conversation,裡面每一封信或備註是一個 thread。
- 客人:用 email 地址認人。同一個地址的來信,都算同一位客人。
工單的狀態很簡單:處理中、等待客人、已結案。客服回信時順便選狀態,例如「回覆並等待客人」。
在本機跑起來
FreeScout 沒有自己發布 Docker image。官網的 Docker 頁面直接轉址到一個社群維護的 image,我用的就是它,內含 FreeScout 1.8.245,資料庫改用官方的 MariaDB。
客服系統一定要有郵件伺服器,才能模擬客人寄信進來。我加了一台測試用的郵件伺服器 GreenMail,它同時支援寄信(SMTP)和收信(IMAP),不檢查密碼,信件只放在記憶體裡。三個容器合計大約 300 MB 記憶體。
架起來之後,第一封客訴信就走通了:客人寄信到客服信箱 → FreeScout 用 IMAP 收進來 → 變成工單 #1。
一封客訴走一遍
接著讓客服回信。客人的信箱收到了,信頭有一行:
In-Reply-To: <客人原本那封信的 Message-ID>這一行是 email 的回覆機制:每封信有一個唯一的 Message-ID,回信時在 In-Reply-To 寫上被回覆的那封。FreeScout 就是靠它,把回信歸到正確的工單。
然後我測了四種「客人再來信」的情況:
| 情況 | 結果 |
|---|---|
| 客人直接按「回覆」 | 歸到同一張工單,狀態從「等待客人」變回「處理中」 |
| 客人新寫一封信,主旨一樣是「Re: ……」 | 變成一張新工單 |
| 同一個人換一個 email 寄信 | 多了一位客人,開了一張新工單,兩位客人同名 |
| 工單結案後,客人直接按「回覆」 | 原工單自動重新打開 |
第一和第四種是設計好的行為:只要客人按回覆,信就會回到原本的工單,結案了也會重新打開,不會被漏掉。
第二和第三種,是客服每天都會遇到的情況。
同一個人為什麼會變成兩張單
FreeScout 用信頭對應工單,不用主旨。 客人如果不是按回覆,而是新寫一封信、自己打上一樣的主旨,系統就把它當成新的事情。這種設計是對的:如果用主旨對應,所有主旨叫「訂單問題」的信都會被合成一張。但結果是同一件事分成了兩張工單,兩個客服可能各回各的。
FreeScout 用 email 認人。 客人換了公司信箱寄信,系統就多了一位同名的客人。這跟 CRM 會碰到哪些資料那篇講的身分問題一模一樣:同一個人在不同管道留了不同的聯絡方式,系統要先回答「這是不是同一個人」。
對客服團隊來說,要做的事:
- 接手工單時,先查同一位客人和同名客人的其他工單。 系統不會自動合併,要靠人看。
- 發現重複時,合併工單或客人資料。 不要兩張單各自回覆。FreeScout 的核心有合併工單和合併客人的功能。這點我只在程式碼裡確認過,沒有實際操作。
- 客服回信的範本請客人「直接回覆這封信」。 這是讓信回到原工單最簡單的方法。
API 是付費模組:AI 要怎麼接進來
FreeScout 的核心是 AGPL-3.0,但 REST API 和 Webhooks 是付費模組,一個站台買斷。沒有買的話,外部程式能碰到 FreeScout 的方法只剩三種:
- 網頁表單:這次實驗就是這樣做的。我寫了一支程式登入網頁,拿到防偽造的 token,再送出回信的表單。可以用,但網頁一改版就會壞。
- email:寄信進客服信箱,就是建立工單。這是最穩定的介面,但只能「新增」,不能查詢。
- 資料庫:直接讀 FreeScout 的資料表。
2026-10 查證時,FreeScout 的社群 MCP 都是 0 顆星。這是推論,不是實測:這些 MCP 需要付費的 API 模組。
如果要讓 AI 幫客服,比較實際的分工是:
- 讀取走資料庫的唯讀副本。 「這位客人之前來信過幾次?」「這週等待客人回覆超過 3 天的有哪些?」這類問題,查唯讀副本最直接,也不會影響正式系統(見名單和報表的 ETL 怎麼規劃)。要注意的是,資料表結構是 FreeScout 的內部設計,升級時可能改變,所以只做讀取。
- AI 寫草稿,客服按送出。 回信是對外的動作,寄出去收不回來。AI 可以根據之前的往來寫好草稿,由客服確認後送出。
- 寫入用付費 API,不要寫資料庫。 直接寫資料表會繞過 FreeScout 的商業邏輯,例如寄信、更新狀態、通知。要讓 AI 寫入,就買 API 模組。
客服工單和專案工單的分工
最後回到開頭:客服接到客訴,要交給工程師。
客服工單和專案工單是兩個系統,服務的對象不同:
- 客服工單面對客人。 裡面的每一封信都可能寄給客人,語氣、用詞都是對外的。
- 專案工單面對內部。 裡面寫的是重現步驟、程式碼、內部討論,不能讓客人看到。
所以常見的做法是:客服工單裡記下專案工單的編號,專案工單裡記下客服工單的編號,兩邊互相連結,但內容分開。工程師在專案工單標示「已解決」,客服再回到客服工單通知客人。這次實驗沒有把兩個系統串起來,這段是常見做法的說明,不是實測。
想看實作,可以讀這幾套
| 系統 | 授權 | 特色 | AI/MCP 現況(2026-10) |
|---|---|---|---|
| FreeScout | AGPL-3.0 | 輕量,介面像共用信箱;API 是付費模組 | 社群 MCP 都是 0 顆星 |
| Zammad | AGPL-3.0 | 功能較完整,支援 email、聊天、電話等多種管道 | 社群 MCP 最多 44 顆星 |
| osTicket | GPL-2.0 | 歷史最久,PHP | 我沒查 |
相關主題
- 專案管理系統在管什麼:客訴交給工程師之後的那一側
- CRM 會碰到哪些資料:同一個人在不同管道,系統要先認出來
- 會員資料怎麼進 CRM:重複的人要定期找出來合併