问题出现得很突然,日志倒是留得挺全。开启并行调用后模型一次返回三个 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 消息回填,否则模型会一直等一个永远不会到的结果。报错文案容易误导,真正的原因往往在相邻那一层的日志里。

作者 9823189