iT邦幫忙

2025 iThome 鐵人賽

DAY 12
0
生成式 AI

打造基於 MCP 協議與 n8n 工作流的會議處理 Agent系列 第 12 篇

Day 12 系統可靠性升級 - 錯誤處理與狀態回報

  • 分享至 

  • xImage
  •  

昨天我們的 Agent 學會了辨識「會議類型」、「專案名稱」與專案關聯,但一個穩定可靠的系統,不只要能在順利時完美運作,更要在發生意外時能有條理的處理失敗。
今天的目標是為我們的 MCP Agent 建立錯誤處理與狀態回報機制,讓它變得更加「可靠」。

今天的目標與挑戰

  • 在 Notion 新增「錯誤訊息」欄位
  • 在流程開始時就建立記錄並且更新狀態為「處理中」
  • 建立一個獨立的「錯誤處理」工作流,使用 Error Trigger 節點統一捕獲異常
  • 當錯誤發生時,建立錯誤紀錄,並詳細記錄錯誤原因
  • 透過 LINE 發送執行紀錄ID與錯誤紀錄頁面連結的通知,加速問題排查

為什麼需要錯誤處理機制?

如果沒有錯誤處理,流程會直接中斷,我們不僅無法得知任務失敗,也不知道問題出在哪裡,因此一個好的錯誤處理機制能帶來四大好處

  1. 可靠性:系統不會因單點故障而完全崩潰,而是能捕獲異常並執行備用路徑
  2. 可觀測性:當問題發生時,我們能清楚知道是哪個環節、因為什麼原因失敗
  3. 除錯效率:詳細的錯誤通知能讓我們立即定位問題,大幅縮短修復時間
  4. 使用者體驗:系統會明確回報「成功」或「失敗」,而不是讓使用者無限等待或困惑

Step 1:更新 Notion 資料庫結構

需要先為「會議記錄」的資料庫增加欄位,用來追蹤每一次處理的狀態與結果。

1-1 更新與新增欄位

進入「會議記錄」資料庫,新增以下欄位,若已有則不用

  1. 摘要狀態
    • 屬性:狀態 (Status)
    • 選項:待處理、錯誤、處理中、已完成
    • 用途:即時反應每次會議摘要處理的當前階段。
  2. 錯誤訊息
    • 屬性:文字 (Text)
    • 用途:當處理失敗時,用來儲存詳細的錯誤資訊。

Step 2:重構主流程,提前建立 Notion 頁面

因為要在流程的一開始就追蹤狀態,因此我們需要調整 n8n 工作流的順序,概念想法是先建立空的記錄,後更新完整內容。

2-1 在 Webhook 後新增「建立初始會議記錄」節點

  1. 在「Webhook」節點後方,新增一個 Notion 節點。
  2. Display Name: 建立初始會議記錄
  3. Action: Create a Database Page
  4. Database: 會議記錄
  5. Title: AI會議摘要 {{ new Date().toLocaleDateString('zh-TW') }}
  6. 在 Properties 中,設定以下欄位
    • Key Name or ID: Session ID
      • Text: {{ $('Webhook').item.json.body.session_id }}
    • Key Name or ID: 摘要狀態
      • Status: 摘要生成中

2-2 新增 Edit Fields 節點,保存 Page ID

為了讓後續的節點(包括錯誤流程)知道要更新哪一筆「會議記錄」,我們需要將剛剛建立的 Page ID 保存下來。

  1. 在「建立初始會議記錄」節點後方,新增一個 Edit Fields 節點
  2. Display Name: 保存 Page ID
  3. Mode:Manual Mapping
  4. Fields to Set:
    • name:pageID
    • value:{{ $('建立初始會議記錄').first().json.id }}

這樣設定之後,這個 「Edit Fields」 節點就會將 Notion Page ID 成功地加入到工作流的資料中,方便後續所有節點取用。

2-3 修改原有的「寫入會議紀錄」節點

我們在流程開始時建立了初始記錄,現在需要在流程的尾端,將 AI 處理好的完整資料更新回剛剛建立的初始記錄欄位裡。

由於 If 節點會讓資料流產生分岔,我們需要分別處理 True 和 False 兩條路徑。

處理 True 分支 (成功匹配到專案)

當成功匹配到專案時,已經經過了許多的節點,因此會導致「專案查詢」的輸出結果,會沒有我們之前保存的 pageID。

