Eric TechBlog
AIAI Assistant

External Integration

外部服務整合,包含 MCP 協議選型、工具正規化 pipeline、App 選擇機制,以及整合的完整流程設計。

設計問題

AI 助理光靠對話和搜尋是不夠的。用戶會說:

  • 「幫我看一下 John 信裡提到的 deadline 那天有沒有會議」
  • 「根據這封 email 建一個任務提醒我下週交報告」
  • 「把這個時間加到我的行事曆」

這意味著你需要整合 Google Calendar、Google Tasks、Slack、Notion 等等。每個服務都有自己的 API、認證方式、資料格式。

核心問題:如何設計一個可擴展的外部服務整合架構,讓新增服務盡可能簡單,同時處理好現實世界 API 的各種怪癖?


方案比較

為每個服務寫專門的整合程式碼:

Google Calendar SDK → 自定義工具
Google Tasks API   → 自定義工具
Slack API          → 自定義工具
  • 優點:完全控制、可以精確優化每個工具
  • 缺點:每個服務都要寫認證、錯誤處理、工具定義。新增服務 = 新的開發工作

透過標準化協議連接外部服務:

你的應用 ←MCP→ MCP Server ←→ Google Calendar
                            ←→ Google Tasks
                            ←→ Slack
  • 優點:標準協議、工具動態發現、一次整合多個服務
  • 缺點:多一層間接、可能不如直接整合精確、依賴 MCP Server 的品質

核心服務(如 email)直接整合以獲得最佳控制,其他服務透過 MCP。

選擇:MCP + 必要的直接整合

MCP 處理大部分外部服務,但保留直接整合的能力用於需要精確控制的場景(如 email 的混合搜尋)。

這篇與 Retrieval Pipeline 的分工

Email 搜尋通常是 AI Assistant 的核心能力,所以常需要 自訂檢索 pipeline 來做到 snippet、全文抓取與重排。Calendar、Tasks、Slack 這類外部服務則更適合透過 MCP 接入。


MCP 的工作原理

連線

MCP 使用 HTTP 或 stdio 作為傳輸層。在 Web 應用中,HTTP 是自然的選擇:

建立連線 → 查詢可用工具 → 轉為 AI SDK 的 ToolSet

動態發現

MCP 的殺手功能是工具動態發現。你不需要預先知道 MCP Server 有哪些工具,連線後直接查詢即可:

連線 MCP Server
  → "你有什麼工具?"
  → [
      findCalendarEvents(start, end, ...),
      createCalendarEvent(title, date, ...),
      listTasks(...),
      completeTask(taskId),
      ...
    ]

這意味著:

  • 新增工具只需要在 MCP Server 端配置,不需要修改你的程式碼
  • 工具的 schema(名稱、描述、參數)由 MCP Server 定義,你的系統自動適配

優雅降級

MCP Server 可能不可用(沒設定 URL、Server 當掉)。系統必須在沒有外部服務的情況下正常運作:

if (!mcpUrl) {
  console.warn("MCP unavailable")
  return {}  ← 返回空的工具集,系統繼續運作
}

沒有外部服務時,AI 助理仍然可以對話、搜尋 email、管理記憶。只是無法操作行事曆和任務。


工具正規化

問題

MCP Server 返回的工具可能有各種問題:

  1. 不需要的工具:MCP Server 可能附帶管理工具(如 add_toolsedit_tools),這些不應該暴露給 Agent
  2. 命名不直覺google_calendar_find_eventsfindCalendarEvents 更難讓 LLM 理解
  3. API 設計怪癖:某些 API 的參數命名與直覺相反

解法:正規化 pipeline

API 適配器的實際案例

某些 Calendar API 的參數命名是反的(真實案例)

API 定義:
  start_time = 時間範圍的「結束」
  end_time   = 時間範圍的「開始」

如果直接暴露給 Agent,它會把 start 傳給 start_time(因為這是人類的直覺),得到完全相反的結果。

適配器的做法:

包裝工具:
  輸入:start(自然語言)、end(自然語言)
  內部:start → 傳給 API 的 end_time
        end   → 傳給 API 的 start_time

Agent 使用自然語言的 start/end,適配器在背後處理反轉。

為什麼不改 MCP Server?

因為 MCP Server 可能是第三方提供的(如 Zapier),你無法控制它的 API 設計。適配器是在「你的系統」和「外部系統」之間建立一個翻譯層。


App 選擇機制

問題

Agent 有了 Calendar、Tasks 等工具後,即使用戶只是在閒聊,Agent 有時也會不必要地嘗試使用這些工具。更多的工具 = 更多的 token 消耗(工具定義本身佔 token)+ 更高的誤用風險。

解法:用戶選擇啟用哪些 App

前端提供 App 切換按鈕:

輸入框旁邊:
[📅 Calendar] [✅ Tasks]     ← 可切換開/關

用戶選擇的 App 作為 metadata 附在訊息中:

用戶訊息:
  text: "明天有什麼會議?"
  metadata: [app-tag: "calendar"]

後端根據 metadata 篩選工具:

所有 MCP 工具 → 只保留 Calendar 相關的 → 傳給 Agent

篩選邏輯

每個 App 定義了它「擁有」哪些工具:

Calendar:
  前綴匹配: google_calendar_*
  精確匹配: findCalendarEvents

Tasks:
  前綴匹配: google_tasks_*

新的 MCP 工具只要遵循命名慣例(google_calendar_ 前綴),就自動歸入 Calendar App。

System Prompt 的動態適配

如果用戶沒選 Calendar App,Agent 的 system prompt 會調整:

沒選 Calendar 時:
"Calendar integrations are not configured in this environment.
 If the user asks about them, explain that the integration
 is unavailable."

選了 Calendar 時:
正常的行事曆使用指引

這避免了 Agent 嘗試使用不存在的工具,或對用戶撒謊說「我可以查你的行事曆」。


整合的完整流程

注意

執行已批准的工具時,使用的是原始工具(不是 HITL 包裝版),因為用戶已經批准了。


生產考量

認證管理

MCP Server 的認證通常透過 URL 中的 token 或 header。在多用戶環境中:

  • 每個用戶需要自己的 MCP Server 連線(各自的認證)
  • 認證 token 需要安全儲存(不能存在前端)
  • Token 刷新機制

連線池

每次請求都建立新的 MCP 連線是浪費的。生產環境應該:

  • 複用連線(連線池)
  • 設定連線超時
  • 健康檢查

工具變更

MCP Server 的工具可能隨時變更(新增、移除、修改 schema)。你的系統需要能動態適應。

好消息:因為是動態發現的,不需要修改程式碼。但需要注意:

  • System prompt 中硬編碼的工具名稱可能失效
  • HITL 的例外列表可能需要更新
  • App 定義中的前綴可能需要調整

降級策略

情況處理方式
MCP URL 未設定不載入 MCP 工具,系統正常運作
MCP Server 連線失敗log 錯誤,返回空工具集
工具執行失敗錯誤回傳給 Agent,讓它決定下一步
認證過期提示用戶重新認證

重點總結

設計決策選擇原因
整合方式MCP + 直接整合MCP 處理大部分,直接整合用於精確控制
工具發現動態查詢新增工具無需改程式碼
降級策略返回空工具集沒有外部服務系統照常運作
正規化過濾 + 重命名 + 適配處理第三方 API 的各種怪癖
App 選擇用戶切換 + 工具篩選減少誤用風險和 token 浪費
動態 prompt根據可用工具調整避免 Agent 使用不存在的工具

Last updated on

On this page