從單次問答到真正的「對話記憶」
在先前的早餐店機器人實戰中,我們成功地把 OpenAI (ChatGPT) 接到了 LINE 的 Webhook 裡。 那時候,客人發一句話,機器人就回一句話。這看起來很聰明,但如果你仔細測試,你會發現一個致命的缺點:它會失憶。
例如: 客人:「老闆,我要點一份蛋餅。」 機器人:「好的!一份原味蛋餅,總共 30 元。請問還要其他東西嗎?」 客人:「那再加一杯大冰奶好了。」 機器人:「好的!一杯大冰奶 20 元。請問還要點什麼嗎?」 客人:「就這樣,總共多少錢?」 機器人:「請問您點了什麼呢?」
這就是所謂的「單輪對話 (Single-turn conversation)」。每次 Webhook 收到訊息去呼叫 OpenAI 時,OpenAI 都是把它當作一個全新的客人,它根本不記得上一秒聊了什麼!
要打造真正能取代人力的 AI 客服,我們必須讓機器人擁有「短期記憶 (Short-term memory)」。
🧠 給 AI 裝上大腦海馬迴:對話陣列 (Messages Array)
要讓 OpenAI 有記憶,原理其實出乎意料地簡單:每一次呼叫 API 時,你不能只傳給它「最新的一句話」,你要把它過去聊過的所有歷史紀錄,打包成一整包再傳給它。
在 OpenAI 的 API 規格中,我們送出去的請求是一個名為 messages 的陣列:
const messages = [
{ role: "system", content: "你是早餐店老闆娘..." }, // 系統人設 (上帝視角)
{ role: "user", content: "我要一份蛋餅" }, // 客人講的話 (歷史紀錄 1)
{ role: "assistant", content: "好的,還要其他的嗎?" }, // AI 剛剛回的話 (歷史紀錄 2)
{ role: "user", content: "再加一杯冰奶茶" } // 客人現在最新的一句話
];
當你把這個完整的 messages 陣列丟給 OpenAI,它就能像看劇本一樣,瞬間理解前因後果,然後給你完美的回覆!
🛠️ Vibe Coding 實戰:用記憶體暫存對話
如果要我們自己手寫這個記憶管理邏輯,會非常複雜:你要把每個人的 Line ID 當作 Key,去查他過去的對話,超過一定長度還要刪除舊記憶,以免超出 Token 上限。
這時,我們要召喚最強的外掛:Cursor + Vibe Prompt。
【AI 記憶客服 Vibe Prompt】 我正在開發一個 Line Bot 的 Node.js 伺服器,負責處理客服聊天。 之前的版本 AI 無法記住上下文,現在我需要你幫我重構邏輯,加入「對話記憶功能」。
請遵循以下實作細節:
- 使用一個全域變數
const memoryStore = new Map()來當作記憶體暫存區。以使用者的lineUserId當作 Key,Value 是一個儲存該使用者messages的陣列。- 當收到新訊息時,先從
memoryStore拿出歷史紀錄。如果沒有,就初始化一個包含 System Prompt 的新陣列。- 將使用者的最新訊息
.push()進陣列,然後發送給 OpenAIgpt-4o-mini。- 收到 OpenAI 回覆後,將 AI 的回覆也
.push()進同一個陣列中存起來。- 【重要機制】為了避免陣列無限增長導致記憶體爆滿或 Token 爆表,請實作「自動裁切」功能:如果該用戶的歷史對話超過 10 句 (即陣列長度 > 11,包含 system),請自動將最舊的一問一答給移除 (
splice)。- 請提供完整的 Node.js Express 程式碼,加上清楚的中文註解。
送出這段咒語後,AI 會瞬間產出一段包含 Map 資料結構與 Array.splice 邏輯的完美程式碼。
這套系統的威力:多重任務客服
一旦你的 LINE Bot 有了記憶,它的商業價值將翻倍成長:
- 連續搜集資料: 「請問您的大名?」➡️「林先生你好,那請問您的電話是?」➡️「好的,林先生,電話 0912,請問您要預約什麼時間?」(它能一步步引導客人完成表單)。
- 專業技術客服: 「我的螢幕無法開機。」➡️ AI 教了三個步驟 ➡️「第二個步驟我卡住了,燈沒有亮。」➡️ AI 能針對第二步繼續深入解決。
- 高黏著度陪伴機器人: 像塔羅牌占卜師、心理諮商 AI、甚至是虛擬女友,都是建立在這個強大的「記憶體管理機制」之上的。
🚨 記憶系統的進階考量:當伺服器重新啟動時
眼尖的你可能發現了,我們在上面的 Prompt 中,把對話紀錄存在 new Map() 裡面,這叫做「記憶體內暫存 (In-memory storage)」。
這在測試開發時非常快、非常好用。但它有一個致命弱點:如果你的伺服器當機,或是你在 Vercel/Render 上重新部署了程式,這個 memoryStore 就會瞬間清空,所有機器人都會再度「集體失憶」。
如果你在接案時,這是一個每月收費 3 萬塊的高端客服系統,我們就不能容許這種事發生。
在真正的企業級架構中,我們會把這個 messages 陣列轉換成 JSON 格式,存到 Redis (記憶體資料庫) 或是 Supabase (PostgreSQL) 裡面持久化保存。
但在前期快速驗證商業模式 (MVP) 時,先用 Node.js 的 Map 陣列跑起來,已經足以讓你震撼客戶,成功把案子簽下來了!準備好去改造你的早餐店阿姨了嗎?下一章我們將教你更猛的 LINE 隱藏武器:LIFF 網頁!