Skip to content

變更紀錄

2026-05-28|P2-A 漏抓修復(3-Shot + Pagination)

Section titled “2026-05-28|P2-A 漏抓修復(3-Shot + Pagination)”

5/27 一日驗證發現一通 10 分鐘的長通話(tTalk=646s)連續 4 次 cron 都漏抓,未進 HubSpot。

根因 1:Get Recordings retry sleep 5s 太短(5/26 over-correction 的副作用)

Section titled “根因 1:Get Recordings retry sleep 5s 太短(5/26 over-correction 的副作用)”
  • 5/26 為了避免 vm2 sandbox 60s task budget 撞牆,把 RETRY_SLEEP_MS 從 20000 改成 5000
  • 但代碼註解仍寫「sleep 20s」— 暗示 20s 是設計值,5s 是 hack
  • Genesys 行為:第 1 次 GET /recordings 觸發 async prep(回 HTTP 202 + empty)→ 需等 15-20 秒 才會 ready
  • 5s 太短永遠拿不到 → ready=false → Recording Ready? IF node 整通靜默丟棄
  • cron 4h 間隔,async prep TTL 短,每次重新 reset → 永久漏抓

根因 2:Query Conversations pagination 截斷

Section titled “根因 2:Query Conversations pagination 截斷”
  • 原 HTTP node 只抓 page 1(pageSize=100)
  • 5/28 13:00 cron 觀察到 totalHits=113 但只撈到 100 通 → page 2 的 13 通永遠不處理
  • Get RecordingsRETRY_SLEEPS_MS = [20000, 20000],改 3-shot(per-item budget 5+20+5+20+5=55s)
  • Get RecordingsRecording Ready?=false 時印 console.log [Get Recordings MISS] 留追蹤線索
  • Query Conversations:HTTP node → Code node + while loop paginate(MAX_PAGES=20 安全閥)

本次同步更新 docs 把「< 5 秒」改成「< 60 秒」(5/21 已實際提高擋 cold call,但 docs 沒同步)。


2026-05-27|n8n staging vs published 修正 + 卡單通話補處理

Section titled “2026-05-27|n8n staging vs published 修正 + 卡單通話補處理”

P2-C 2026-05-26 22:00 cron 失敗,error 顯示 HubSpot rejected transcribe_status: 'unanswered'(不在 enum 允許值 [pending, processing, done, failed, transcribing, transcribed, summarizing, summarized] 內)。

  1. 本地 Build Failure Patch jsCode 已是 transcribe_status: 'failed'(正確)
  2. n8n cloud editor 上的 code 也已是 'failed'
  3. 但 cron 跑的不是 editor 顯示版本——n8n cloud 區分 staging(編輯中)vs published(cron 用)
  4. 昨天 Cmd+S 只是「Name version(存到 staging)」,沒按 Publish,cron 一直跑舊版 published(仍含 'unanswered'
  • P2-C → Publish v3.3(含 Extract Call Context 單軌偵測 + Build Failure Patch 'failed' 修正)
  • P2-A → Publish v3.2(含 OUTBOUND 單軌 fail-safe + Ch1 continueErrorOutput
  • summarizing 中間態的 Call 371697855210 → 改回 transcribed,下次 cron 用新版自動處理為 failed + [UNANSWERED] reason

n8n cloud 標準改版流程:

  1. 編輯節點
  2. Cmd+S = Name version(存到 staging)
  3. Shift+P = Publish(讓 cron 真正用新版) ← 之前漏掉這步
  4. 右上 ● Publish 橘色 = 有 staging 未發佈、● Published 綠色 = 已上線

⚠️ 之前如果用 Cmd+S 後沒 Shift+P,所有改動只在 editor 看得到,cron 仍跑舊版。修改 import 後務必確認 button 從橘色變綠色。


OUTBOUND 通話 100% 卡在 P2-A Recording Ready? 走 False branch,沒進 HubSpot。診斷出兩層 bug 疊加。

  • Get RecordingsRETRY_SLEEP_MS: 20000 → 5000(避免 vm2 sandbox 對 hang request 計時不準撞 60s task budget)
  • Extract Recording URLsready: !!(ch0 && ch1)ready: !!ch0;加 isSingleChannel: !ch1 flag
  • Download Ch1 (Customer)onError: continueErrorOutput
  • Upload Ch1 to GCSonError: continueErrorOutput
  • Extract Call Context:加單軌偵測(從 transcript 找 業務] 客戶] tag),單軌時在 user content 前 prepend metadata 註記給 GPT;不動 system prompt(避免影響所有通話 GPT 過度保守)

重大發現:Trunk 其實是 dual stereo audio

Section titled “重大發現:Trunk 其實是 dual stereo audio”

原以為 OUTBOUND 是 Trunk 單軌 mono,實際資料顯示:

  • mediaUris["0"] 只是 ONE file URL(trunk 把雙軌包在同一個 stereo audio file)
  • VM chunked-transcribe.ts ffmpeg 自動 split L/R = 業務/客戶
  • 拿到完整雙軌時間穿插逐字稿,跟 INBOUND 一樣

P2-C 的單軌 prepend 邏輯成為 fail-safe——未來真有單軌情境(例如 Genesys 改設定)會自動 degrade gracefully,目前不會觸發。

  • 3 個 OUTBOUND HubSpot Call 全部 transcribe_status = summarized
  • Contact「宋子瑜」自動補上:姓名、性別「男」、稱謂「先生」、地址(大安區/台北市)、checkout_method: 刷卡;宅配、5 點摘要、3 條 follow-up

