> ## Documentation Index
> Fetch the complete documentation index at: https://data-machi.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Day 26｜AI 一定會失敗：逾時（Timeout）、重試（Retry）、備援（Fallback）怎麼設計？

> 從模型逾時、限流與服務中斷出發，建立逾時（Timeout）、重試（Retry）、備援（Fallback）、答案驗證與可行動錯誤訊息。

到了 Day 26，Data Machi 的核心能力其實已經很完整：可以查文件、算數字、選工具、保留狀態，也能用 LangGraph 管理 Workflow。但如果把這個版本直接丟到正式環境，很快會遇到另一個現實：**外部服務一定會失敗。**

模型可能 timeout，API 可能遇到 429 rate limit，服務可能回 503，網路也可能暫時中斷。企業產品不能把這些狀況當成例外，而應該把它們視為設計的一部分。

```mermaid theme={null}
flowchart TD
    R["外部服務呼叫失敗"] --> C{"錯誤是否可能暫時恢復？"}
    C -->|"Timeout、429、部分 5xx"| T["Retry<br/>指數退避＋次數上限"]
    C -->|"認證、權限或輸入錯誤"| E["停止並回傳可行動錯誤"]
    T --> S{"重試成功？"}
    S -->|"是"| V["Verification<br/>確認結果可用"]
    S -->|"否"| F["Fallback<br/>切換備援模型或替代來源"]
    F --> Z{"仍能可靠完成？"}
    Z -->|"是"| V
    Z -->|"否"| E
```

<p align="center">
  *圖 1｜可靠性不是無限重試，而是依錯誤類型選擇 Retry、Fallback 或停止*
</p>

## 逾時（Timeout）：不要讓整個工作流程永遠卡住

每個外部工具呼叫（Tool Call）都應該有合理的等待上限。如果模型或 API 超過時間仍沒有回應，系統應該主動結束這一次呼叫，記錄錯誤，再決定下一步。

沒有 Timeout 的最大問題不是「使用者多等一下」，而是整條 Workflow 可能一直佔用資源，前端也不知道到底還在處理還是已經壞掉。

## Retry：只重試值得重試的錯誤

不是所有錯誤都適合 Retry。像暫時性網路問題、429 或部分 5xx 錯誤，可以搭配 exponential backoff 重試；但如果是憑證錯誤、權限不足或輸入格式錯誤，重試十次也不會變好。

因此 Retry policy 應該先分類錯誤，再決定重試次數與等待時間。這比寫一個無條件 `try again` 更可靠。

```text theme={null}
429 / temporary 5xx → retry with backoff
401 / 403 → stop, check credential or permission
bad input → stop, return actionable error
```

## Fallback：主要服務不可用時，還有沒有下一條路？

對語言模型可以準備 fallback model；對某些資料來源，也可以在主來源暫時不可用時回傳最近一次可信快取，前提是明確標示資料時間。Fallback 的目的是維持服務可用性，不是偷偷用比較舊或不同的資料假裝一切正常。

如果沒有可靠 fallback，最好的做法就是清楚告知目前哪一段無法完成，而不是讓模型自行補答案。

實作時可以把這四個機制放進同一張對照表，避免彼此的責任混在一起：

| 機制           | 解決什麼問題          |
| ------------ | --------------- |
| Timeout      | 限制單次等待時間        |
| Retry        | 暫時性失敗時重新嘗試      |
| Fallback     | 主模型不可用時切換替代模型   |
| Verification | 檢查回答是否符合工具結果與來源 |

驗證時可以刻意製造失敗情境：故意填錯 API Key，確認會收到認證錯誤而不是無限轉圈；模擬 Timeout，確認前端的 Loading 真的能結束；讓主要模型持續失敗，確認系統會切換到備援模型，並讓使用者知道目前用的是備援服務；最後檢查後端 Log——它應該保留足夠分類資訊方便除錯，但不能記錄完整 Prompt、API Key 或使用者敏感資料。

## Verification 也屬於可靠性

可靠性不只是服務「有沒有回」。即使 Tool 成功回傳，也可能回空結果、欄位變動或不完整資料。因此在 Workflow 中保留 Verification Node 很重要：檢查結果是否可用、來源是否存在，以及回答是否超出工具證據。

這裡可以把 Day 22 的原則放進正式產品：資料不足就補查，問題不清楚就 clarification，來源失敗就回報狀態，而不是一律進最終生成。

## 錯誤訊息要讓使用者知道下一步

「Something went wrong」對使用者幾乎沒有幫助。比較好的錯誤訊息會區分：資料來源目前無法連線、權限不足、模型暫時忙碌、查不到符合條件的資料，或輸入需要補充。

例如「目前無法讀取 Google Sheets，文件查詢仍可使用」就比整頁跳錯誤更有價值，因為使用者知道哪些功能還能繼續。

## 在 Data Machi 中放在哪裡？

可靠性最好不要只散落在每個 Tool 裡。Tool 自己負責基本 Timeout 與 API error handling，Workflow 層則負責 Retry、Fallback、Verification 與使用者可見狀態。這樣每一層責任比較清楚。

## 進階理解｜不同任務，不一定用同一種可靠性策略

模型呼叫可以依任務性質分成兩條路徑。像「判斷要不要查資料」「確認問題類型」這類快速任務，可以使用較快的模型、較短 timeout；長篇摘要或最終回答則可以允許較長時間，失敗後再考慮 Retry 或 Fallback。換句話說，可靠性不是設定一個全系統共用的 30 秒，而是根據任務重要性與使用者等待成本調整。

另外還要注意一種常被忽略的失敗：**輸出被截斷**。服務有回應，不代表內容完整；如果要求固定 JSON 或長篇報告，仍需要檢查格式是否完整，再決定是否重試。

<Accordion title="延伸閱讀：什麼是 Circuit Breaker？">
  如果某個服務已經連續失敗很多次，與其每一位使用者都重新等待 Retry，不如暫時停止把請求送到它，改走備援路徑，等健康檢查恢復後再重新開放。這就像電路跳閘：不是一直嘗試通電，而是先保護整個系統。對高流量服務來說，這能避免故障擴大。
</Accordion>

<Info>
  今天只要記住一件事：正式環境的可靠性，不是期待 AI 永遠成功，而是預先設計「失敗時系統要怎麼繼續」。
</Info>

下一篇我們會從後端可靠性轉到前端體驗：當代理（Agent）需要十幾秒甚至更久完成多步驟任務時，使用者到底應該看到什麼？
