ShopAI 實戰日誌:用 72 小時打造餐飲 AI 客服平台
📌 關鍵要點 Key Takeaways
- 71 小時完成餐飲 AI 客服平台:含後端 API、對話引擎、管理後台、部署
- 實際人工投入:約 22 小時,其餘 49 小時由 Claude Code agent 自動完成
- 遇到 3 個嚴重 bug:2 個 AI 自己修好,1 個需要人工介入
- 最大卡點:串接 LINE Messaging API 的 webhook 驗證,耗費 4.5 小時
- 上線 48 小時後:處理 847 個顧客訊息,平均回應時間 1.2 秒
背景:為什麼要做 ShopAI?
台灣有超過 15 萬家餐飲業者。他們每天花在回覆顧客訊息上的時間,平均 2-3 小時:「請問幾點關門?」「有包廂嗎?」「素食可以嗎?」這些問題 90% 是重複的,但每一個都需要人工回覆,否則顧客就跑了。
技術棧的選擇:Node.js + Fastify 後端、PostgreSQL + Prisma ORM、Anthropic Claude API(claude-3-5-sonnet)、LINE Messaging API 整合、Vercel 部署、Claude Code 開發工具。
第 0-4 小時:需求訪談與架構設計
用 Claude Code 的 /deep-interview 功能做了 40 分鐘的需求釐清。AI 問了 23 個問題,把模糊的「餐飲 AI 客服」變成 38 個具體功能點。
核心架構決策:多租戶 SaaS 模型,每個餐廳是一個 tenant,共享基礎設施但資料完全隔離。資料庫 schema 設計用 Prisma:
model Restaurant {
id String @id @default(cuid())
name String
lineChannelId String @unique
knowledgeBase Json // 餐廳知識庫:菜單、營業時間、常見 QA
conversations Conversation[]
}
model Conversation {
id String @id @default(cuid())
restaurantId String
userId String // LINE user ID
messages Message[]
isEscalated Boolean @default(false)
}
第 4-24 小時:核心 API 開發
把任務清單交給 Claude Code 的 /ralph 自主模式。7 小時後回來:23 個 API endpoints 完成,67 個測試全部通過,還額外加了 rate limiting 和 request logging。
對話歷史太長時超過 Claude API 的 context window 限制,導致 API 錯誤。Claude Code 標記了問題但沒自動修復(需要業務決策:截斷還是摘要?)
保留最近 10 則訊息,更早的對話用 Claude 自動摘要成一段文字放在 system prompt 裡。修復花了 45 分鐘。
LINE webhook 有嚴格的 HMAC-SHA256 簽名驗證機制,body 必須是 raw bytes,不能先被 JSON.parse 處理。
Fastify 預設在 middleware 前就把 body 解析成物件,導致簽名驗證永遠失敗。錯誤訊息
Invalid signature 完全看不出是 body parsing 的問題。
加
addContentTypeParser 攔截器,在 LINE webhook route 上禁用自動 JSON 解析,保留 raw buffer 手動驗證簽名後再 parse。Claude Code 在我描述症狀後 8 分鐘給出正確答案。
fastify.addContentTypeParser(
'application/json',
{ parseAs: 'buffer' },
async (req, body) => {
if (req.url.startsWith('/webhook/line')) {
const signature = req.headers['x-line-signature'];
verifyLineSignature(body, signature);
}
return JSON.parse(body.toString());
}
);
第 24-48 小時:UI 與對話系統
這是 AI 客服品質的關鍵。最終版本的核心設計:加入 [ESCALATE] token——AI 判斷需要轉人工時在回覆中插入這個 token,後端攔截後自動標記並通知餐廳老闆。
你是「{餐廳名稱}」的 AI 客服助理。
## 餐廳資訊
{knowledge_base_json}
## 回覆原則
1. 只回答你有把握的問題
2. 不確定時誠實說「這個問題我需要請同仁確認」
3. 需要預訂或特殊需求時回覆 [ESCALATE]
4. 回覆長度控制在 100 字以內
餐廳老闆更新菜單後,AI 繼續用舊資料回覆顧客。知識庫被快取在記憶體裡,TTL 設了 24 小時。測試環境沒問題(每次測試都重啟 server),但生產環境是致命的。
cache key 包含
restaurant:{id}:kb:v{version},每次更新版本號自動遞增,舊快取立即失效。
第 48-72 小時:測試與上線
- P50 回應時間:0.9 秒
- P99 回應時間:3.1 秒(Claude API latency 佔大部分)
- 加了 retry 邏輯後錯誤率從 0.3% 降到 0.01%
- 處理訊息:847 則
- AI 自動回覆率:91.3%(773 則)
- 轉人工率:8.7%(74 則)
- 平均回應時間:1.2 秒
三個下次會做不同的事
1. 先做第三方 API 整合,不要留到最後。LINE webhook 的 4.5 小時卡點本可更早發現。第三方 API 整合永遠是最大的不確定因素,H+0 就要先建立最小可行的 webhook。
2. 快取策略要在架構設計階段確定。Bug #3 之所以在凌晨 3 點才被發現,是因為開發階段的測試流程掩蓋了快取 invalidation 的問題。設計 API 時同步設計快取策略,而不是功能完成後再補。
3. AI Agent 任務需要更明確的驗收標準。「實作用戶認證」遠不如「實作 JWT 認證,access token 有效期 15 分鐘,refresh token 7 天,需要 revocation 機制,所有 protected routes 必須有 middleware 保護」。越具體輸出越好。