延迟优化方案

AI 应用的延迟问题,不能只用“模型响应慢”解释。

用户感受到的等待时间,可能来自首字慢、完整生成慢、工具调用慢、检索慢、排队慢、网关超时、前端没有状态反馈,或者 fallback 没有及时触发。一个 12 秒完成的回答,如果 1 秒内开始流式输出,用户可能觉得可以接受;一个 4 秒完成的回答,如果前 4 秒没有任何反馈,用户可能以为系统卡住了。

延迟优化的关键,是把“首字时间”“完整时间”“可交互时间”“任务完成时间”分开看。

场景

在一个数据分析助手里,运营同学输入:

帮我看一下上周新用户留存下降的原因,按渠道拆一下,并给我三条运营建议。

系统需要做几件事:

  • 理解问题并生成查询计划。
  • 调用数据仓库查询留存、渠道和活动数据。
  • 等待查询结果并做聚合。
  • 让模型解释异常、生成建议。
  • 把结果以图表说明和文字摘要返回。

用户期望很明确:如果只是普通问答,几秒内应该有反馈;如果需要跑查询,可以等几十秒,但必须知道系统正在做什么。最糟糕的体验不是“慢”,而是不知道慢在哪里,也不知道是否会成功。

这个场景里,延迟有多段:

  • TTFT:用户从提交到看到第一段模型输出或状态更新。
  • 工具延迟:数据仓库、业务 API、检索系统的响应时间。
  • 队列延迟:高峰期等待 worker、模型配额或数据库连接。
  • 生成延迟:模型完整输出所需时间。
  • fallback 延迟:主路径失败后多久能切换到降级方案。

如果系统把所有步骤塞进一个同步 HTTP 请求,用户只会看到 loading。更合理的方式是把任务状态、流式输出、工具进度和降级路径都显式设计出来。

问题类型

延迟问题可以拆成五类。

问题类型常见表现主要影响
TTFT 慢用户提交后长时间无首字或状态感知卡顿,重复点击,放弃任务
完整生成慢首字快但长时间输出不完用户无法及时使用结果
工具延迟检索、数据库、外部 API 慢模型等待,链路不稳定
队列延迟高峰期请求堆积、worker 不足、供应商限流尾部延迟变长,超时上升
fallback 慢主模型或工具失败后才长时间重试用户等待后仍失败

不同 AI 任务对延迟的要求不同。

任务延迟敏感点程序应该处理人工确认
改写 / 翻译TTFT 和完整生成streaming、短输出、超时对外发布前确认
客服回复TTFT、工具查询、引用生成状态提示、工具 timeout、fallback涉及承诺或赔付
数据分析工具延迟、队列、任务状态异步任务、进度、结果缓存关键业务结论
代码助手首字、文件读取、测试执行分阶段输出、工具日志、取消自动修改或提交
自动化流程队列、工具延迟、失败恢复状态机、幂等、人工队列写入和不可逆操作

模型适合生成解释、分阶段说明和基于结果总结。系统必须负责超时、排队、取消、流式协议、工具并发和 fallback。

收益和成本判断

延迟优化的收益包括:

  • 用户更早知道系统在工作,重复点击和放弃减少。
  • 核心工作流不会被长时间阻塞。
  • 高峰期成功率提升,尾部延迟降低。
  • 工具慢或供应商失败时可以及时降级。
  • 通过队列和优先级保护关键任务。

成本包括:

  • streaming 需要前后端协议、状态管理和中断处理。
  • 队列和异步任务会增加任务状态、恢复和用户通知成本。
  • 工具并发和 timeout 需要更复杂的错误分类。
  • fallback 需要模型选择、质量评估和降级文案。
  • 过度拆分链路会让调试和一致性变难。

判断是否值得优化,要区分两种延迟:

延迟类型用户感受优先策略
感知延迟用户是否知道系统开始工作TTFT、streaming、进度状态
实际完成延迟用户多久拿到可用结果工具优化、队列、缓存、模型选择

很多产品先优化感知延迟就能显著改善体验。只有当实际完成时间影响业务吞吐、SLA 或高峰稳定性时,才需要更重的 infra。

方案阶梯

