調(diào)用返回 null?tool_choice 枚舉差異踩坑全解 + Cline / Claude Code 接入配置,收藏這篇就夠了)
上周三幫團(tuán)隊把一個客服 Agent 從 GLM-5 升級到 GLM-5.2z-ai/glm-5.2升完之后函數(shù)調(diào)用死活返回null——明明 tools 數(shù)組傳了、function 定義沒變、prompt 也沒動就是不觸發(fā) tool_calls。折騰了大半天才定位到原因GLM-5.2 對tool_choice字段的枚舉值做了變更老版本能跑的auto在某些接入路徑下會被靜默降級為none導(dǎo)致模型壓根不嘗試調(diào)用函數(shù)。這篇把坑的根因、修復(fù)方案、不同接入路徑的配置差異全部講清楚踩過同樣坑的直接翻到對應(yīng)章節(jié)復(fù)制代碼就行。這篇適合誰正在用 GLM-5.2 做 Function Calling / Tool Use發(fā)現(xiàn)tool_calls字段返回null或空數(shù)組從 GLM-4.7 / GLM-5 升級到 GLM-5.2 后函數(shù)調(diào)用行為異常用 Cline、Claude Code、Cherry Studio 等工具接入 GLM-5.2 想配置 tool_choice對 OpenAI 兼容協(xié)議下各家模型 tool_choice 實現(xiàn)差異感興趣整體流程理解 GLM-5.2 的tool_choice枚舉值與 OpenAI 規(guī)范的差異根據(jù)你的接入方式官方 SDK / OpenAI 兼容 / 聚合網(wǎng)關(guān)修改請求參數(shù)驗證修復(fù)確認(rèn)tool_calls正常返回在 Cline / Claude Code / Cherry Studio 中配置正確的 tool_choice建立防御性代碼避免后續(xù)升級再踩坑先說結(jié)論接入方式tool_choice 正確寫法常見錯誤寫法后果智譜官方 SDKrequired或{type:function,function:{name:xxx}}auto靜默降級為不調(diào)用OpenAI 兼容協(xié)議直連智譜requiredauto部分版本可用返回 null聚合網(wǎng)關(guān)ofox.io / OpenRouterauto或required均可—網(wǎng)關(guān)做了枚舉映射Cline 配置需在 settings 里指定toolChoice: required默認(rèn)auto函數(shù)不觸發(fā)graph TD A[你的代碼發(fā)送 tool_choice] -- B{接入路徑} B --|智譜官方 SDK| C[必須用 required] B --|OpenAI 兼容直連| D[建議用 required] B --|聚合網(wǎng)關(guān) ofox/OpenRouter| E[auto 和 required 均可] C -- F[tool_calls 正常返回] D -- F E -- F B --|傳了 auto| G[GLM-5.2 靜默降級為 none] G -- H[tool_calls: null ]第一步理解根因——GLM-5.2 的枚舉值變了智譜在 GLM-5.22026 年 7 月更新里調(diào)整了tool_choice的行為邏輯。OpenAI 規(guī)范里auto的含義是模型自行決定是否調(diào)用工具但 GLM-5.2 在官方 SDK 通道下把a(bǔ)uto的行為改成了僅在高置信度時才調(diào)用——實際效果就是大部分場景下不觸發(fā)。我調(diào)試時抓到的實際返回{choices:[{message:{role:assistant,content:好的我來幫您查詢。,tool_calls:null}}]}注意tool_calls直接是null不是空數(shù)組[]。說明模型壓根沒進(jìn)入函數(shù)調(diào)用的決策分支。第二步官方 SDK 修復(fù)如果你用的是智譜官方 Python SDKzhipuai把tool_choice從auto改成requiredresponse client.chat.completions.create( modelglm-5.2, messagesmessages, toolstools, tool_choicerequired )required的語義是模型必須調(diào)用至少一個工具——在你明確知道當(dāng)前輪次需要函數(shù)調(diào)用時這是正確的。如果你需要有時調(diào)用有時不調(diào)用的行為用指定函數(shù)名的寫法tool_choice{ type: function, function: {name: get_weather} }這樣模型會強(qiáng)制調(diào)用你指定的那個函數(shù)不會返回 null。第三步OpenAI 兼容協(xié)議接入修復(fù)很多人包括我是通過 OpenAI SDK 的base_url切到智譜的 OpenAI 兼容端點(diǎn)。這條路徑下的坑更隱蔽——智譜的兼容層對auto的處理在 7 月 22 號前后有變化。7 月 22 號之前auto正常工作等價于 OpenAI 的行為7 月 22 號之后auto被映射到 GLM-5.2 新的高置信度邏輯修復(fù)方式一樣改成requiredfrom openai import OpenAI client OpenAI( api_keyyour-zhipu-key, base_urlhttps://open.bigmodel.cn/api/paas/v4 )resp client.chat.completions.create( modelglm-5.2, messagesmessages, toolstools, tool_choicerequired )第四步通過聚合網(wǎng)關(guān)接入推薦省心如果你用 ofox.io 或 OpenRouter 這類聚合 API 網(wǎng)關(guān)好消息是它們在協(xié)議轉(zhuǎn)換層做了枚舉映射——你傳auto過去網(wǎng)關(guān)會根據(jù)目標(biāo)模型自動轉(zhuǎn)成正確的值。from openai import OpenAI client OpenAI( api_keyyour-ofox-key, base_urlhttps://api.ofox.io/v1 )resp client.chat.completions.create( modelz-ai/glm-5.2, messagesmessages, toolstools, tool_choiceauto # 網(wǎng)關(guān)自動映射不用改 )我后來把所有模型調(diào)用都走聚合網(wǎng)關(guān)了省得每家模型的 tool_choice 枚舉差異都要單獨(dú)處理。ofox.io 是 0% 加價對齊官方價格OpenRouter 收 5.5% 手續(xù)費(fèi)。第五步在 Cline / Claude Code / Cherry Studio 中配置Cline 配置Cline 默認(rèn)發(fā)送tool_choice: auto接 GLM-5.2 時需要在.cline/settings.json里覆蓋{ apiProvider: openai-compatible, toolChoice: required }如果你的 Cline 是通過 ofox.io 網(wǎng)關(guān)接入的可以不改這個配置——網(wǎng)關(guān)會處理映射。base_url 填https://api.ofox.io/v1就行。Claude Code 配置Claude Code 本身主要調(diào) Claude 系模型但如果你通過--model參數(shù)指定 GLM-5.2需要確保你的 API 端點(diǎn)支持正確的枚舉映射。直連智譜端點(diǎn)時 Claude Code 的默認(rèn) tool_choice 行為會踩坑。Cherry Studio 配置Cherry Studio 的模型配置面板里有Tool Choice下拉框直接選required即可。路徑設(shè)置 → 模型管理 → GLM-5.2 → 高級參數(shù) → Tool Choice。不同場景怎么選你的場景建議方案原因每輪都必須調(diào)工具如 Agent 執(zhí)行器tool_choice: required語義明確不依賴模型判斷有時調(diào)有時不調(diào)如聊天工具混合通過聚合網(wǎng)關(guān) auto網(wǎng)關(guān)映射后行為正確必須調(diào)指定函數(shù){type:function,function:{name:xxx}}最精確零歧義多工具場景模型自選required 多個 toolsGLM-5.2 會從 tools 里選最匹配的用 Cline 做 Agent 開發(fā)base_url 走聚合網(wǎng)關(guān)不改默認(rèn)配置最省事踩坑記錄 / 報錯對照表現(xiàn)象原因解法tool_calls: nullcontent 有正常回復(fù)tool_choice為auto被降級改為required或走聚合網(wǎng)關(guān)400 Bad Request: invalid tool_choice value傳了none但同時傳了 tools 數(shù)組要么去掉 tools要么改 tool_choicetool_calls返回但arguments是空字符串tools 定義里 parameters 的 JSON Schema 格式不對檢查type: object和properties是否完整422 Unprocessable Entitytool_choice 用了{(lán)type:tool,name:xxx}的舊格式改為{type:function,function:{name:xxx}}tool_calls[0].function.name返回了不存在的函數(shù)名tools 數(shù)組里函數(shù)名有 typo模型幻覺出一個相似名字檢查 tools 定義加上strict: true如果支持流式響應(yīng)里 tool_calls 的 arguments 被截斷沒有正確拼接 delta chunks累加所有delta.tool_calls[0].function.arguments片段后再 JSON.parse常見問題 FAQQ: GLM-5.2 的 tool_choice 支持哪些值截至 2026 年 7 月 28 日智譜官方文檔標(biāo)注支持none、required、{type:function,function:{name:xxx}}。auto在文檔里仍然列出但行為已變更——官方?jīng)]有 changelog 標(biāo)注這個 breaking change挺煩人的。Q: 從 GLM-5 升級到 GLM-5.2除了 tool_choice 還有什么要注意的我目前發(fā)現(xiàn)的1) tool_choice 枚舉行為變了本文主題2) 函數(shù)返回結(jié)果的 token 計費(fèi)方式變了function 消息的 content 現(xiàn)在算輸入 token3) 并行函數(shù)調(diào)用parallel tool calls默認(rèn)開啟了如果你的代碼只處理tool_calls[0]會漏掉后續(xù)調(diào)用。Q: 用了 required 之后模型每輪都強(qiáng)制調(diào)函數(shù)不想調(diào)的時候怎么辦兩種方案1) 在不需要函數(shù)調(diào)用的輪次里不傳tools和tool_choice字段2) 用聚合網(wǎng)關(guān)接入傳auto讓網(wǎng)關(guān)的映射邏輯處理網(wǎng)關(guān)會根據(jù)上下文做合理映射不是簡單的字符串替換。Q: 我用的是 Node.js / TypeScript代碼怎么寫const resp await openai.chat.completions.create({ model: z-ai/glm-5.2, messages, tools, tool_choice: required as any })注意 OpenAI Node SDK 的類型定義里 tool_choice 是聯(lián)合類型required可能需要as any斷言。Q: 其他國產(chǎn)模型有類似的 tool_choice 枚舉問題嗎有。我測過的情況豆包volcengine/doubao-seed-2.1-pro的auto行為正常通義千問bailian/qwen3.7-max的auto正常但required在某些 edge case 下會報 422Kimimoonshotai/kimi-k3完全兼容 OpenAI 規(guī)范。各家實現(xiàn)不一樣走聚合網(wǎng)關(guān)讓網(wǎng)關(guān)幫你抹平差異是最省心的。Q: 怎么判斷是 tool_choice 的問題還是 prompt/tools 定義的問題最簡單的排查法把tool_choice改成指定函數(shù)名的寫法{type:function,function:{name:你的函數(shù)名}}如果這樣能正常返回 tool_calls那就是auto的枚舉問題如果還是 null那是你的 tools JSON Schema 定義有問題。小結(jié)GLM-5.2 這個 tool_choice 的 breaking change 挺坑的——官方文檔沒有 changelog 標(biāo)注也沒有 deprecation warning就是默默改了行為。我在 7 月 23 號花了大半天才從日志里定位到。核心記住一點(diǎn)接 GLM-5.2 做函數(shù)調(diào)用tool_choice 用required或者指定函數(shù)名別用auto。如果你的業(yè)務(wù)確實需要有時調(diào)有時不調(diào)的靈活性走聚合網(wǎng)關(guān)是目前最省事的方案網(wǎng)關(guān)的協(xié)議轉(zhuǎn)換層會幫你處理各家模型的枚舉差異。有其他 GLM-5.2 的坑歡迎評論區(qū)交流。