跳到主要内容

首字延迟 (TTFT) 是你尚未监测的延迟 SLO

· 阅读需 12 分钟
Tian Pan
Software Engineer

调出过去一周的生产环境追踪记录,查看你的延迟仪表板。你几乎肯定在总请求延迟上设置了 p50 和 p99。你可能还有令牌吞吐量(token throughput)。你甚至可能有一张每秒令牌数(tokens-per-second)图表,因为某个供应商的基准测试说服你这么做了。但你几乎肯定没有的是按模型、按路由、按租户划分的**首字时间(time to first token, TTFT)**直方图 —— 这是决定你产品感知速度的核心指标。

这绝非一个小疏忽。对于任何流式界面 —— 聊天、代码补全、智能体侧边栏、语音 —— 用户感知的速度取决于在内容出现之前,他们盯着闪烁光标的时间。一旦第一个令牌(token)出现,用户就开始进入阅读状态;随后的令牌是在与他们的阅读速度竞争,而不是与他们的耐心竞争。总延迟(Total latency)对于吞吐量规划和成本预算很重要,而 TTFT 则决定了产品是否让人感觉“有生命力”。

这两个数字之间的差距正在拉大。推理模型(Reasoning models)产生的总延迟可能与其非推理兄弟模型完全相同,但却会将 TTFT 从 400 毫秒推高到 30 秒。一个“保持延迟持平”的路由更改,可能会悄无声息地将一个反应灵敏的助手变成一个卡死的窗口。如果你没有对 TTFT 进行图表化,你就是在发布连你自己都察觉不到的 UX 退化。

为什么总延迟隐藏了你实际交付的 UX

总延迟是从发出请求到收到最后一个令牌的时间。它是批处理作业、成本模型以及任何用户不在实时观看场景的正确指标。但对于流式界面,它是两种在感官体验上截然不同的过程粘合在一起的复合体。

第一阶段是等待。用户点击了发送,加载动画在旋转,什么也没发生。这一阶段的每一秒都显得格外漫长。关于聊天界面的研究得出了一个粗略的结论:一秒以内的响应感觉是即时的,一到三秒感觉很快,而超过三秒就感觉慢了。在客户服务机器人上,每增加一秒的等待时间,用户流失率就会上升大约 7% 到 10%。这一阶段完全由 TTFT 主导。

第二阶段是阅读。令牌正在流式传输,用户的眼睛在移动,认知负荷分布在模型的输出速度和用户的输入速度之间。如果令牌到达的速度快于阅读速度 —— 英文散文大约每分钟 250 个单词,或每秒约 5 个令牌 —— 用户根本不会注意到令牌间的延迟。这一阶段的令牌吞吐量是在与用户竞争,而不是与空白屏幕竞争。

p99 总延迟模糊了这两个阶段。一个包含 200 毫秒 TTFT 和快速流式传输的 12 秒响应,与一个包含 11 秒沉默后突然爆发的 12 秒响应,给人的感觉完全不同。你的仪表板无法区分它们,但你的用户可以。

推理模型的时间炸弹

传统 LLM 的 TTFT 几乎全部消耗在预填充(prefill)阶段 —— 即处理输入令牌并计算 KV 缓存。预填充是可预测的:提示词(prompt)越长,耗时越长,而在长上下文场景下,缓存系统提示词可以将 TTFT 降低多达 80%。工程师对这部分通常有较好的直觉。

推理模型打破了这种直觉。在产生一个用户可见的令牌之前,模型会生成一个内部思维链,可能包含数百到数万个令牌。从用户的角度来看,这与预填充没有区别 —— 屏幕是空白的,光标在闪烁 —— 但从基础设施的角度来看,这是伪装成 TTFT 的解码时间。目前的推理级别模型在处理某些问题时,TTFT 常在 10 到 150 秒之间,而同样的场景非推理模型只需 400 毫秒即可产出首字。

这造成了一个路由陷阱。像“将难题路由到推理层,简单题路由到快速层”这样的启发式方法优化了准确性和总延迟,却可能默默地毁掉 TTFT。如果你的产品有任何流式路径 —— 大多数产品都有 —— 将 20% 的流量转移到推理模型可能会让你的 p99 总延迟仪表板保持平稳,同时摧毁应用的感知响应速度。

