先把失敗位置說清楚
假設你每次發布文章後,會讀取正文、請 AI 草擬摘要、人工批准,再發送到團隊通知頻道。這四步中,「重做摘要」主要增加運算和審閱成本,「重發通知」則會改變外部系統。兩者不能套用同一個重試決策。
n8n 的執行與重試文件說明,失敗重試會沿用已保存的執行狀態;完成節點的結果會保留,但失敗節點會重新處理收到的項目。因此,若發送節點在一批通知中途失敗,先前已處理的項目仍可能再次發送。這是查核當日文件描述的行為,套用前要核對自己使用的版本。
先記錄失敗的是摘要、批准、發送,還是回執寫入。若只有「整個流程失敗」這一個訊息,資料不足以決定重送。
用一個固定識別,代表一件通知任務
本例規定:一篇文章的同一個已批准版本,只需要向同一個目的地通知一次。用三個固定欄位代表這件事:
article_id = note-017
approved_version = v1
destination_id = team-demo
notification_key = ["note-017", "v1", "team-demo"]用結構化欄位或不會產生歧義的編碼保存識別。不要直接把任意文字以分隔符拼接,否則欄位本身含分隔符時可能混淆。批准版本由你的發布紀錄決定,不由 AI 每次重試時重新命名。
不要用摘要全文作為唯一識別:同一篇文章再次生成摘要,措辭可能不同,但仍是同一件通知任務。反過來,只用文章編號又會擋住真正批准的新版本。若 v2 值得再通知,先批准 v2,再建立新的任務;單純修正標點是否需要通知,則是你應先訂好的編輯規則。
事件識別也不一定等於業務任務識別。例如 GitHub 官方文件指出,重新投遞的 webhook 會保留原有的 X-GitHub-Delivery 值。它可以協助辨認同一事件的重送,但如果同一業務任務可能由不同事件觸發,仍要以你的通知單位做第二層判斷。
「看過資料」和「服務接受通知」是兩件事
n8n Remove Duplicates 文件區分目前輸入內的重複,以及先前執行處理過的重複。只檢查目前輸入,無法單靠這個設定辨認上一輪已出現的資料。跨執行比較也有保存範圍與歷史容量限制,不能視為永久紀錄。
更關鍵的是,去重紀錄只回答「見過沒有」,不回答「後面的發送成功沒有」。下面是本站編寫的反例:你在發送前,把通知鍵永久標成「完成」;接著摘要驗收失敗,根本未送出。下次執行因為已完成而跳過,結果是漏通知。如果等到發送後才記完成,服務已接受、但回執寫入失敗時,又可能重複通知。
因此本例分開保存狀態:not_started 表示確定尚未進入發送;in_progress 表示已被某個執行領取;accepted 表示有服務接受請求的證據;unknown 表示已嘗試發送卻無法確定外部結果。服務接受不等於成功送達,更不等於已讀。退信或投遞失敗需要另一套核對流程。
先用六個獨立案例驗收決策
每一列都是獨立情境,不要把前一列的狀態帶到下一列。先遮住答案,用自己目前的流程判斷,再核對下表。「建立待送項目」只代表可以排入待處理清單,不代表立刻對外發送。
| 案例 | 已知條件 | 預期決策 | 核對理由 |
|---|---|---|---|
| A | 首次處理;沒有紀錄 | 建立待送項目 | 先驗摘要,再建立唯一任務 |
| B | 同一版本已取得服務接受回執 | 跳過自動重送 | 保留回執;接受不等於收件人已讀 |
| C | 送出後逾時;服務結果查不到 | 人工核對 | 不得把逾時當成未送出 |
| D | 摘要生成失敗;發送步驟尚未開始 | 修正後續跑 | 重做摘要,不必重做已完成的安全步驟 |
| E | 第二個執行遇到已被領取的同一任務 | 等待並查狀態 | 不可同時發送;過期仍須核對外部結果 |
| F | 已批准 v2,舊紀錄只有 v1 | 建立待送項目 | 新版本是新任務;不要用重試創造版本 |
特別檢查 C 和 E:沒有回應不等於未發送;執行逾時或鎖過期也不等於外部沒有變更。若你的流程在這兩種情況直接重新送出,還缺少核對或冪等機制。
下載六個案例、答案與重試核對表。可用文字編輯器填寫工具版本、執行 ID、回執、時間與人工決策;不要把帳號密碼或完整私人訊息寫進紀錄。
把發送前後的檢查接回流程
- 固定輸入。保存已批准的摘要版本、文章編號及目的地代號。重試發送時沿用批准內容;若重做摘要,先重新驗收,避免悄悄換掉內容。
- 查詢狀態。同一通知鍵已有接受回執時,不自動重送;正在處理時等待;結果不明時交人工核對。沒有紀錄才建立待送任務。
- 一次只讓一個執行領取。正式系統需要原子性的唯一鍵建立或條件更新,避免兩個執行同時查到「不存在」後都發送。共享試算表先查後寫,不能直接當作這種保證。
- 發送並保存證據。如果目的地正式支援冪等鍵,依其文件把同一通知鍵映射為穩定的請求識別,並核對保存時間、請求內容限制和衝突處理。自己多加一個欄位,不會讓不支援此功能的服務變得冪等。
- 處理不確定結果。收到服務接受回執後記為 accepted。發送逾時或回執保存失敗時,先查目的地紀錄;能確認已接受才補登,能確認未執行才批准重送。查不到就保持 unknown,安排人工追查。
即使內部任務領取是原子的,發送和保存回執仍可能分屬兩個系統。這段中間空隙,是單靠一張狀態表無法消除的限制。本文的保守做法會讓部分通知暫停等待人工處理,換取不盲目重送;它不保證端到端恰好送達一次。
可先接一個只寫入本地清單的假發送器,模擬「接受後逾時」和「回執寫入失敗」。本地模擬只驗證分支,不代表真實服務具備相同保證。上線前,再以你控制的測試目的地小量驗收。
在 n8n 按下 Retry 之前看什麼
先看失敗節點的輸入項目及目的地現況,確認是否有部分項目已完成。依 n8n 官方文件,使用原工作流或目前保存的工作流重試,都會帶入先前執行資料;修改後的流程也不會重新計算已完成節點的結果。若修的是摘要內容,不能假設選擇新流程就會自動更新先前已完成的摘要。
再確認下游需要的通知鍵、批准版本、狀態與回執仍在。去重歷史的保留時間要涵蓋你允許重送舊事件的期間,並設定容量、逾期紀錄與人工補送規則。不要為了讓一筆通知通過而清空整批歷史,否則其他舊資料也可能再次進入流程。
最後逐筆填下:是否曾開始發送、證據在哪裡、誰批准重送。未取得證據的項目留在待查清單,別把重試按鈕當成修復原因本身。
讓 AI 協助找漏洞,不讓它替你猜結果
以下提示詞適合用來審查節點設計。提供去識別化的節點順序和必要欄位即可,無須貼入真實客戶資料或憑證。
請檢查這個 AI 摘要通知流程的重試設計,不要執行或發送訊息。
任務:將已批准的文章摘要送到指定的測試目的地。
通知識別:article_id + approved_version + destination_id。
AI 只負責草擬摘要;批准版本、目的地及狀態以流程紀錄為準。
請先問我缺少的資料,不要假設工具具有交易鎖或冪等保證。
請逐項回答:
1. 哪些步驟只讀資料,哪些步驟會造成外部變更?
2. 發送逾時、部分批次成功、寫入回執失敗,各自如何恢復?
3. 兩個執行同時處理相同任務時,哪裡能保證只有一個領取成功?
4. 如果目的地不支援冪等鍵,哪些情況必須改成人工核對?
5. 為本文六個案例列出決策與待查證的官方文件。
不要把提供了重試按鈕,解讀成不會重複發送。
以下貼上我的節點順序、工具版本、狀態欄位與目的地文件:驗收 AI 回答時,先看它有沒有把「逾時」判成「確定未送出」,再看它是否說明並行執行和歷史紀錄過期。答案只有「加上去重節點、重試三次」仍不足以處理本文的案例。
若摘要本身尚未通過驗收,先依來源主張核對方法檢查內容;要記錄多次執行結果,可搭配小型任務測試表。先把內容品質和通知狀態分別記清楚,才知道該修的是哪一步。