iT邦幫忙

2025 iThome 鐵人賽

DAY 16
0

昨天我在單一「AI 摘要與任務提取」節點中建立了複雜的分析流水線,雖然功能變得更強大了,但也因此已經變成一個難以維護的「巨石應用」節點...

雖然能穩定運作,但所有邏輯都集中在單一節點中,導致會議摘要品質下降、任務指派不夠準確、期限邏輯還需要強化,而且參與夥伴目前是直接將人員資料庫的所有成員都設為參與者,這些問題都讓我意識到需要進行根本性的架構調整。

因此今天的目標是將單一 AI 呼叫的節點拆分為三個獨立、串連的節點,分別為會議屬性提取獲取參與者提取結構化任務,並為每個節點設計目標單一的 Prompt,讓整個工作流有了穩定性與可維護性。

今天的目標與挑戰

  • 重構 n8n 工作流程,建立清晰的 AI 任務鏈
  • 將複雜的「AI 摘要與任務提取」節點拆分為三個獨立的 AI 節點
  • 為每個節點設計專一目標的 Prompt,提升 AI 回應品質
  • 改善會議摘要準確度和任務指派等邏輯
  • 強化期限處理機制,支援不同期限的任務

Step 1:分析原有架構並設計新的任務鏈

1-1 原有架構問題

現在的「AI 摘要與任務提取」節點同時處理了以下功能

  • 會議基本資訊提取:專案名稱、會議類型、摘要
  • 參與者辨識:從逐字稿中識別與會人員
  • 任務分析:結構化任務提取與智慧分配
  • 日期解析:時間表達式轉換為標準日期

1-2 設計新的任務鏈架構

我的設計思路是將複雜的處理流程拆分為三個專門的 AI 專家

  1. 「會議摘要與資訊提取」:專門負責專案判斷、會議類型、基礎摘要
  2. 「獲取參與者」:專門負責從逐字稿中辨識參與人員
  3. 「提取結構化任務」:專門負責任務分析、分配與整合

每個節點都有單一明確的職責,降低複雜度並提升可維護性。


Step 2:建立第一個節點 — 「會議摘要與資訊提取」

這個節點專門負責會議的基本資訊提取。

2-1 建立節點

  1. 在「格式化成員列表」節點後方新增一個「Code」節點
  2. 將節點重新命名為「會議摘要與資訊提取」

2-2 設計專用的「會議摘要與資訊提取」 Prompt

這個 Prompt 專注於會議的基本資訊提取,不處理複雜的任務分析

// 建立會議摘要與資訊提取的 Prompt
function buildMeetingAttributePrompt(projectList) {
  const projectListFormatted = Array.isArray(projectList) ? projectList.join('\n- ') : projectList;
  return `你是專業的會議屬性分析專家,專門負責從會議逐字稿中提取基本會議資訊。

【已知專案清單】
- ${projectListFormatted}

【你的唯一任務】
1. 判斷會議主要討論的專案(從清單中選擇,若無則回傳 null)。
2. 判斷會議類型(從 7 種固定類型中選擇)。
3. 生成一段簡潔的純文字會議摘要。

【會議類型限制 - 必須從以下選擇】
專案討論、技術討論、需求分析、進度報告、創意發想、決策會議、一般會議

【摘要撰寫要求】
summary 必須是**純文字段落摘要**,符合以下規則:
- 只使用自然的句子和段落,不要使用任何 Markdown 格式(如 #, -, *)。
- 不要包含「專案名稱:」、「會議類型:」等標籤。
- 重點描述會議的核心討論內容和主要決議。
- 長度控制在 100-200 字之間。

【輸出格式要求】
嚴格按照以下 JSON 格式,不可包含任何其他內容:
{
  "project_name": "專案名稱或null",
  "meeting_type": "會議類型",
  "summary": "簡潔的純文字摘要"
}`;
}

2-3 呼叫 AI 並處理回應

在節點的程式碼中設定較低的溫度 temperature: 0.1 來確保輸出穩定。同時我還加入了錯誤處理機制,如果 AI 分析失敗,會回傳一個預設的 JSON 物件,避免工作流中斷。


Step 3:建立第二個節點 — 「獲取參與者」

這個節點專門負責從會議逐字稿中識別參與人員。

3-1 建立節點

  1. 在「會議摘要與資訊提取」節點後方新增一個「Code」節點
  2. 將節點重新命名為「獲取參與者」
  3. 連接從「會議摘要與資訊提取」節點的輸出

3-2 設計專用的「參與者辨識」 Prompt

這個 Prompt 的核心在於「證據導向」,AI 必須在逐字稿中找到明確的證據才能將某人列為參與者。

// 建立參與者辨識的 Prompt
function buildParticipantIdentificationPrompt(memberList) {
  const memberListFormatted = Array.isArray(memberList) ? memberList.join('\n- ') : memberList;
  return `你是專業的參與者識別專家,專門從會議逐字稿中準確識別參與成員。

【已知成員清單】
- ${memberListFormatted}

【識別策略】
1. **直接發言標記**:「XX說」、「XX表示」、「XX提到」。
2. **角色稱呼**:對話中提到的職位、暱稱或簡稱。
3. **工作指派**:被分配任務的成員。

【重要原則】
- 只有在逐字稿中有明確證據的成員才能被識別為參與者。
- 不要因為「各位」、「大家」就自動包含所有成員。
- 謹慎處理暱稱和簡稱,確保映射正確。

【輸出格式】
{
  "participants": ["實際參與者姓名列表"],
  "evidence": ["用於判斷的證據句子列表"]
}`;
}

