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