DOCAI · 课程 · L2 · 25 分钟
流式输出与超时设置
打开流式、逐块拼接文本、给首字节和总时长各设一个超时:让用户早点看到字,也让卡住的连接能自己退出。
你将学会
- 能把一次普通请求改成流式并逐块打印
- 能分别设置首字节超时与总超时
- 流中断时能判断该重试还是该放弃
打开流式
stream = client.chat.completions.create(
model=os.environ["DOCAI_MODEL"],
messages=[{"role": "user", "content": "写一段 200 字的产品介绍"}],
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta.content
if delta:
print(delta, end="", flush=True)
关键点:每块可能是空字符串,要判空;拼接顺序就是到达顺序,不要自己排序。
两个超时,各管一段
| 超时 | 管什么 | 设太长的后果 |
|---|---|---|
| 首字节超时 | 从发出到收到第一块 | 用户盯着空白页 |
| 总超时 | 整个流的最长时长 | 卡住的连接一直占资源 |
只设总超时,等于允许「前 50 秒什么都不来」。只设首字节超时,等于允许「来了一个字之后永远不结束」。
断流的三种情况
- 首字节超时:多半是排队或输入太长。可以退避重试一次。
- 中途断开:网络或代理问题。多数服务不支持续传,只能整段重发。
- 输出被截断:撞上了
max_tokens。不是错误,但内容不完整,要能识别。
重发意味着输入 token 再算一次,成本会上升。重试要有次数上限。
怎么验证做对了
- 长输出时,第一个字应在 1–2 秒内出现(具体取决于服务与网络)。
- 拔网线再恢复,程序应该在超时后退出,而不是永远挂着。
- 把
max_tokens设为 10,确认你能识别「被截断」而不是当成正常结束。
自测
- 流式输出会让总生成时间变短吗?为什么?
- 为什么两个超时都要设?只设一个会漏掉什么?
- 流中断后重发,成本为什么会增加?