延迟优化可以从用户感知到系统吞吐逐级推进。

TTFT

TTFT 是 Time To First Token,也就是用户提交请求后看到第一段输出的时间。对聊天、写作、客服、代码补全这类交互,TTFT 往往比完整耗时更影响感知。

优化 TTFT 的方式:

  • 请求进入后立即返回任务状态或开始流式连接。
  • 把慢工具调用放到模型首段说明之后,或先展示“正在查询”状态。
  • 减少首轮 prompt 组装的同步操作。
  • 优先调用响应快的模型处理低风险首段。
  • 避免在首字前做非必要日志、格式化、完整检索和长链路工具调用。

TTFT 不是欺骗用户。首段内容不能假装已经完成查询。可以展示状态、计划或已知信息,但必须区分“正在处理”和“已有结论”。

Streaming

Streaming 的价值是让用户边看边判断,而不是等完整结果。

适合 streaming:

  • 长文本生成。
  • 客服回复草稿。
  • 代码解释和修改说明。
  • 数据分析的阶段性解读。
  • 多步骤任务的进度和日志。

不适合只靠 streaming:

  • 输出必须一次性校验通过才可展示。
  • 结果依赖工具最终返回,前面不能先下结论。
  • 高风险答案必须经过人工确认。

streaming 需要明确事件类型。不要只有纯文本 chunk,最好区分 statustokentool_starttool_resultwarningerrordone,这样前端才能正确展示状态。

队列

队列用于处理高峰期、慢任务和上游限流。

适合进入队列:

  • 数据分析、报告生成、批量总结。
  • 需要多个工具调用的任务。
  • 可异步完成并通知用户的任务。
  • 高峰期可以延后执行的低优先级任务。

不适合排长队:

  • 用户正在输入时的补全。
  • 客服实时沟通中的短回复。
  • 需要立即反馈的交互动作。

队列设计要包含优先级、超时、取消、重试、任务状态和结果保存。否则队列只会把“接口慢”变成“用户不知道排到哪里”。

工具延迟

很多 AI 应用的慢不在模型,而在工具。

工具延迟治理包括:

  • 给每个工具设置明确 timeout。
  • 可并行的查询并行执行。
  • 对慢查询做缓存或预计算。
  • 工具返回字段做裁剪,减少后续模型输入。
  • 外部系统慢时使用熔断和降级。
  • 写入类工具超时后先确认状态,避免重复执行。

工具结果还会影响模型延迟。一个 2 秒返回的巨大 JSON,可能让模型再花更多时间阅读和生成。工具优化既要看工具耗时,也要看工具结果带来的 token 成本。

Fallback

fallback 的目标是在主路径不可用或太慢时,让系统有可解释的降级。

常见 fallback:

  • 主模型慢或失败:切换备用模型。
  • 强模型排队:先用轻量模型生成草稿,再标记可升级。
  • 工具超时:返回已有信息、提示缺失数据或转人工。
  • 检索失败:追问用户、使用缓存结果或暂不回答事实问题。
  • 长任务超时:转异步任务,完成后通知。

fallback 要有时间预算。例如主模型 8 秒无首字就切换,工具 5 秒无结果就返回部分状态,整体任务 30 秒未完成就转异步。没有预算的 fallback 往往只是“等很久以后再失败一次”。

什么时候简单优化足够

以下情况通常先用简单策略:

  • 输出只是草稿,用户可以等待几秒。
  • 没有慢工具或外部系统依赖。
  • 并发不高,高峰期不明显。
  • 失败后用户可以手动重试。
  • 主要问题是用户看不到进度。
  • 完整结果不需要进入下游系统。

这时可以做:快速状态反馈、streaming、合理 timeout、前端停止按钮、基础错误提示和 TTFT 监控。

什么时候需要 infra 方案

以下情况需要更完整的延迟 infra:

  • 高峰期 p95 或 p99 延迟影响核心流程。
  • 存在慢工具、数据仓库、外部 API 或长任务。
  • 用户需要跨页面查看任务状态和结果。
  • 请求会触发写入、审批、通知或自动化流程。
  • 供应商限流或不可用会影响业务连续性。
  • 需要不同用户、任务和客户的优先级。
  • 需要按 SLA 监控 TTFT、完整耗时和失败率。

