你让 AI 整理一份方案,前面几段都挺顺畅。写到“具体执行步骤如下”时,文字突然停了。
光标还在闪,停止按钮也还亮着。你等了十几秒,没动静。切出去看了一眼消息,网络好像没问题,再回来,还是那半句话。
这时候点“重新生成”,舍不得前面已经写好的内容;继续等,又不知道它到底还在不在工作。
流式回答带来的一个新麻烦是:任务还没结束,用户已经拿到了一部分结果。连接出了问题,这部分内容该怎么处理,比普通页面加载失败复杂得多。
同样是“没出字”,可能卡在不同地方
一次回答大致会经过几个阶段:手机发出请求,服务端开始处理,第一段内容返回,后续内容持续到达,最后收到结束信息。
第一次出字前的等待,可能来自网络,也可能是服务端排队、检索资料、调用工具或模型计算。只凭页面转圈,很难判断是哪一段慢了。
已经出字后突然停住,也不一定就是断网。服务端可能暂时没有新的内容,中间转发环节可能在缓冲,手机也可能还没把收到的数据画到屏幕上。
排查时,至少要把“等到第一段内容的时间”和“输出过程中停顿的时间”分开。前者一直很长,后者却很顺畅,与每隔几秒就停一次的问题,通常需要不同的调查方向。
弱网模拟可以帮助验证其中的网络因素,但不能仅靠几条数据包记录,就认定模型思考了多久。
为什么会突然蹦出一大段文字?
屏幕上的输出速度,并不直接等于模型的生成速度。
可以把服务端输出想成不断往外递纸条。纸条要经过网络和中间转发服务,到达客户端后还要被解析、显示。中间有人攒了一小叠才往下递,你看到的就会是“停一下,然后突然出现一大段”。
网络重传也会造成类似现象。以依赖有序可靠传输的连接为例,前面的数据缺了一块,后面的内容可能要等它补齐才能交付。缺口补上后,积压内容一起到达。
客户端自身也可能按固定节奏刷新界面。因此,光靠录屏判断“模型输出忽快忽慢”并不准确。录屏记录的是用户最终看到的节奏,原因还得结合服务端和客户端的时间记录来看。
断线后重连,能接着上次说吗?
这要看产品有没有为恢复做准备。
重新建立一个连接,只解决了通道问题。服务端是否保留原任务,之前的内容还能不能取回,客户端能不能说明“我已经收到这里了”,都需要另外约定。
如果没有这些能力,再发一次相同问题,通常是在启动一次新的生成。新回答可能换个结构,也可能与前半段接不上。原任务如果仍在后台运行,还可能增加资源消耗;是否产生额外费用,要看具体服务的计费规则。
所以“重连”“重新获取原回答”和“重新生成”最好在产品里分清楚。它们对用户来说是不同的选择。
自动重试也有这个限制。HTTP 的语义规范要求客户端在自动重试非幂等操作前,能够确认重复执行是安全的,或确认原操作没有生效;不能仅凭连接失败就推断可以重做。RFC 9110:请求重试
放到 AI 对话里,就是先弄清楚原任务是否还在,再决定要不要创建下一次生成。
用户点了“停止”,停止的是哪件事?
还有一个容易漏掉的场景:回答卡住后,用户点了停止。网络恢复时,文字却又继续往外冒。
这可能是积压内容刚刚到达,也可能是客户端只断开了显示连接,服务端任务仍然在运行。关闭连接并不天然等于取消计算,取消需要端到端的支持。
页面至少应该尊重用户已经停止的选择。属于旧任务的内容晚到了,也不该混进新回答。如果产品只能停止接收,无法保证服务端立即终止,就要按实际能力设计交互,别把两件事当作同一个动作。
同样的问题也会出现在连续提问时。第一轮还没收尾,用户已经发了第二个问题,两个任务的返回内容必须各自归位。
从四个位置打断,比随便调个丢包率更有用
测试时可以固定一个问题,分别在下面几个位置制造短暂的网络异常。
| 中断位置 | 重点观察 |
|---|---|
| 第一段内容返回之前 | 页面能否解释等待,重试是否启动重复任务 |
| 回答输出到一半 | 已有内容是否保留,恢复后是否重复或缺段 |
| 大部分内容到达、结束信息尚未到达 | 是否误把不完整回答标成已完成 |
| 用户点击停止之后 | 晚到内容是否继续更新页面或混入下一轮回答 |
这里的结束信息尤其容易被忽略。连接关闭可能是正常结束,也可能是故障。客户端应该根据所用协议约定的完成事件或任务状态判断结果,不能看到一段像结尾的话,就猜测它已经写完。
实际测试可以先正常输出,随后制造几秒下行不可用,再恢复网络。这与切换 Wi-Fi、把应用放到后台是不同条件,最好分开验证;一开始全部混在一起,出了问题反而难定位。
如果要比较两个版本,保留相同问题、业务操作时机和弱网场景。固定随机种子有助于控制模拟器的随机决策,但服务端负载、生成内容和实际流量顺序仍可能变化,不能指望整段回答逐字、逐毫秒重放。
页面可以把情况说得更具体一点
一个一直闪的光标,承担不了所有状态表达。
等待首段响应时,可以说明请求正在处理;已经接收部分内容后失联,可以保留正文,标明回答中断。能恢复原任务,就提供继续接收;只能重新生成,就让用户知道它会产生一份新回答。
不要为了显得聪明,随意把所有等待写成“正在深度思考”。如果系统没有这样的状态依据,这句话只是在替故障找理由。
已有内容也值得留下来。即使最后一段没收到,用户可能已经得到了需要的信息。是否复制、保存或重新尝试,可以交给用户决定,但未完成状态要清楚。
判断体验是否合格,可以先看几个具体结果:中断后是否保留正文,恢复时是否重字漏字,停止后是否还会追加内容,最终完成状态是否可信。它们比单看一次请求有没有返回成功更贴近使用过程。
留住已经收到的那半份答案
流式交互让用户更早看到结果,也让失败发生在了阅读过程里。对用户来说,前面那几段已经是自己的工作材料,突然清空重来会很挫败。
网络出问题时,先保留它,说明当前状态,再给出确实可用的下一步。下次答案停在“具体执行步骤如下”时,用户至少能知道:这是暂时没收到后续内容,还是需要重新发起一次任务。
144



被折叠的 条评论
为什么被折叠?