第二个更隐蔽的失败是:推理模型 API 通常只公开“思维摘要”,而不提供原始思维令牌。如果你的 UI 在思考阶段没有渲染任何内容,你就是在让用户在最昂贵、最慢的请求部分里盲等。无论你的仪表板显示什么,你的用户都会觉得“模型坏了”。

每个生产团队都应该采集的 TTFT 基准

在设置 SLO 之前,你需要基准。以下测量指标是让你能够分析流式 UX 的最低要求。

  • 按模型的 TTFT 直方图。 为你路由到的每个模型记录 p50、p95、p99 的 TTFT,并按输入长度桶(bucket)进行细分(例如:0–2k、2k–10k、10k–50k、50k+ 令牌)。单一的中位数是不够的,因为预填充与输入长度呈线性关系,而尾部延迟通常由缓存未命中驱动。
  • 缓存命中率以及命中 vs. 未命中的 TTFT。 提示词缓存(Prompt caching)在 1k 令牌时可以减少 7% 的 TTFT,而在 150k 令牌时可以减少 67%。如果你没有分开追踪缓存命中情况,你的 TTFT 分布将是双峰的(bimodal),你在优化“慢”模式上所做的任何努力在分离它们之前都不会显现出来。
  • 推理阶段时长作为一个独立的指标。 对于推理模型,分别测量首个推理令牌时间(TTFRT)和首个答案令牌时间(TTFAT)。只有当你渲染思考过程时,前者才面向用户;后者才是真正出现在聊天气泡中的内容。
  • 按租户和按路由的 TTFT。 长的系统提示词、大型检索上下文和工具密集的提示词都会推高 TTFT。聚合的仪表板会掩盖这些差异。按路由的直方图可以告诉你哪个产品功能点的体验正在退化。
  • 在边缘侧测量 TTFT,而不是在模型侧。 从用户的客户端测量,或者至少从你的边缘终结点(edge terminator)测量,而不是从你的推理服务器测量。网络、流式封装和 SSE 保活(keep-alive)开销可能会增加 50–300 毫秒,而你的 GPU 指标永远看不到这些。

如果你已经记录了总延迟和令牌计数,添加 TTFT 只是为每个请求增加一个跨度属性(span attribute)。阻力几乎总是来自管理层面,而非技术层面:没有人负责这个 SLO,所以没有人捕获这个数字。

掩盖 TTFT 而不欺骗用户的 UX 脚手架

一旦你开始衡量 TTFT(首指令到达时间),你就可以从两个方向入手:降低它,或者掩盖它。掩盖往往被低估了,因为工程师本能地更倾向于“真正的”修复。但掩盖几乎总是成本更低,而且往往是正确的答案,特别是对于 TTFT 是固有特性的推理模型(Reasoning models)而言。

乐观大纲(Optimistic outlining)。一旦请求离开客户端,立即渲染一个符合预期输出形状的占位符结构:标题、列表骨架、代码块框架。这让用户在预填充(Prefill)运行时有内容可以解析。规则是占位符在结构上必须是诚实的——如果你渲染了三个列表项,而模型返回了五个,你就已经训练用户不再信任大纲了。仅在请求确定的粒度级别上使用占位符。

占位符流(Placeholder streaming)。在模型响应 之前,由应用层立即发送一个“正在输入……”或单词确认。这不是作弊;这与 Slack 上的输入指示器具有相同的功能,它在不欺骗用户内容的前提下,重置了用户的等待心理时钟。窍门是保持确认足够简短,以便模型的真实 Token 可以覆盖它而不产生卡顿感。

渲染思维过程(Rendered thinking)。对于推理模型,在折叠面板中显示思维摘要,该面板在第一次请求时默认打开,在后续回合中折叠。关于用户对 AI 系统感知研究得出了相同的结论:拟人化的“正在思考……”功能可以为你赢得 10 秒的耐心,而白屏则不行。如果服务商只提供摘要,不要渲染原始的思维 Token——展示未经过滤流的诱惑力很大,但当模型的思维链与最终答案矛盾时,往往会适得其反。

