專案管理那篇的開頭,是客服接到一封客訴,要交給工程師處理。那篇講的是工程師那一側。這篇往前一步,看客服那一側:客人的信寄到哪裡、誰回、回到哪了。

客服信箱如果是一個大家共用的 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 會碰到哪些資料那篇講的身分問題一模一樣:同一個人在不同管道留了不同的聯絡方式,系統要先回答「這是不是同一個人」。

對客服團隊來說,要做的事:

  1. 接手工單時,先查同一位客人和同名客人的其他工單。 系統不會自動合併,要靠人看。
  2. 發現重複時,合併工單或客人資料。 不要兩張單各自回覆。FreeScout 的核心有合併工單和合併客人的功能。這點我只在程式碼裡確認過,沒有實際操作。
  3. 客服回信的範本請客人「直接回覆這封信」。 這是讓信回到原工單最簡單的方法。

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)
FreeScoutAGPL-3.0輕量,介面像共用信箱;API 是付費模組社群 MCP 都是 0 顆星
ZammadAGPL-3.0功能較完整,支援 email、聊天、電話等多種管道社群 MCP 最多 44 顆星
osTicketGPL-2.0歷史最久,PHP我沒查

相關主題