这时要引入任务队列、状态机、优先级、异步通知、fallback、trace 和告警。

方案选型表

场景条件推荐方案不推荐方案判断理由额外成本
用户只是觉得“没反应”快速状态 + TTFT 监控 + streaming先重构后端队列感知延迟是首要问题前端状态和流式协议
长文本生成慢streaming + 输出长度约束等完整结果一次性返回用户可以边看边编辑chunk 状态和中断处理
工具查询偶发慢工具 timeout + 并发 + 缓存模型无限等待工具工具慢会拖垮整轮对话工具封装和错误分类
数据分析或报告生成异步队列 + 任务状态 + 完成通知单个 HTTP 请求同步等待长任务需要恢复和进度队列、状态存储、通知
高峰期请求堆积优先级队列 + 限流 + 降级所有请求同等重试关键任务需要被保护容量规划和策略配置
主模型首字不稳定模型 fallback + 时间预算等主模型直到网关超时早切换比长等待失败更好路由、质量评估、提示
高风险输出完整校验后展示 + 状态进度未校验内容直接流式展示错误早展示会误导用户校验、审核和延迟解释
写入工具超时查询执行状态 + 幂等 + 人工确认直接重试写入避免重复副作用工具状态和审计

反模式

第一种反模式:只看平均延迟。

AI 产品更容易被 p95、p99 和超时伤害。平均 3 秒但 5% 请求超过 30 秒,用户仍会觉得系统不可靠。

第二种反模式:把 streaming 当成万能加速。

streaming 改善感知延迟,但不会让工具更快,也不会解决队列堆积。对于必须完整校验的高风险输出,过早展示反而有风险。

第三种反模式:所有步骤都同步执行。

检索、慢查询、模型生成、工具写入都放在一个请求里,任何一段慢都会让用户卡住。长任务应该有任务状态和异步结果。

第四种反模式:工具没有 timeout。

模型等工具时,用户只看到助手卡住。每个工具都应该有 timeout、错误类型和降级路径。

第五种反模式:队列没有用户可见状态。

队列能保护系统,但如果用户不知道任务是否排队、正在执行还是失败,体验仍然很差。

第六种反模式:fallback 没有时间预算。

主模型等 25 秒失败,再切备用模型等 20 秒,最后用户等到的只是更晚的失败。fallback 必须按阶段设置触发时间。

第七种反模式:重试和降级不区分任务风险。

低风险草稿可以快速重试,高风险写入不能盲目重试。延迟优化不能绕过幂等、权限和人工确认。

工程清单

  • 场景边界:哪些任务需要实时交互,哪些可以异步。
  • 指标拆分:是否记录 TTFT、完整耗时、工具耗时、排队耗时、fallback 耗时。
  • 百分位监控:是否监控 p50、p95、p99,而不是只看平均值。
  • 状态协议:前端是否能展示 received、queued、running、streaming、failed、done。
  • Streaming:事件类型是否区分文本、状态、工具开始、工具结果、错误和完成。
  • 工具治理:每个工具是否有 timeout、并发、缓存、错误分类和结果裁剪。
  • 队列策略:是否有优先级、取消、重试、过期、死信和任务恢复。
  • Fallback:模型、工具、检索、上下文和长任务失败时是否有时间预算。
  • 用户体验:慢任务是否展示进度、可取消、可稍后查看或转人工。
  • 幂等安全:写入类工具延迟和重试是否避免重复副作用。
  • 成本控制:加速策略是否放大 token、重试或并发成本。
  • 回放复盘:是否能按 trace 重建每段耗时和失败点。

小结

延迟优化不是把所有请求都做得更快,而是让用户在关键时刻更早得到可信反馈,让系统在慢任务和高峰期保持可控。

早期功能通常先做 TTFT、streaming、状态反馈和工具 timeout。只要任务进入慢工具、长报告、高峰并发、写入动作或 SLA 场景,就需要队列、状态机、fallback 和全链路 trace。

好的延迟设计会诚实地告诉用户:系统开始了、卡在哪里、还能等多久、失败后怎么办。这比单纯追求一个漂亮的平均耗时更可靠。