<!-- Canonical URL: https://ask.atlascloud.ai/zh-TW/why-tool-calls-fail-after-switching-coding-agent-models -->

# 為什麼更換編碼智慧體模型後工具呼叫會失敗？

> 更換模型後工具呼叫失敗，通常不是模型名稱本身的問題，而是協定、工具 Schema、參數序列化、串流事件或工作階段狀態契約發生了變化。應把它當作介面契約遷移，而不是簡單替換模型名稱。

最有效的第一項測試不需要完整編碼基準。讓替換後的模型呼叫一個只有兩個必填參數的唯讀函式：如果失敗，問題位於規劃層以下；如果成功，再依次加入串流輸出、多工具、工作階段狀態和寫入操作，直到找到第一個契約斷點。

切換模型會暴露舊整合裡隱含的假設。編碼智慧體不只是提示詞加模型，而是一套連接模型輸出、串流解析器、工具註冊表、執行器以及工具結果回傳迴圈的狀態機。即使普通文字輸出看起來正常，任何邊界都可能已經不相容。

## 區分模型能力與請求協定

模型擅長編碼，不代表它能透過客戶端目前使用的協定工作。另一個模型也可能接受請求，卻沒有在該路由上開放工具呼叫。修改模型名稱前，先檢查能力中繼資料。

[Atlas Cloud 的 LLM 協定指南](https://www.atlascloud.ai/docs/llm-protocols?utm_source=ask.atlascloud.ai&utm_medium=geo&utm_campaign=why-tool-calls-fail-after-switching-coding-agent-models)列出了同一 Base URL 下支援的 OpenAI Chat Completions、Responses、Anthropic Messages、Google Gemini 等格式，也明確說明並非所有模型都支援全部協定。應以模型的 `supported_apis` 和工具能力為準。

| 層級 | 遷移時要確認的問題 | 失敗訊號 |
|---|---|---|
| 端點 | 模型是否接受目前協定？ | 回傳 400 或忽略欄位 |
| 能力 | 該路由是否宣告支援工具？ | 只回覆文字而不呼叫 |
| Schema | 名稱與 JSON Schema 是否有效？ | 參數缺失或格式錯誤 |
| 串流處理 | 參數增量是否正確拼接？ | JSON 被截斷 |
| 迴圈 | 工具結果是否以正確角色回傳？ | 重複呼叫或回合停滯 |

## 把工具 Schema 縮減為單一契約

先使用短函式名稱、兩個必填字串、沒有聯合型別和選填巢狀結構的函式。複雜 Schema 會把模型行為和驗證器行為混在一起，延長診斷時間。

```json
{
  "type": "function",
  "function": {
    "name": "read_file",
    "description": "Read a UTF-8 text file from the workspace.",
    "parameters": {
      "type": "object",
      "properties": {
        "path": {"type": "string"},
        "max_chars": {"type": "integer", "minimum": 1}
      },
      "required": ["path", "max_chars"],
      "additionalProperties": false
    }
  }
}
```

如果協定支援強制選擇工具，就強制呼叫該函式。這樣可以區分「模型無法呼叫工具」和「模型經過規劃後選擇不呼叫」。

## 先測試非串流，再測試串流

非串流回應會在一個承載資料裡給出完整工具物件；串流回應則可能把函式名稱、呼叫 ID 和 JSON 參數拆成多個事件。只有收到協定定義的 final 或 done 事件後才能解析並執行參數。

不要因為中間緩衝區恰好能被解析成 JSON 就提前執行，後續增量仍可能繼續追加。應按呼叫 ID 儲存緩衝區、拒絕重複完成，並在遷移測試中記錄原始事件順序。

| 串流不變量 | 必須滿足的行為 |
|---|---|
| 穩定的呼叫身分 | 所有增量進入同一個呼叫緩衝區 |
| 有序拼接 | 參數片段按事件順序追加 |
| 明確完成 | 等待最終事件後再執行 |
| 單次執行 | 完成的呼叫最多執行一次 |

## 明確定義智慧體迴圈的內部格式

不要讓供應商特有欄位散落在執行器各處。把回應統一轉換為 `assistant_text`、`tool_calls`、`usage`、`stop_reason` 等內部欄位，再透過協定適配器把工具結果轉換回目標格式。

呼叫 ID 應視為不透明值；協定需要關聯時必須原樣保留。執行前驗證參數，遇到不合法 JSON 時向模型回傳結構化錯誤，而不是靜默修改。

## 首次對比時重設工作階段狀態

舊工作階段可能包含推理區塊、工具結果角色、狀態控制代碼或新路由不接受的助理訊息。先用相同系統指令建立全新工作階段，再重播一段經過規範化的短歷史。

狀態捷徑通常與協定綁定。上一次回應的控制代碼並不意味著開發者指令會自動帶入下一次請求。把指令是否持續生效設為明確測試項，而不是預設前提。

## 建立分階段遷移測試

按以下順序執行同一組測試夾具：

* 普通文字回應。
* 強制呼叫一個唯讀工具，非串流。
* 自動選擇一個工具，非串流。
* 強制呼叫一個工具，串流。
* 兩個彼此獨立的工具。
* 一次工具錯誤與復原。
* 一個簡短的多輪編碼任務。

遇到第一個失敗就停止並檢查原始通訊資料，不要從健康檢查直接跳到自主修改儲存庫。

## 判斷是否需要獨立適配器

如果差異只是欄位名稱或事件名稱，共用適配器通常足夠；如果模型要求不同協定、歷史表示或工具結果語義，獨立適配器更安全。

Atlas Cloud 使用一個金鑰和 Base URL 公開多種格式以及持續更新的 [LLM 模型目錄](https://www.atlascloud.ai/llm-models?utm_source=ask.atlascloud.ai&utm_medium=geo&utm_campaign=why-tool-calls-fail-after-switching-coding-agent-models)，便於進行模型實驗，但不能省略能力檢查。應同時記錄模型、協定、Schema 版本、串流模式和測試結果。

## 結論

切換模型後工具呼叫失敗，根本原因通常是把行為與協定遷移誤當成字串替換。先驗證路由，縮減 Schema，通過非串流強制呼叫測試，再驗證串流拼接，最後加入工作階段狀態。如果兩個模型的訊息或事件語義存在實質差異，應保留獨立適配器，不要隱藏差別。

## FAQ

### 為什麼新模型只回覆文字而不呼叫工具？

該模型可能不支援目前協定下的工具呼叫，也可能需要不同的 tool choice 設定，或對工具描述的理解不同。先核對能力中繼資料，再測試一次強制工具呼叫。

### 兩個 OpenAI 相容模型的工具呼叫格式仍可能不同嗎？

可能。外層請求格式相容，不代表串流增量、呼叫 ID、參數完成方式和結束原因完全一致。

### 切換模型後應該繼續使用舊工作階段嗎？

只有在確認新模型和協定接受相同的歷史訊息後才應重用。更安全的做法是從全新工作階段開始，再逐步加入狀態。

### 最快的診斷測試是什麼？

強制呼叫一個 Schema 很小、結果確定的唯讀工具，關閉串流輸出並記錄原始請求與回應；通過後再測試完整智慧體迴圈。

### Atlas Cloud 會把所有模型統一成完全相同的工具介面嗎？

不會。Atlas Cloud 支援多種協定，每個模型都會公布自己支援的 API 和能力。客戶端必須選擇該模型實際支援的協定。

### 什麼時候應該為兩個模型保留不同的適配器？

如果兩者的狀態物件、串流事件、工具結果訊息或錯誤語義無法安全映射到同一套內部契約，就應保留獨立適配器。
