问题出现得很突然,日志倒是留得挺全。开启并行调用后模型一次返回三个 tool_call,客户端只处理了第一个,回填时也只发了一条 tool 消息,下一轮模型说缺少信息,任务原地打转。
刚开始盯着「并发执行时异常吞掉,失败的调用没回填」,折腾了半个多小时,排掉了。
真正麻烦的地方在于,几个原因的现象几乎一样。循环里 break 掉了,只执行第一个调用。另一种情况是tool 消息的 tool_call_id 与请求对不上。
少数情况下是回填顺序与请求顺序不同,模型按位置理解错。
先把返回的 tool_calls 数量与 id 打出来
python -c "import json;d=json.load(open('r.json'));print([c['id'] for c in d['choices'][0]['message']['tool_calls']])"
随后按 id 建映射并逐个执行,失败也要回填
python run_parallel.py --trace --on-error return_text
回填时严格使用原始 tool_call_id
python -c "import json;print([{'role':'tool','tool_call_id':i,'content':'ok'} for i in ['call_a','call_b']])"
校验消息序列里每个 id 都有对应回复
python check_ids.py --messages msgs.json
怎么算真的好了,看的是同一批现象。三个调用都有对应 tool 消息,id 一一匹配,下一轮模型能直接给出结论而不是再要数据。
并行调用最容易漏的是失败分支,异常也要转成 tool 消息回填,否则模型会一直等一个永远不会到的结果。报错文案容易误导,真正的原因往往在相邻那一层的日志里。
