现场是这样的。openai 1.55 的 gpt-4.1 做结构化输出,response_format 里 json_schema 的 name 用了 invoice_extraction_2026_11_15_final_v3,请求返回 400,原文 name must be at most 64 characters。
中间走过弯路,把「SDK 自动拼接了项目前缀导致超长」当成主因,改完现象没变。
排查方向其实有限,先把可能性排一排。name 超过 64 个字符的上限;name 里带了空格或斜杠等非法字符;name 过长让缓存键不稳定,命中率下降。
量一下实际发出的 name 长度
python -c "n='invoice_extraction_2026_11_15_final_v3';print(len(n))"
再往下改成稳定的短名并写进常量
python -c "print('SCHEMA_NAME = \'invoice_v3\'')"
然后用 curl 复现并确认请求体里的 name
curl -s https://api.openai.com/v1/chat/completions -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d @body.json
末了在封装层加长度和字符集校验
python validate_schema_name.py --max 64
这类问题以前遇到过,但这次的触发条件和上次不一样。
这类改动我都写进变更记录,过两周再出问题时能对上号。
恢复的判定其实很直接。请求返回 200,返回的 JSON 能通过校验,日志里的 name 固定为 invoice_v3。
补一句。name 不只是标签,它参与结构化输出的缓存键,带时间戳的名字会让每次都重新编译 schema,成本和延迟都会上去。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。
