流式响应:在不毁掉 UX 的前提下

流式响应:在不毁掉 UX 的前提下

从外面看,流式输出很简单:token 到达,你追加,用户阅读。等到第一次有不完整的 JSON 块在渲染中途到达,或者代码块开了头但闭合的反引号四秒后才到,你才会理解为什么团队把流式输出当成 UX 问题,而不是传输问题。

流式输出会变丑的地方

流式过程中渲染 Markdown 是最常见的坑。半渲染的标题会让布局抖动;半开的代码围栏让格式溢出到周围文本;尚未闭合的粗体/斜体标记会被字面渲染。修复方式不是裸流,而是缓冲到安全边界(换行、闭合围栏、结构性元素结束),然后按语义单元 flush。即使用户讲不出为什么,他们也能感觉到一条流是丝滑的还是参差的。

反压与放弃

另一个失效模式是用户中途离开页面。没有显式 abort 时,模型会继续生成、你的成本会继续上涨。把 AbortController 串到每一层——fetch、代理、模型 API——并通过看成本面板而不是看代码,来验证 abort 真的传播下去了。

流式是少有的需要工程和设计一起解决的特性。把它们分开,会得到一条上线的流,和一个不上线的 UX。

相关文章