Prompt 調校第 4 輪|checkout_method 加入「刷卡」

Section titled “Prompt 調校第 4 輪|checkout_method 加入「刷卡」”
  • 背景:HubSpot「結帳/配送方式」欄位新增「刷卡」選項(第 4 個位置)
  • 檔案P2-C_v3_summarize_only.json
  • 修改
    1. System prompt 規則:5 個選項 → 6 個選項
    2. JSON schema enum:加入 "刷卡"
    3. 同義詞對應補充:信用卡 / 刷卡 / 感應付款 → 刷卡
  • 位置https://app.tiwise.com.tw/docs/
  • 內容:結案報告 + 業務員 SOP + 系統規則完整文件

Root cause 3 層

  1. P2-A 時間窗 5h 太短,跨日通話會漏
  2. VM chunkSeconds = 300 觸發 Whisper hallucination 迴圈
  3. P2-C 關鍵字過濾誤殺有效通話

修復

  • 時間窗 5h → 25h(涵蓋整天)
  • chunkSeconds 300 → 60(每片段較短,Whisper 不會 loop)
  • P2-C 加 hallucination cleaning(過濾「請訂閱頻道」等字串)

驗證:5/21 那通 200s 通話補跑成功,transcript 521 → 2059 字、業務軌 70 → 909 字,驗收 7/7 通過

詳細紀錄:[[Phase1_5-21遺失通話排查與修復_2026-05-22]]


P2-A Get Recordings 重構:Polling → Single Shot

Section titled “P2-A Get Recordings 重構:Polling → Single Shot”

問題:5/20 通話量爆 38x(5h 76 通),P2-A 撞 60s task timeout

根因

  • n8n helpers.httpRequesttimeout: 5000 option 對「HTTP 200 + empty body」不可靠
  • Genesys API 偶發回 200 但 body empty(5 通實測 4 通遇到)
  • 原 polling 設計沒對 empty body 做 immunity,會 hang 等資料

設計

Filter New → Get Recordings = 1 次 fetch + AbortController 5s
ready? → Yes → 繼續 GCS upload + 建 HubSpot Call
ready? → No → skip + 下個 cron 自動重撈

結果

  • 每 item 最壞耗時 17s → 5s
  • Genesys API 呼叫量 -75%(100 通 × 4 calls → 100 calls)
  • 撞 task timeout 風險 → 0

踩坑:n8n vm2 sandbox 不支援 AbortController 與 fetch。最終用 this.helpers.httpRequest + Promise.race 雙保險。

詳細紀錄:[[P2A_GetRecordings_重構_2026-05-20]]


  • < 5 秒通話標 [LOW_VALUE]
  • transcript < 10 字標 [UNANSWERED]
  • 兩類都不進 P2-C 摘要流程,節省 OpenAI 成本

詳細紀錄:[[P2未接通過濾改造_2026-05-18]]


  • Executions / 月:2,500(目前 ~90,使用率 3.6%)
  • Workflow execution time:60 分鐘
  • Code node task runner:60 秒 per-item
  • 結論:Frank 量級安全,撞牆需 5h 內 150+ 通真實接通(≈ 一天 600 通)

  • P2-A / P2-B / P2-C 分離
  • 從每 5 分鐘 cron 改為每日批次(當時:19:00 / 19:30 / 20:30 各一次)
  • 月用量從 25,920 降到 90(節省 99.6%)

ℹ️ 現況更新:後續為縮短業務看到摘要的等待時間,已將批次頻率調整為每天 4 輪(P2-A 09/13/17/21:00、P2-B +30 分、P2-C 10/14/18/22:00)。月用量約 360,仍在 quota 安全範圍。


  • 從單一 summary 字串 → 5 個 35 字內單句
  • 欄位:客戶 / 主題 / 現況 / 反應 / 下一步
  • 業務員一眼看懂通話重點

  • PDF 業務主管版 + Frank 完整版
  • 對應合約 12 章節結構
  • P0+P1 修復完成
  • 5 條 bullet 摘要正式上線
  • Frank 田先生 Contact 驗收通過

  • 擴充 Contact 欄位:address、city、state、zip、country、checkout_method、mentioned_products
  • 從 R2 改 GCS(穩定性 + 同地端)

初版 4 個必要欄位(合約規定)

Section titled “初版 4 個必要欄位(合約規定)”
  • customer_name / call_subject / intent_label / follow_up
  • gpt-4o-mini + JSON mode

Prompt 調校總覽(合約承諾 ≥ 3 輪)

Section titled “Prompt 調校總覽(合約承諾 ≥ 3 輪)”
輪次日期重點
v12026-04-274 個基本欄位
v22026-05-04擴充地址、結帳方式、提及產品
v32026-05-12摘要拆 5 欄、雙軌時間穿插格式
v3.12026-05-22hallucination 過濾 + 未接通過濾
v3.22026-05-25checkout_method 加入「刷卡」
v3.32026-05-26單軌通話偵測 + metadata prepend(user content 層,不動 system prompt)

已超出合約承諾的 3 輪。後續 Prompt 調校屬 Phase 2 範圍。