3-3 將參與者名字對應到 Notion User ID

在 AI 回傳參與者姓名後,透過輔助函式 matchParticipantsToNotionIds來遍歷 AI 回傳的 participants 陣列,並在「格式化成員列表」提供的成員資料中進行查找,比對姓名和所有暱稱,最後回傳一個包含 Notion User ID 的陣列。


Step 4:建立第三個節點 — 「提取結構化任務」

這是任務鏈中最複雜的節點,負責任務分析、分配與整合。

4-1 建立節點

  1. 在「獲取參與者」節點後方新增一個「Code」節點
  2. 將節點重新命名為「提取結構化任務」
  3. 連接從「會議摘要與資訊提取」節點的輸出

4-2 設計結構化任務提取邏輯

這個 Prompt 的任務是從會議內容中辨識出具體的行動項目,並且將其結構化。

// 建立任務提取的 Prompt
function buildTaskExtractionPrompt(participants) {
  const participantList = participants.join('、');
  return `你是專業的任務提取專家,專門從會議內容中識別具體的行動項目和責任分配。

【會議參與者】
${participantList}

【任務識別規則】
1. **明確指派**:「XX,請你負責...」、「XX來處理...」。
2. **承諾性陳述**:「我會負責...」、「我來處理...」。
3. **帶期限的工作**:包含時間要求的具體任務。
4. **可執行行動**:有明確產出的工作項目。

【輸出格式】
{
  "tasks": [
    {
      "title": "簡潔任務標題",
      "description": "詳細任務描述",
      "assignee": "負責人姓名或null",
      "category": "任務分類",
      "priority": "高/中/低",
      "time_expression": "原始時間表達"
    }
  ]
}`;
}

4-3 整合所有資訊並進行智慧指派

最後透過 generateIntelligentSummary 函式再次呼叫 AI,但這次是作為一個「資訊整合專家」,它會接收前面所有節點的分析結果(專案、摘要、參與者、任務),並執行以下操作

  • 強化摘要:結合參與者和任務資訊,生成更完整的 Markdown 格式摘要。
  • 智能期限解析:分析任務中的時間表達(例如「三天後」、「下週一」),並計算出具體的截止日期。
  • 選擇最晚期限:從所有任務中找出最晚的截止日期,作為整個會議記錄的主要期限。
  • 格式化任務:將結構化任務轉換為美觀、易讀的格式。
  • 最終輸出:生成一個包含所有會議資訊的完整 JSON 物件。

Step 5:重構工作流程連接與相關節點

完成三個 AI 任務鏈節點後,需要調整整體的工作流程

  1. 更新「格式化成員列表」節點
  2. 更新「Merge」節點:將「寫入會議紀錄」節點所需要的資料透過「Merge」節點來做資料合併,其輸入從 2 改為 3,以接收新的資料流。
  3. 修改「If」節點:將用於判斷是否有專案關聯的「If」節點,其條件判斷表達式從 {{ $json.meeting_info.project_name }} 修改為 {{ $json.meeting_attributes.project_name }},以讀取來自新任務鏈的資料。
  4. 更新「寫入會議紀錄」節點:由於資料結構已經改變,應該更新了相關的對應欄位,確保摘要、任務、參與者、指派人員和期限都能正確寫入 Notion。
  5. 修改「Markdown 格式化處理」節點:更新了此節點的程式碼,確保它能從新的資料結構中正確提取摘要和任務清單。

Step 6:測試與驗證新的任務鏈架構

完成重構後,我進行了測試,先確保整個資料流的傳輸都沒問題。

6-1 準備測試資料

使用包含豐富資訊的會議音訊檔進行測試

  • 明確的專案討論
  • 多位參與者互動
  • 具體的任務分配
  • 時間期限描述

6-2 執行完整流程測試

  1. 開啟 Gradio 前端介面
  2. 上傳測試音訊檔案
  3. 在使用者指令中輸入:請生成會議摘要與提取行動任務
  4. 點擊「開始處理」

6-3 最終結果

Notion「會議記錄」中的資料

  • 基本會議資訊正確
  • 資料正確填入相對應欄位
  • Line 通知發送正常

今天的成果總結

完成項目

  • 成功將複雜的「巨石應用」拆分為三個專門的節點
  • 建立了「會議摘要與資訊提取」、「獲取參與者」、「提取結構化任務」三個 AI 任務鏈
  • 為每個節點設計了目標單一的專用 Prompt
  • 將 Merge 節點擴展為三輸入,整合更多資料來源
  • 重構了整體工作流程,實現模組化架構
  • 修改了相關節點的表達式和邏輯,確保資料流正常運作

心得

今天的架構重構雖然工程浩大,但結果令我非常滿意,將單一複雜的節點拆分為三個職責明確的 AI 任務鏈,就像是把一個什麼都做的通才,換成了一個各司其職的專業團隊。

每個節點現在都有了明確的職責,不僅讓 Prompt 設計更有針對性,也讓輸出的結果品質顯著提升了,讓我感到開心。

🎯 明天計劃

測試並最佳化新的任務鏈架構,進一步強化參與者的配對邏輯,並對每個任務進行獨立的期限解析,最後再針對調適過程中發現的問題進行調整。


上一篇
Day 15 強化解析架構 — 設計多工 Prompt 與指派邏輯強化
下一篇
Day 17 任務鏈精煉 — 精準配對與獨立期限解析
系列文
打造基於 MCP 協議與 n8n 工作流的會議處理 Agent17
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言