為了解決這個問題,我們需要使用 Merge 節點,將「專案查詢」的結果和我們需要的 pageID 重新合併在一起。

  1. 新增 「Merge」 節點

    • 在「專案查詢」和「寫入會議紀錄」之間,新增一個 Merge 節點。
  2. 設定 「Merge」 節點連線

    • 將「專案查詢」的輸出端,連接到 Merge 節點的 Input 1。
    • 這是關鍵步驟,要從前面的「保存 Page ID 與初始資料」節點,另外拉一條輸出線,連接到 Merge 節點的 Input 2。
  3. 設定 「Merge」 節點參數
    點開 「Merge」 節點的設定

    • Mode: Combine
    • Combine By: Position
      Merge Settings
  4. 修改「寫入會議紀錄」節點
    將此節點連接到 Merge 節點之後,將 Operation 從 Create 改為 Update

    • By ID: {{ $json.pageID }} (現在可以從 Merge 節點的合併結果中取到值了!)
    • 在 Properties 區域,點擊 Add Property,更新或新增以下所有欄位
      • 會議日期:{{ DateTime.now().toISODate() }}
      • 摘要狀態:已完成
      • 會議摘要:{{ $('AI 摘要與任務提取').first().json.meeting_info.summary }}
      • 行動任務:{{ $('AI 摘要與任務提取').first().json.meeting_info.tasks }}
      • 會議類型:{{ $('AI 摘要與任務提取').item.json.meeting_info.meeting_type }}
      • Session ID:{{ $('AI 摘要與任務提取').item.json.session_id }}
      • GIGI 工作室專案庫: {{ $('專案查詢').first().json.id }}

💡 n8n 偵錯技巧:解決「無法新增屬性」問題

在設定 Update 節點時,可能會遇到編輯器無法載入屬性列表(No execution data available)的問題。這是因為編輯器需要一個「範本 ID」來讀取資料庫結構。

可以使用「先寫死,再改活」的方式來解決

  • 1. 先取得真實 Page ID
    1. 先完整跑一次工作流
    2. 再到工作流上方的 Executions
    3. 找到剛剛錯誤工作流裡面的 「Merge」節點
    4. 複製 pageID
  • 2. 使用真實 Page ID 載入屬性
    1. 回到工作流上方的 Editor 的「寫入會議紀錄」節點
    2. 在 By ID 欄位,暫時貼上剛剛複製的真實 ID
    3. 此時下方的 Properties 區域就可以正常設定了!
  • 3. 設定所有屬性
    在 Properties 區域,點擊 Add Property,更新或新增以下所有欄位:
    • 會議日期:{{ DateTime.now().toISODate() }}
    • 摘要狀態:已完成
    • 會議摘要:{{ $('AI 摘要與任務提取').first().json.meeting_info.summary }}
    • 行動任務:{{ $('AI 摘要與任務提取').first().json.meeting_info.tasks }}
    • 會議類型:{{ $('AI 摘要與任務提取').item.json.meeting_info.meeting_type }}
    • Session ID:{{ $('AI 摘要與任務提取').item.json.session_id }}
    • GIGI 工作室專案庫: {{ $('專案查詢').first().json.id }}
  • 4. 將 ID 改回動態表達式:
    設定完所有屬性後,務必回到 By ID 欄位,將寫死的 ID 重新改回動態表達式 {{ $json.pageID }}。

透過這樣的技巧節點就能在執行時動態接收正確的 pageID 了。

處理 False 分支 (未匹配到專案)

如同我剛剛所說的,流程已經經過了許多的節點,因此也會沒有我們之前保存的 pageID,所以我們要

  1. 複製剛剛修改好的「寫入會議紀錄」節點,並且重新命名為「寫入會議紀錄(無關聯)」
  2. 刪除「GIGI 工作室專案庫」這個關聯屬性
  3. 複製剛剛設定好的「Merge」節點
  4. 「Mergee」節點連線
    • 將「If」的 false 輸出端,連接到 Mergee 節點的 Input 1。
    • 從前面的「保存 Page ID 與初始資料」節點,另外拉一條輸出線,連接到 Mergee 節點的 Input 2。
  5. 將「Mergee」節點的輸出連接到「寫入會議紀錄(無關聯)」的輸入

M2A Agent WorkFlow

完成以上的修改後,工作流就能根據 AI 的判斷結果,準確地更新對應 Notion 頁面的內容與狀態了!


Step 3:建立統一的錯誤處理工作流

現在要建立一個專門處理失敗情境的獨立工作流。

3-1 建立新工作流與 Error Trigger 節點

  1. 在 n8n 主畫面,點擊 Create workflow 建立一個全新的工作流
  2. 新增「Error Trigger」節點,這個節點就是錯誤工作流的入口
  3. 儲存這個工作流,並命名為 M2A Agent Error Handler

3-2 連結主工作流與錯誤工作流

  1. 回到我們主要的 M2A Agent 工作流
  2. 點擊右上角三個點,打開選單後再點擊進入 Settings 打開工作流設定
  3. 在 Error Workflow 的下拉選單中,選擇我們剛剛建立的 M2A Agent Error Handler
  4. 儲存設定

只要 M2A Agent 工作流中任何一個節點(Webhook 除外)執行失敗,n8n 就會自動觸發 M2A Agent Error Handler 工作流,並把錯誤相關的資料傳遞過去。


