事情本身不复杂,线索都在日志里。用 gpt-4o 的 function calling,约 3% 的响应里 tool_calls[0].function.arguments 是空字符串,json.loads 直接抛 Expecting value,整条调用链断在这里。
第一反应是「arguments 分片按 index 合并时末片丢失」,验证下来不成立。
原因不止一个,得分开看。并行工具调用时参数写进了另一个 call。还有一种是流式拼接只累加了第一段 delta。
还有一种情况,空参数工具与带参工具混在同一轮。
动手时先把原始 tool_calls 打印出来看分片
python -c "import json;d=json.load(open('resp.json'));print(d['choices'][0]['message']['tool_calls'])"
流式场景按 index 累加 arguments 再解析
python sse_collect.py --index-key tool_calls --out args.json
空串时按 schema 填默认值并重试一次
python fill_default.py --schema tools.json --retry 1
末了把空串发生率打成监控指标
python metric.py --name empty_args_rate --log calls.jsonl
同样的操作我在测试机上先走了一遍,线上只做验证过的部分。
这台环境是别人交接的,不少默认值被动过,只能一项项核。
改完先别撤,确认这几项。空串场景不再抛异常,重试后参数完整,空串发生率在监控里可见且低于 1%。
提醒一点。流式下 arguments 是增量片段,按整串覆盖赋值必然只剩最后一段。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。
