记录一下那天晚上的排查过程。请求里显式写了 parallel_tool_calls 为 false,gpt-4o 仍然在一次响应里返回两个 tool_calls,业务侧只处理了第一个,第二个结果丢失。
刚开始盯着「参数被 SDK 丢弃,实际没发到服务端」,折腾了半个多小时,排掉了。
把日志和配置对完,能解释这个现象的基本就这几处。该参数需要模型与接口版本同时支持。也可能是工具本身无依赖,模型倾向一次给全。
还有一种情况,网关做了参数白名单,未知字段被过滤。
先抓包确认请求体里真的有这个字段
curl -s https://api.openai.com/v1/chat/completions -H "Authorization: Bearer $OPENAI_API_KEY" -d '{"model":"gpt-4o","parallel_tool_calls":false,"messages":[{"role":"user","content":"查北京和上海天气"}],"tools":[{"type":"function","function":{"name":"weather","parameters":{"type":"object","properties":{"city":{"type":"string"}}}}]}'
再往下在提示里明确要求一次只调一个
python -c "print('每次只调用一个工具,拿到结果后再决定下一步')"
业务侧改成循环处理全部 tool_calls
python -c "calls=[{'id':'a'},{'id':'b'}];print([c['id'] for c in calls])"
等前面都确认过,再把网关的字段白名单补上该参数
python -c "print({'allow':['model','messages','tools','tool_choice','parallel_tool_calls']})"
别只看报错消失,验证要多做一步。响应里只出现一个 tool_call,或业务侧能完整处理两个,结果不再丢失。
关掉并行只是提示性的,最稳的做法还是按数组处理,别假设一次只会有一个调用。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。
