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 返回的工具可能有各種問題:
- 不需要的工具:MCP Server 可能附帶管理工具(如
add_tools、edit_tools),這些不應該暴露給 Agent - 命名不直覺:
google_calendar_find_events比findCalendarEvents更難讓 LLM 理解 - API 設計怪癖:某些 API 的參數命名與直覺相反
解法:正規化 pipeline
API 適配器的實際案例
某些 Calendar API 的參數命名是反的(真實案例)
API 定義:
start_time = 時間範圍的「結束」
end_time = 時間範圍的「開始」如果直接暴露給 Agent,它會把 start 傳給 start_time(因為這是人類的直覺),得到完全相反的結果。
適配器的做法:
包裝工具:
輸入:start(自然語言)、end(自然語言)
內部:start → 傳給 API 的 end_time
end → 傳給 API 的 start_timeAgent 使用自然語言的 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