Step 4:錯誤處理的流程

回到 M2A Agent Error Handler 工作流,來實作錯誤發生時的具體動作。

4-1 Code 節點:格式化錯誤資訊

Error Trigger 傳來的資料結構比較複雜,我們先用一個 Code 節點把它整理成方便使用的格式。

  1. 在 Error Trigger 後新增一個 Code 節點。
  2. Display Name: 格式化錯誤資訊
  3. JavaScript:
const execution = $input.item.json.execution;
const error = $input.item.json.error;

const formattedError = {
  sessionId: `errorID_${execution?.id || 'unknown'}`,
  workflowName: $input.item.json.workflow?.name || execution?.workflow?.name || '未知工作流',
  nodeName: execution?.error?.node?.name || '未知節點',
  errorMessage: execution?.error?.message || '未知錯誤',
  notionUrl: `http://localhost:5678/workflow/Q2Kd8E56GkaFWscI/executions/${execution?.id || 'unknown'}`,
  errorType: execution?.error?.level || 'Unknown',
  timestamp: new Date().toISOString(),
  executionId: execution?.id || 'unknown-execution'
};

return [formattedError];

4-2 Notion 節點:建立錯誤記錄

在 Notion 中建立一筆詳細的錯誤記錄,方便日後追蹤和分析。

  1. 在 「Code」 節點後,新增一個 「Notion」 節點
  2. Display Name:: 建立錯誤訊息
  3. 基本設定:
    • Credential: M2A Agent Notion Credential
    • Resource: Database Page
    • Operation: Create
    • Database: 會議記錄
  4. 標題設定:
❌ {{ $json.workflowName }} 執行錯誤-ID#{{ $json.executionId }}
  1. 屬性設定:點擊 Add Property
    • 摘要狀態: 錯誤
    • Session ID: {{ $json.sessionId }}
    • 錯誤訊息:
    🚨 工作流執行失敗
    
    **失敗節點**: {{ $json.nodeName }}
    **錯誤類型**: {{ $json.errorType }}
    **錯誤訊息**: {{ $json.errorMessage }}
    **執行時間**: {{ $json.timestamp }}
    
    **執行記錄連結**: {{ $json.notionUrl }}
    

4-3 HTTP Request 節點:發送 LINE 通知

複製主流程中的 LINE 通知節點,並貼到此處,確保 JSON 的值設定為

{
  "messages": [
    {
      "type": "text",
      "text": "🚨 M2A Agent 處理失敗通知 🚨\n\n錯誤記錄: {{ $json.name }}\n\n查看詳情: {{ $json.url }}"
    }
  ]
}

Step 5:端到端錯誤流程驗證

現在來實際測試一下結果,需要手動製造一個錯誤。

5-1 模擬錯誤情境

  1. 回到主工作流 M2A Agent
  2. 製造一個想模擬的錯誤情況

5-2 執行測試

  1. 一樣打開 Gradio 前端介面
  2. 上傳音訊檔,輸入指令,點擊「開始處理」
  3. 這次 Gradio 介面「會議摘要」與「行動提取」都會失敗,因為我們的工作流之中有錯誤

5-3 驗證結果

  • LINE 通知: 會收到一則錯誤通知
  • Notion 頁面: 檢查「會議記錄」資料庫,會發現一筆新的記錄,其「摘要狀態」為「錯誤」,且「錯誤訊息」欄位寫滿了詳細的錯誤原因。
  • n8n 後台: 檢查 M2A Agent 工作流的 Executions,會看到一筆失敗的記錄。再檢查 M2A Agent Error Handler 的 Executions,會看到一筆成功的記錄。

5-4 復原

測試完成後,請務必記得要復原。


今天的成果總結

✅ 完成項目

  • 在 Notion 中建立了狀態追蹤機制 (待處理、錯誤、處理中、已完成)
  • 重構了主工作流,實現了「先建立,後更新」的模式
  • 利用 Error Trigger 建立了可重複使用的集中式錯誤處理工作流
  • 實現了失敗時建立新的錯誤欄位並記錄詳細錯誤資訊
  • LINE 錯誤告警,實現了故障發現能力

心得

今天透過建立獨立的錯誤處理工作流,將「成功路徑」與「失敗路徑」分離,實現了軟體工程中一個非常重要的概念,我的主工作流簡潔,只專注於核心業務,而所有的異常處理邏輯則被集中管理,不僅提高了可靠性,也讓未來的維護和擴充變得更加容易。

🎯 明天計劃
從會議對話中自動辨識「參與夥伴」,並與 Notion 使用者資料庫進行匹配,實現會議記錄的智慧標記與歸檔。


上一篇
Day 11 智慧會議辨識類型與專案關聯
下一篇
Day 13 Prompt 架構升級 — 智慧日期解析與模組化設計
系列文
打造基於 MCP 協議與 n8n 工作流的會議處理 Agent 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言