跳到主要内容

线上 AI 服务的超时策略,我更推荐这三层

· 阅读需 5 分钟
一介布衣
全栈开发者 / 技术写作者

补档说明:本文属于「AI 工程落地周记」系列,计划发布时间为 2025-05-25 11:40。当前先保留为草稿,后续补充真实案例、代码片段和复盘细节后再发布。

如果只拿一个线上场景来说超时策略,我会选“知识问答 + 检索 + 工具调用”的组合请求。

这类请求最容易暴露一个错觉:团队经常以为“只要给 SDK 设一个 30 秒超时就够了”。但真实请求进来之后你会发现,30 秒这个数字根本没有回答任何关键问题:

  • 用户愿意盯着这个页面等多久?
  • 整条链路最多能烧掉多少预算时间?
  • 单个检索或工具步骤慢到什么程度时就该放弃?

当这些问题没有分开,超时就不会是一个边界,而只是一个会随机爆炸的数字。

我们后来把一次请求拆成了三层 deadline

为了让超时真正可控,我们后来把一个请求拆成三层时间边界。

第一层:用户感知 deadline

这是面向前端和产品的。它回答的不是“服务还跑不跑”,而是“用户还能不能接受继续等待”。

举个更真实的例子:

  • 对话页里,用户 6-8 秒没看到有效反馈,体感就会明显变差。
  • 报告页里,20 秒内还可以接受,因为用户预期本来就是长任务。

所以这层的处理通常不是“立刻杀死任务”,而是:

  • 给出明确状态
  • 告诉用户正在处理
  • 必要时切成异步任务

第二层:服务总 deadline

这是后端整条链路的预算。它回答的是:

  • 从接到请求开始,到决定必须放弃为止,最多给这条链路多少时间。

在那条“问答 + 检索 + 工具”的链路里,我们后来大致拆成:

  • 用户 deadline:8 秒
  • 服务 deadline:15 秒
  • 工具 / 检索 deadline:3-4 秒

这样做之后,你就不会再让某个局部步骤无上限地吞掉整条链路。

第三层:步骤 deadline

这是最容易被忽略,但我最想强调的一层。

因为真实链路里最常见的问题不是“整体慢”,而是某一段突然拖死全局:

  • 某次检索卡了 5 秒
  • 某个工具偶发慢 7 秒
  • 某个供应商节点抖动

如果没有步骤级 deadline,系统就只能被动等着某个慢步骤把整条链路拖垮。

一段更接近生产的实现

后来我们的 Node.js 链路大致是这样处理 deadline 传播的:

async function runAiRequest(input: Input) {
const requestStartedAt = Date.now()
const serviceBudgetMs = 15_000

const serviceAbort = AbortSignal.timeout(serviceBudgetMs)

const retrieval = await runWithDeadline(
() => retrieveContext(input, {signal: AbortSignal.timeout(3_000)}),
serviceAbort,
)

const toolResult = await runWithDeadline(
() => callTool(input, {signal: AbortSignal.timeout(4_000)}),
serviceAbort,
)

const llmResult = await runWithDeadline(
() => callModel({input, retrieval, toolResult, signal: AbortSignal.timeout(6_000)}),
serviceAbort,
)

return {
latencyMs: Date.now() - requestStartedAt,
data: llmResult,
}
}

这段代码不是万能模板,但它体现了一个关键点:超时不能只存在于 SDK 配置里,而要沿着整条链路传播。

为什么这三层不能混成一个数字

如果只给一个统一超时,最容易出现 3 种错觉:

1. 用户已经不耐烦了,但服务还在“努力”

从系统视角它还没超时,但从产品视角已经失败了。

2. 整体偶尔慢,团队却不知道慢在什么步骤

没有步骤级 budget,就没有定位能力。

3. 某一层过于保守,提前把可恢复请求打断

如果只有一个数字,通常很难做到既保护用户体验,又不浪费真正还可能成功的请求。

我后来总结出的处理顺序

如果一个 AI 服务开始出现超时问题,我现在会按这个顺序查:

  1. 用户大概在第几秒开始觉得“系统不可信”
  2. 整体链路的预算是否被某一类请求持续打穿
  3. 哪个具体步骤最常拖垮请求

顺序不能反。很多团队一上来就只调 SDK 超时值,最后只是把问题往后拖。

最后给一张可执行清单

只要一个 AI 请求链路上线,我现在都会要求:

  1. 有用户感知层的 deadline
  2. 有服务总预算
  3. 有步骤级超时
  4. 超时后能区分是回退、重试还是转异步
  5. trace 里能看见是哪一层先超了

总结

线上 AI 服务的超时策略,真正有用的不是“把超时设成多少秒”,而是把它拆成用户层、服务层、步骤层三层边界。

这样做的价值,不只是让系统少报错,而是让等待、回退、异步化和问题定位都变得可解释。超时不是一个数字,而是服务如何承认自己边界的一种方式。

  • 读者:关注 AI 应用落地、全栈工程化、工作流自动化和技术内容系统的开发者。
  • 场景:补充 2025 年到 2026 年初这段时间里缺失的技术观察和工程复盘。
  • 目标:不写成新闻转述,而是写成可以复用到项目里的判断框架。