骨架到内容的连续性(Skeleton-to-content continuity)。当真实的 Token 流开始时,它应该流入骨架而没有明显的重排(Reflow)。首个 Token 时的重排是现代聊天产品中最令人沮丧的微观 UX 失败。如果你的骨架是一个灰色矩形,而你的 Token 以不同的字体和宽度落地,用户会将首个 Token 视为页面加载,而不是内容的延续。

这些脚手架中的每一个都是伪装成工程工作的生产决策。它们需要 UI 团队和基础设施团队在协议上达成一致——即从服务器到客户端提交什么以及何时提交——而大多数组织从未将此正式化。

将 TTFT 视为硬约束的路由策略

标准的 LLM 路由决策被框架化为质量与成本的权衡:对于每个查询,选择满足质量标准的最低成本模型。这是在一个三维问题上进行的二维优化。第三个维度是 TTFT,当它缺失时,路由系统会乐于将面向用户的查询分配给推理层,因为评估中的准确率提升看起来很不错。

解决方法是将 TTFT 视为硬约束,而不是软目标。具体而言:

  • 基于不同界面的 SLO。为每个产品界面定义 TTFT 预算。代码补全弹窗可能是 100 ms。聊天助手可能是 500 ms。用户启动后即可离开的深度研究侧边栏可能是 30 秒。不知道界面的路由系统无法遵守这一约束。
  • 提交前预估。在路由之前,根据输入长度、缓存预热状态以及(对于推理层)预期的思维 Token 预算,预估候选模型的 TTFT。如果预估超过了该界面的 SLO,则路由失败。预估可以是低成本的——一个以模型和输入桶(Input bucket)为键的查找表,通常能达到观测到的 p95 的 20% 以内。
  • 回退层,而非质量层。如果推理层会违反 TTFT SLO,请回退到非推理层并提供降级答案的功能,而不是让用户等待。“我们为你提供了一个快速答案;点击此处获取深度答案”可以保持界面的响应性,并使昂贵的路径变为可选。
  • 异步逃生通道。对于深度答案确实至关重要的界面,提供异步路径:派遣到推理层,返回一个运行 ID,并在完成时通知。这是 Agent UX 的收件箱模式,也是自然 TTFT 超过界面 SLO 的请求的正确归宿。不要假装 30 秒的 TTFT 是聊天响应。
  • 事后校准。路由会发生偏移。缓存率会变,模型版本会变,流量组合也会演进。闭环处理:对于每个路由决策,记录预测的 TTFT、观察到的 TTFT 和 SLO;当预测与观察的偏差超过阈值时发出告警。没有反馈的路由系统最终会开始撒谎。

在这种框架下,“哪个模型最便宜”成了在 TTFT 可行性检查 之后 的平局决胜因素,而不是整个决策的驱动力。这反转了大多数 LLMOps 平台展示权衡的方式,也是唯一能在与推理模型接触时生存下来的框架。

下周一早上该做什么

你不必大费周章。三个动作就能让你领先于大多数团队:

  1. 将 TTFT 添加为每次推理调用的日志跨度属性(Span attribute),并按模型和输入长度桶进行分段。一周的数据对比你的总延迟仪表盘,能让你更了解产品带给用户的真实性能感受。
  2. 挑选一个流式流量最高的产品界面。为其设定明确的 TTFT SLO,并将其记录在产品和基础设施团队都必须查看的地方。将违规视为事故处理。
  3. 对于任何路由到推理模型的界面,在发布路由更改之前,先构建渲染思维功能或异步逃生通道。如果顺序颠倒,你会得到一个无声的 UX 退化,直到两周后参与度下降,才有人注意到。

Token 经济学和模型质量在 LLMOps 复盘中备受关注,因为它们易于衡量且易于讨论。 TTFT 处于基础设施指标和产品指标之间的盲区,而那个盲区正是大多数用户可见的延迟退化所在。消除这个盲区,你会发现,你原本以为的“模型变差了”的报告中,有一半实际上是“我们改变了屏幕保持空白的时间”。第一张要画的图表是你现在还没有的那张。

References:Let's stay in touch and Follow me for more thoughts and updates