事情本身不复杂,线索都在日志里。用 gpt-4o 的流式函数调用做订单查询,delta.tool_calls 里同一个 index 出现多次,按 index 直接覆盖后 arguments 只剩最后一小段,json.loads 报 Unterminated string。
第一反应是「只有 finish_reason 为 tool_calls 时内容才完整」,验证下来不成立。
排查方向其实有限,先把可能性排一排。arguments 是增量片段 必须按顺序拼接。少数情况下是index 表示第几个调用 不是分片序号。
还有一种情况,并行调用时 index 会跳号。
上来先把每个 delta 原样记下来观察
python -c "print('log each delta.tool_calls')"
接着按 index 分组累加 arguments
python agg.py --in deltas.jsonl --group index
收到完成信号后再统一解析
python -c "print('parse after finish_reason')"
末了对解析失败的调用做一次补偿重试
python retry_tool.py --strict false
排查用的命令都是临时敲的,没有写成脚本,事后才整理。
恢复的判定其实很直接。聚合后的 arguments 能被 json.loads 解析,订单号完整,工具调用成功率回到正常水平。
补一句。流式函数调用和流式文本不一样,参数是拼出来的,任何按块覆盖的写法都会丢内容。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。
