记录一下那天晚上的排查过程。Python 3.11 用 anthropic 0.49 调 claude-3-7-sonnet-20250219,开了 thinking 并给 budget_tokens 2048,同时把 tool_choice 设成 {"type":"tool","name":"query_order"},接口回 400,原文是 Thinking may not be enabled when tool_choice forces tool use。改成 auto 能通,可模型又不肯调工具,只回一段分析文字。

刚开始盯着「并行工具开关和 thinking 一起打,请求被判定为组合冲突」,折腾了半个多小时,排掉了。

把日志和配置对完,能解释这个现象的基本就这几处。思考模式与强制工具选择在协议层互斥,不能同时要求。少数情况下是tool_choice 指定了具体函数,等于要求立刻调用。

不容易想到的是,SDK 把 tool_choice 的默认值补成了 any,代码里看不见。

上来先用 curl 复现,确认是参数组合而不是 SDK 拼错

curl https://api.anthropic.com/v1/messages -H "x-api-key: $ANTHROPIC_API_KEY" -H "anthropic-version: 2023-06-01" -H "content-type: application/json" -d '{"model":"claude-3-7-sonnet-20250219","max_tokens":4096,"thinking":{"type":"enabled","budget_tokens":2048},"tool_choice":{"type":"tool","name":"query_order"},"messages":[{"role":"user","content":"查订单 123"}]}'

随后把 tool_choice 改成 auto 再发一次,确认其余参数没问题

python -c "import anthropic;print(anthropic.__version__)"

再往下用提示词要求先分析再决定是否调用,把强制交给模型

python check_tool_call.py --choice auto --prompt '先分析再决定是否调用工具'

末了确实需要强制调用时,把 thinking 关掉再走同一分支

python call_claude.py --thinking off --tool-choice query_order

改完先别撤,确认这几项。请求返回 200,content 里先出现 thinking 块再出现 tool_use 块,工具名与 schema 完全一致。

同一份代码在两版模型上表现不同,升级模型前把 thinking 与 tool_choice 的组合单独跑一遍最省事。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。

作者 9823189