ShopAI 實戰日誌:用 72 小時打造餐飲 AI 客服平台

海衫科技 HarrysonTech | | 閱讀時間:15 分鐘
H
HarrysonTech Engineering
AI-driven tech team · 2 engineers + AI Agents · ShopAI 產品負責人
ShopAI 從第一行程式碼到正式上線,總共花了 71 小時 23 分鐘。這是完整的工程師視角紀錄:包含三個嚴重 bug、兩次架構翻盤、以及一個在凌晨 3 點發現的致命快取問題。不修飾、不美化,就是實際發生的事。

📌 關鍵要點 Key Takeaways

71h總開發時間
22h人工投入
847上線 48h 訊息數
1.2s平均回應時間

背景:為什麼要做 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 小時:需求訪談與架構設計

H+0:00 需求釐清 + 架構決策

用 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 開發

H+4:00 啟動 /ralph 自主模式,去睡覺

把任務清單交給 Claude Code 的 /ralph 自主模式。7 小時後回來:23 個 API endpoints 完成,67 個測試全部通過,還額外加了 rate limiting 和 request logging。

🐛 Bug #1:Context window 管理問題
對話歷史太長時超過 Claude API 的 context window 限制,導致 API 錯誤。Claude Code 標記了問題但沒自動修復(需要業務決策:截斷還是摘要?)
✅ 修復:滑動視窗 + 摘要策略
保留最近 10 則訊息,更早的對話用 Claude 自動摘要成一段文字放在 system prompt 裡。修復花了 45 分鐘。
H+13:00 LINE Messaging API 整合——最大卡點(4.5 小時)

LINE webhook 有嚴格的 HMAC-SHA256 簽名驗證機制,body 必須是 raw bytes,不能先被 JSON.parse 處理。

🐛 Bug #2:Fastify 的 body parsing 問題
Fastify 預設在 middleware 前就把 body 解析成物件,導致簽名驗證永遠失敗。錯誤訊息 Invalid signature 完全看不出是 body parsing 的問題。
✅ 修復:攔截 raw buffer
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 與對話系統

H+31:00 System Prompt 工程——測試 7 種版本

這是 AI 客服品質的關鍵。最終版本的核心設計:加入 [ESCALATE] token——AI 判斷需要轉人工時在回覆中插入這個 token,後端攔截後自動標記並通知餐廳老闆。

你是「{餐廳名稱}」的 AI 客服助理。

## 餐廳資訊
{knowledge_base_json}

## 回覆原則
1. 只回答你有把握的問題
2. 不確定時誠實說「這個問題我需要請同仁確認」
3. 需要預訂或特殊需求時回覆 [ESCALATE]
4. 回覆長度控制在 100 字以內
H+39:00 凌晨 3 點的快取災難
🐛 Bug #3(最嚴重):知識庫快取沒有 invalidation
餐廳老闆更新菜單後,AI 繼續用舊資料回覆顧客。知識庫被快取在記憶體裡,TTL 設了 24 小時。測試環境沒問題(每次測試都重啟 server),但生產環境是致命的。
✅ 修復:改用 Redis + 版本號 cache key
cache key 包含 restaurant:{id}:kb:v{version},每次更新版本號自動遞增,舊快取立即失效。

第 48-72 小時:測試與上線

H+48:00 k6 壓力測試:500 並發對話
H+71:23 正式上線 · 上線 48 小時數據

三個下次會做不同的事

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 保護」。越具體輸出越好。

想為你的餐廳導入 AI 客服?

ShopAI 目前開放早鳥測試,免費試用 30 天

立即申請試用 →