记录一下那天晚上的排查过程。工具函数从 pandas 取指标,df.mean() 遇到全 NaN 的列返回 nan,直接 json.dumps 后作为 tool 消息回填,客户端抛 ValueError: Out of range float values are not JSON compliant,整轮 Agent 直接中断。

刚开始盯着「工具层没有统一的序列化出口」,折腾了半个多小时,排掉了。

原因不止一个,得分开看。JSON 标准不支持 NaN 与 Infinity。也可能是pandas 的 to_dict 默认保留 NaN。

还有一种情况,日志把结果打成字符串,看起来一切正常。

复现序列化失败的那一列

python -c "import json,math;print(json.dumps({'v':math.nan},allow_nan=False))"

再往下在工具出口做一次 NaN 转换

python -c "import pandas as pd,json;df=pd.DataFrame({'a':[1,None]});print(json.dumps(df.where(df.notna(),None).to_dict()))"

然后统一用 allow_nan=False 的序列化器暴露问题

python -c "import json;print(json.dumps({'v':0},allow_nan=False))"

给工具结果加一层 pydantic 校验再回填

python tool_result_check.py --schema metric.json --file res.json

中途换过一次思路,把范围缩到最小的那一层,反而快了。

怎么算真的好了,看的是同一批现象。同一批指标回填后不再抛异常,空值以 null 出现,Agent 能继续走到下一轮。

工具出口要有一条固定的序列化通道,NaN 这类值在源头转成 null,比在每个调用点判断省事。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。

作者 9823189