把客人的一句話
變成一筆正確的訂位
這是一本從零開始的 AI 客服機器人原理讀本。我們不堆術語,而是從「一句『6/21 兩大一小一狗』怎麼從 LINE 訊息,一路被讀懂、查證、變成老闆面前一顆可以按的按鈕」這條路徑,一步步認識沿途的每個零件——它為什麼存在、解決什麼問題,以及它對這句話做了什麼。
一條貫穿全書的訊息鏈
在拆解任何一個零件之前,先記住一個觀念:無論客人是想訂位、改訂、取消,還是只是問「有沒有停車場」,所有訊息走的都是同一條鏈。差別只在「中間哪一段需要動用比較重的工具」。把這條鏈記熟,後面每一章都只是在放大其中一塊。
先讀第 1 章建立「聽懂人話、說真話」的直覺,它是全書的歐姆定律。再讀第 2 ~ 4 章——它把訊息鏈每一段都走過一次,是骨幹。第 5 ~ 8 章是延伸與進階,讀起來會輕鬆很多。
第一原則:聽懂人話,說真話
要看懂後面所有設計,只需要先建立一個直覺:把「理解」和「事實」這兩件事,交給兩個完全不同的東西去做。這條分工就是整個系統的第一條定律。
1.1為什麼一定要分工
大型語言模型(LLM)非常會「猜人話的意思」,但它不可靠地計算事實。如果讓它自己決定「今天還有沒有位子」「訂金收多少」,它會用很有自信的口氣講出錯的數字——這在餐廳場景是災難:超賣、報錯訂金。所以我們把責任切開:
- LLM 只負責兩件事:把客人任何寫法的話讀懂(理解層)、決定用什麼語氣跟客人講。
- 所有事實由程式算:有沒有位、剩幾位、訂金多少、能不能改——這些一律走確定性程式(真相層)。
沒有這條分工時,LLM 看到「今晚 8 位」會直接回「沒問題幫您留好了!」——但實際上當天只剩 5 個位子。客人開心地來,現場卻沒位子。箝住 AI 的嘴、讓程式查證後才出口,正是第 4 章要做的事。
1.2四層架構:把規則關進閘門
「說真話」不是寫在 AI 的腦袋裡,而是寫在一套四層架構裡。任何商業規則都不可以塞進畫面或 AI,而要拆成四層,各司其職:
| 層 | 負責什麼 | 例子 |
|---|---|---|
| Gate 閘 | 純規則:輸入狀態,回傳能不能。不碰資料庫、不發 IO | 「這筆能不能取消?」 |
| Primitive | 單一副作用單元(一次寫入 / 一次推播) | 建一筆暫留、更新訂金狀態 |
| Orchestrator | 依 Gate 結果組合 Primitive,回傳結果 | 換桌、踢人、確認訂位 |
| Route / View | 超薄:解析輸入 → 呼叫 Orchestrator → 翻成回應 | API 端點、畫面按鈕 |
Gate 是純函數——同樣的輸入永遠得到同樣的輸出,沒有副作用。這代表它可測試、可重用、不會說謊。AI 想做任何動作,最後都要通過這些 Gate;AI 自己說了不算,Gate 點頭才算。這就是「程式說真話」的物理基礎。
理解層:從「問一次」到 Agent 迴圈
理解層的工作,是把客人那句口語變成結構化資料(日期、時間、人數、意圖)。早期我們只「問 LLM 一次」就收工——但這太笨。這一章把它升級成會自己查資料再回答的 Agent 迴圈。
2.1一次性抽取器的極限
「問一次」的模式是:訊息進來 → 丟給 LLM → 它吐一段回覆。問題是它什麼都不能查——不知道今天有沒有位、不知道客人之前有沒有訂位,只能憑訊息本身猜。客滿了它只會乾巴巴說「客滿」,不會主動找替代時段。
2.2Agent 迴圈:想 → 查 → 再想
Agent 迴圈(業界稱 tool-calling / function calling)讓 LLM 多了一隻手:它可以在回答前,自己決定「我需要先查一下」,呼叫一個工具,看到結果後再繼續想,繞上好幾圈,最後才給出接地的回覆。
迴圈不能無限繞。我們設了上限(每則訊息最多 5 圈工具呼叫)、整段逾時 22 秒,超過就退回保守做法。萬一 Agent 沒吐出乾淨結果,系統會自動退回「問一次」的舊路——升級永遠不會讓行為變差。
工具箱:AI 的技能
Agent 有手,但手要握得住東西。這一章是全書的「元件表」:AI 能呼叫的工具。工具分兩種——唯讀工具(只看不動)可以放心讓 AI 自由用;寫入工具(會改資料)一律加護欄。
3.1唯讀工具:AI 的眼睛
每一個工具內部都是確定性程式——它去查真實資料、回傳事實,AI 不自己算。這就是第一原則的延伸:AI 透過工具「看見」真相,而不是「想像」真相。
| 工具 | 用途 |
|---|---|
| check_availability | 查某日某人數可不可訂、各時段剩幾位 |
| suggest_alternatives | 客滿時找鄰近可訂時段/日期,主動給選項 |
| get_deposit_rule | 依人數算訂金(門檻、金額),金額一律以此為準 |
| get_restaurant_settings | 寵物友善、兒童椅、人數上限、併桌門檻、政策 |
| get_business_hours | 某日有沒有營業、公休、暫停接訂位 |
| find_customer_reservations | 查這位客人現有訂位(判斷新訂/改訂/取消) |
| search_menu | 語意搜尋菜單/價格/素食 |
| search_knowledge | 語意搜尋 FAQ/停車/寵物政策/官網 |
3.2寫入工具與三層護欄
會「改資料」的工具危險得多。我們用一道護欄光譜把它們分成三級,越不可逆的動作,AI 的權限越小:
當 AI 提議「取消 6/21 那筆」,它不回訂位的內部編號(UUID)——因為 LLM 會把編號亂編。它只回 target_date/target_time,由 POS 自己比對到真實那筆訂位,再給出按鈕。AI 指「哪一天那筆」,程式負責「找出真的是哪一筆」。
真相層:決策閘與「箝位」
這一章是骨幹。AI 給出的回覆,在送到客人面前之前,要先通過一道決策閘。它的作用就像電子電路裡的箝位:把 AI 過度樂觀的承諾,強制壓回「事實允許的安全範圍」。
4.1箝位:把承諾壓回事實
AI 可能讀懂了「今晚 8 位」,也擬了一句溫暖的「幫您留好了」。但在出口前,程式會去 check_availability 查真相。如果真的可訂,就放行 AI 那句溫暖的話;如果其實客滿,就把回覆換成確定性版本——「不好意思客滿了,這幾個時段還可以…」。AI 的語氣再好,也不能突破事實的天花板。
4.2哪些事走真相層
| 問題 | 誰回答 | 來源 |
|---|---|---|
| 有沒有位 | 程式 | /api/availability(訂位系統 dry-run) |
| 訂金多少 | 程式 | deposit gate(只看門檻人數) |
| 要不要暫留 | 程式 | canHold gate(可訂 + 信心夠) |
| 怎麼跟客人講 | AI | 已被上面事實接地後的語氣 |
AI 提供「溫度」,Gate 提供「真相」。兩者相乘,才是一句既親切又不會出錯的回覆。
動作與狀態管理
當客人想改訂位、取消,AI 不會自己動手——它提議,老闆按下。這一章談兩件事:怎麼把提議變成按鈕;以及怎麼讓系統記得「這顆按鈕已經給過、已經被按過」,不重複騷擾老闆。
5.1提議 → 按鈕 → 老闆按
客人說「前面兩筆都取消」,AI 先用 find_customer_reservations 查出他有哪幾筆,然後輸出一組 提議動作(proposed_actions),每筆指名「對哪一天那筆做什麼」。POS 把每筆比對到真實訂位、長出一顆按鈕;老闆按下去,才跑第 1 章的四層 API(Gate 在伺服器端再驗一次)。
5.2用「現有欄位」管理按鈕狀態
一張「待接單」卡片有三種狀態。我們不發明複雜的新欄位,而是用三個既有訊號精準描述它的一生:
reservation_intent=該不該顯示卡;locallyConfirmedIds=老闆剛按下、立刻把卡藏起來(不等同步);chefsmate_reservation_id=已確認的持久標記。三者合起來,按鈕「按過就不再出現」。因為一句「我要取消」被前文帶進來的日期,誤判成「又一筆新訂位」→ 又長出一張待接單卡。解法是:取消/改訂位的訊息一律不是新訂位(reservation_intent=false),而且同一客人同時段已有訂位就不重複開卡。狀態管理對了,按鈕就不會幽靈式重生。
學習(上):私有與共有
前五章讓 AI 會做事;這兩章讓它越用越聰明。核心洞見是:學習的東西要分兩種——私有知識(這家店的事實)和共有知識(怎麼讀懂訊息)。分清楚,才不會存一堆沒用的流水帳。
6.1流水帳 ≠ 記憶
如果把每一則訊息原封不動存起來叫「學習」,最後只會得到一大堆沒結構的紀錄。業界一定把兩者分開:
| 流水帳 Log | 記憶 Memory | |
|---|---|---|
| 存什麼 | 每則原始訊息 + AI 判讀 | 結構化、去重、被驗證過的問答 |
| 拿來幹嘛 | 除錯 / 稽核 | 下次檢索參考 |
| 誰能進 | 全部 | 只有老闆認可的才晉升 |
6.2私有:好冷啟動,靠認可累積
私有知識(營業時間、座位數、寵物友善、菜單)很好冷啟動:開店前把設定、FAQ、菜單填完就有足夠的料。剩下的邊界案例靠日積月累——而且只有「老闆原封不動送出的回覆」才會晉升成記憶(代表這題答對了)。老闆大改過的,學改後的版本;沒送的,不學。這叫回饋閘門(feedback-gated memory)。
6.3共有:問題共有,答案私有
巧妙的地方在這:「有沒有停車場」這個問題,每家店都該回答,所以它屬於共有問題清單;但海邊小巫答「有」、別家答「沒有」,答案是私有的。新店一開張,系統就能拿這份清單請他預填——這就是數據護城河:用得越久、店越多,新店冷啟動越快。
6.4零重複設定:完整度儀表板
新店要回答共有清單時,怕跟 POS 既有設定重複填。解法是把帳號管理頁做成完整度儀表板,而不是第二個輸入框:
- POS 已有對應設定的問題(營業時間、座位數):只讀現況顯示狀態(✅已設定 / ⚠️未設定 → 點了跳去 POS 設定)。單一真相=POS,不重複輸入。
- POS 沒有欄位的問題(停車、Wi-Fi):才在這頁用選擇題作答(有 / 沒有)→ 存成 FAQ。
學習(下):概念化的判斷規則
共有知識的第二種,是「怎麼讀懂訊息」的判斷規則。這一章用一個經典難題收尾:6.21 到底是 6 月 21 日,還是 18:21,還是 6:21?答案不是死背,而是一套判斷流程。
7.1標準消歧流程:四步決策
遇到任何模糊的數字,都套用同一套優先序。能在前一步定案就不往下走:
精準值(這位客人要 18:00)留在他的私有訂位紀錄。共有記憶存的是「模糊數字怎麼消歧」這條概念規則。一筆規則 = 情境 + 判斷流程 + 範例 + 信心 + 套用次數 + 被更正次數。它套用到所有店、所有未來的模糊值。
7.2防汙染:共有規則要審核才上線
共有規則一旦更新,會影響所有餐廳。一條壞規則就是全網災難。所以共有規則走「提議 → 審核門檻 → 晉升」:門檻可以是「跨 M 家店、被同方向更正 N 次」,或人工審。未達門檻只記不啟用。共有內容一律去個資、去店名。
規則學成後雙向餵:能寫成程式的 → 進確定性解析器;難寫死的 → 進 LLM 的提示當指引。下一次同樣的「6.21」進來,第 1 章的理解層就更準,第 4 章的真相層也更穩。學習不是另一個系統,而是回頭餵養前面每一章。
多管道:一個大腦,多個管道
客人不只在 LINE。他們也在 Instagram、Facebook 私訊。但我們不為每個平台養一隻 AI——而是一個大腦,多個管道:所有平台的訊息正規化進同一個收件箱,交給同一套理解層處理,再用對應的送出器回覆。
channel 欄位),交給同一支 Agent,再依管道用對應送出器回覆。新增一個平台,只是多接一條進水管,大腦不變。Meta 走官方 webhook:收訊要驗證 hub.challenge 與 X-Hub-Signature;回覆走 Graph Send API,而且有 24 小時客服訊息視窗的規則。平台前置(開 Meta App、拿 Page Access Token、App Review)需要老闆操作,所以這一波排在 Agent 穩定之後。
名詞總表・實作起手式
A.1該認識的零件一覽
| 零件 | 它解決什麼問題 | 章節 |
|---|---|---|
| 第一原則 | 分工:LLM 聽懂人話、程式說真話 | 1 |
| 四層架構 | 把規則關進 Gate,AI 說了不算 | 1 · 4 |
| Agent 迴圈 | 讓 LLM 自己查資料再回答 | 2 |
| 唯讀工具 | AI 的眼睛:查位 / 訂金 / 設定 / 菜單 | 3 |
| 護欄光譜 | 自動 / 提案 / 永不自動三級權限 | 3 |
| 決策閘(箝位) | 把 AI 承諾壓回事實,防超賣 | 4 |
| proposed_actions | AI 提議、老闆按、程式執行 | 5 |
| 狀態三訊號 | 按鈕「按過就不再出現」 | 5 |
| 私有 / 共有 | 店家事實 vs 怎麼讀懂訊息 | 6 |
| 消歧四步 | 前後文→可行性→常理→不懂就問 | 7 |
| 多管道收件箱 | 一個大腦服務 LINE / IG / FB | 8 |
A.2建議的實作順序(Roadmap)
Wave A/B:Agent 迴圈 + 唯讀工具箱(✅ 已上線)
line-process 改成 tool-calling,8 個唯讀工具讓 AI 自己查位、客滿主動給替代時段。
Wave C:寫入工具 + 護欄(進行中)
proposed_actions → POS 動作按鈕 → 老闆按 → 四層 API。狀態三訊號讓按鈕不重複出現。
學習 L1:共有問題清單 + 完整度儀表板
新店一開就有料、基礎設定不重複問(讀 POS 狀態 + 沒對應的才選擇題作答)。
學習 L2:私有記憶晉升 + 語意去重
老闆「原封不動送出」=認可訊號 → 晉升記憶;學習頁改成「結構化記憶卡」。
學習 L3:共有判斷規則庫
消歧四步 schema + 更正→提煉→審核門檻→晉升 + 雙向餵養解析器與提示。
Wave D:Meta 多管道
收件箱加 channel 欄位 + Instagram / Facebook webhook 收發。
所有圖表裡的「箝位」「天花板」都是比喻;真正的事實來源永遠是 Gate 與訂位系統的 dry-run API。改任何一段前,先回到第 1 章那條定律:這段是在「聽懂人話」還是「說真話」?放錯層,系統就會開始說謊。