先看现象。responses.create 里沿用了 chat 的 max_tokens,SDK 先报 400 Unknown parameter,改成 max_output_tokens=256 能跑通,但长回答永远在句子中间断掉,返回体里 incomplete_details.reason 是 max_output_tokens。

真正麻烦的地方在于,几个原因的现象几乎一样。256 对带推理链的模型明显不够,额度先被推理 token 吃掉。少数情况下是推理 token 也计入 max_output_tokens,正文可用空间被压缩。

还有一种情况,客户端没检查 status=incomplete,把半截文本当完整结果入库。

另外,上下文接近窗口上限时,输出额度会被自动下调。

动手时先把 status 和 incomplete_details 一起打出来

python -c "from openai import OpenAI;r=OpenAI().responses.create(model='gpt-5-mini',input='hi',max_output_tokens=256);print(r.status,r.incomplete_details)"

调大额度用同一个问题重跑

curl https://api.openai.com/v1/responses -H "Authorization: Bearer $OPENAI_API_KEY" -H "Content-Type: application/json" -d '{"model":"gpt-5-mini","input":"写三百字说明","max_output_tokens":2048}'

接着看 usage 里 reasoning 占了多少 token

curl -s https://api.openai.com/v1/responses -H "Authorization: Bearer $OPENAI_API_KEY" -H "Content-Type: application/json" -d '{"model":"gpt-5-mini","input":"hi"}' | jq '.usage'

末了在落库前用 jq 拦住不完整的结果

curl -s https://api.openai.com/v1/responses -H "Authorization: Bearer $OPENAI_API_KEY" -H "Content-Type: application/json" -d '{"model":"gpt-5-mini","input":"写三百字说明","max_output_tokens":2048}' | jq -r '.status, .incomplete_details.reason'

恢复的判定其实很直接。返回体 status 是 completed,incomplete_details 为 null,正文长度接近需求字数,usage 里的 reasoning_tokens 加 output_tokens 没有顶到上限。

推理模型的额度是先推理后作答,max_output_tokens 要按推理开销留余量,按 chat 时代的最小值照搬,看起来像模型能力问题,实际只是额度卡住。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。

作者 9823189