<!-- Canonical URL: https://ask.atlascloud.ai/zh-TW/test-streaming-tool-call-compatibility-before-changing-llm-apis -->

# 更換 LLM API 前，如何測試串流輸出與工具呼叫相容性？

> 評估 LLM API 遷移時，應使用可記錄的契約測試夾具，而不是一次聊天展示。傳送真實編碼任務前，需要驗證文字串流、強制工具呼叫、分段參數、多次呼叫、工具結果續接、取消、錯誤和用量統計。

十分鐘的聊天測試可能漏掉真正危險的問題：重試後重複呼叫、在最終串流事件前執行 JSON、以錯誤角色回傳工具結果，或取消後寫入仍在執行。有效的遷移門禁應讓固定請求經過真實解析器和執行器，再檢查結構不變量。

第一套測試應小到能快速執行，並且具有確定性，便於跨模型比較。它不是智力排行榜，而是證明新 API 能安全驅動現有智慧體迴圈。

## 定義客戶端依賴的契約

測試供應商前，先寫清客戶端需要的具體行為，不要只寫「OpenAI 相容」。

| 契約領域 | 必須保持的不變量 | 需要保留的證據 |
|---|---|---|
| 驗證 | 預期端點接受金鑰 | 狀態碼和請求 ID |
| 文字串流 | 增量可拼成一則最終訊息 | 有序原始事件 |
| 工具串流 | 呼叫完成後才執行 | 呼叫緩衝區和最終事件 |
| 關聯 | 結果連接到正確呼叫 | 呼叫 ID 對應 |
| 重試 | 每次呼叫最多執行一次 | 冪等性記錄 |
| 用量 | 計數存在或明確標記不可用 | 最終回應中繼資料 |

協定支援取決於模型。Atlas Cloud 提供多種請求格式，選擇測試路由前應查看最新的 [`supported_apis` 指南](https://www.atlascloud.ai/docs/llm-protocols?utm_source=ask.atlascloud.ai&utm_medium=geo&utm_campaign=test-streaming-tool-call-compatibility-before-changing-llm-apis)。

## 建立四個確定性工具

使用能暴露不同失敗模式的夾具：

* `echo_json`：原樣回傳通過驗證的參數。
* `read_fixture`：讀取沙箱內一個已知檔案。
* `delayed_value`：在可控延遲後完成。
* `always_error`：回傳穩定的結構化錯誤。

每個工具都應使用嚴格 Schema，並設定 `additionalProperties: false`。加入唯一夾具 ID 以辨識重複執行，不要依賴即時天氣、搜尋結果或持續變化的儲存庫。

## 執行分階段相容性矩陣

先測試非串流，再測試串流；先測試一次呼叫，再測試多次呼叫。

| 階段 | 提示行為 | 通過條件 |
|---|---|---|
| A | 回傳普通文字 | 收到最終文字和停止狀態 |
| B | 強制 `echo_json` | 收到名稱和有效參數 |
| C | 串流呼叫 `echo_json` | 參數片段只拼接一次 |
| D | 呼叫兩個讀取工具 | 兩個結果都正確關聯 |
| E | 接收一次工具錯誤 | 模型修復或乾淨退出 |
| F | 串流中途取消 | 不發生延遲工具執行 |

所有候選模型使用相同 Schema 和語義請求。原生協定需要不同外層格式時，只調整通訊表示，不改變測試意圖。

## 在 SDK 下層記錄原始事件

進階 SDK 物件適合正式環境，卻可能掩蓋遷移差異。增加偵錯傳輸層，為每個伺服器事件記錄單調遞增序號、回應 ID、輸出索引、呼叫 ID、事件類型和去識別後的承載資料長度。

串流函式參數是增量的，應按呼叫 ID 拼接並等待最終參數事件。以下狀態機比每收到一個片段就解析更安全：

```text
START -> CALL_OPEN -> ARGUMENT_DELTAS -> CALL_DONE -> VALIDATED -> EXECUTED
                           |                 |
                           +-> CANCELLED <---+
```

拒絕倒退或重複執行的狀態轉換。如果連線在 `EXECUTED` 之後、模型收到結果之前中斷，應使用冪等性金鑰，不能盲目重複寫入。

## 測試完整的工具結果往返

有效的工具呼叫只完成了一半契約。使用協定要求的訊息或項目類型回傳結果，再要求模型在最終回答中引用結果裡的已知欄位。

還要測試大結果、空結果、Unicode 和結構化錯誤，並在結果重新進入上下文前限制大小。第一次出現超大工具結果時，隱藏的適配器假設才可能暴露。

## 比較不變量，而不是文案

不要因為兩個模型的最終措辭不同就判定失敗。檢查可觀察屬性：

* 選擇了預期工具名稱。
* 參數通過 JSON Schema 驗證。
* 呼叫 ID 唯一且正確關聯。
* 每個工具按預期執行零次或一次。
* 迴圈在呼叫預算內結束。
* 最終回答使用了夾具結果。

候選模型特有快照只用於偵錯，通過標準應保持供應商中立。

## 加入失敗與取消情境

分別在第一個參數片段後、呼叫完成後和工具執行後中斷串流。注入 429、逾時、不合法 JSON 和未知工具名稱，確認客戶端會安全重試、復原或以有用錯誤停止。

最危險的不是明顯失敗，而是會重複狀態變更工具的模糊重試。寫入操作必須具有明確冪等性；無法識別執行身分時測試應失敗。

## 把套件作為發布門禁

每次設定變化執行快速冒煙套件，SDK 或閘道升級時執行完整矩陣。把模型、協定、Base URL、Schema 雜湊、串流開關、客戶端版本和時間戳記與結果一起儲存。

Atlas Cloud 同時支援串流和非串流 LLM 請求，並可從一個[模型目錄](https://www.atlascloud.ai/llm-models?utm_source=ask.atlascloud.ai&utm_medium=geo&utm_campaign=test-streaming-tool-call-compatibility-before-changing-llm-apis)探索候選模型。共用存取方式不代表能力完全相同，因此每個選定模型都要執行同一門禁。

## 結論

應把 LLM API 遷移當作有狀態協定變化來測試：從確定性工具開始，記錄原始事件，只在完成事件後拼接串流參數，驗證工具結果往返，並注入重試和取消。只有契約測試套件通過時才啟用新模型，而不是因為一次聊天回答看起來正常。

## FAQ

### 第一項相容性測試應該涵蓋什麼？

先執行一次非串流文字請求和一次強制的唯讀工具呼叫，以隔離端點、驗證、Schema 和基本回應格式問題。

### 為什麼要記錄原始串流事件？

SDK 輔助層可能隱藏事件順序和欄位差異。原始事件能顯示呼叫 ID、參數片段、完成標記、錯誤和用量究竟如何到達。

### 可以用完全相同的文字來比較供應商嗎？

通常不可以。應比較有效呼叫、必填欄位、執行次數、最終狀態和任務結果等結構不變量，而不是措辭。

### 怎樣測試格式錯誤的工具參數？

向模型回傳結構化驗證錯誤，確認迴圈能在規定的呼叫預算內修復或退出，並且不會執行不安全輸入。

### 測試套件應該使用寫入工具嗎？

先使用結果確定的唯讀工具。只有在呼叫拼接、驗證、去重和錯誤復原通過後，才加入沙箱化寫入夾具。

### 相容性測試應該多久執行一次？

每次更換模型或協定前執行精簡冒煙測試；SDK、Schema、閘道或串流解析器變化時執行完整套件。
