现场是这样的。openai-agents 0.2 的 Runner.run 设了 max_turns 为 6,第 7 次工具调用后直接返回,result.final_output 是 None,业务侧记了空字符串,也没有异常。
中间走过弯路,把「工具没有收敛,每轮都在产生新的调用」当成主因,改完现象没变。
这类报错背后常见的原因有几处,逐个排除就行。到达轮次上限属于正常返回,不是异常;final_output 只在最后一条 assistant 消息上才有;没有检查 result 的原始消息列表。
动手时先打印 result 里的消息链与最后一轮状态
python -c "import json;print(json.load(open('result.json'))['last_agent'])"
显式判断 final_output 为空并抛业务异常
python -c "print({'check':'final_output is None -> raise'})"
接着让工具返回明确的终态标记,减少轮次
python -c "print({'done':True,'reason':'no_more_tools'})"
末了把 max_turns 调高并压测平均轮次
python run_stats.py --max-turns 12 --n 50
我习惯把每一步的执行时间和结果记在一边,后面复盘省事。
恢复的判定其实很直接。同一批请求都能拿到非空 final_output,平均轮次从 6 降到 3,日志里不再出现空回答。
补一句。轮次上限是护栏不是熔断,返回值为空要在业务侧显式判定,否则成功响应里会混进空内容。报错文案容易误导,真正的原因往往在相邻那一层的日志里。
