AI 回答分成两步
我们和模型的一次对话可以粗略拆成两个阶段。先看这张时间轴第一个阶段是 Prefill它有点像“读题”。当你把 prompt 发给模型时里面可能不只有这一次的问题还包含了系统提示词、上下文、历史对话、工具返回结果、检索到的文档甚至是一整段代码或日志。模型要先把这些输入内容处理完才能准备后面生成回答要用到的中间状态也就是常说的 KV Cache。第二个阶段是 Decode它有点像“写答案”。模型读完输入后才会开始生成回复。但这个回复通常没法一次性全部生成出来而是要一个 token 一个 token 往后写。第 10 个 token 的生成会依赖前面已经生成的 9 个 token第 100 个 token也要接着前面 99 个结果继续往后推。所以一次请求花了多久粗略看就是两部分把前面处理输入的时间加上后面生成答案的时间。Prefill 慢是“迟迟不开始”只要问题发出去对话界面一直空着模型迟迟没开始输出。这段时间一般是模型在处理输入就是 prefill 阶段。在 API 指标中这段等待时间常用TTFT来衡量。TTFT 的全称是Time To First Token是从请求发出到第一个 token 出现之前所消耗的时间。如果你发给模型的 prompt 很长Prefill 阶段就会被拉长。像是让模型读一整篇论文、分析一个代码仓库、总结一大段会议记录或者是 Agent 把大量工具调用结果和历史轨迹都塞进上下文里模型都要先把这些输入处理完才会进入生成回答的阶段。这就是为什么有时候你只让 AI 回答一句话它会让你等很久。因为慢点不在回答的难易而在于你给的输入太长。模型在真正开口之前得花时间把上下文读完了。Prefill 还有一个特点在这个阶段模型已经接收了完整的输入可以把一批 token 放在一起处理也就比较容易把 GPU 算力用起来。但上下文越长开口前要读、要算的内容就越多长 prompt 带来的前置成本会明显增加。因此很多推理优化都会盯着 Prefill 阶段做文章参考prompt caching、prefix caching、chunked prefill。它们要解决的问题是让模型少读重复内容以及更稳地拆超长输入。Decode 慢是“说得很慢”Decode 对应的是另一种慢模型开始回复了但输出速度很慢。这时候你会看到它一个 token 一个 token 往外生成。短回答通常还好但如果你让它写长文、写代码或者生成一份完整分析报告Decode 阶段的时间就会明显变长。原因在于模型生成回答本身是一个顺序过程。它没法直接跳到最后一句也没法一次性把整篇内容全部算完。前一个 token 生成出来之后后一个 token 才能接着往下生成。所以Decode 阶段的耗时和输出长度有关系。让模型回答 50 个 token和让它回答 2000 个 token体验一定不一样。因此即使输入很短只要输出很长总处理时间也会被拉长。在 API 指标中Decode 常常会对应 TPS也就是 tokens per second表示模型每秒能生成多少 token。用户看到的模型“打字速度”和这个指标有关。两种不同的慢理解 Prefill 和 Decode 之后我们就能清楚地判断一次 AI 请求到底慢在哪了。如果你给了很长的上下文但只需要一个很短的答案慢点通常更偏向 Prefill。举个例子“请根据这份 10 万字资料告诉我里面有没有提到项目 A。”这种请求可能要等模型一会它才会开始输出。但一旦模型开始回答回复的内容就会很快结束。因为它真正耗时的地方是模型在开口前要处理大量输入。反之你的问题很短但让模型生成的回复很长慢点会偏向 Decode。举个例子“帮我写一篇 30,000 字文章。”这种请求可能很快就开始输出但完成生成会花很多时间。因为模型要沿着前面的内容一个 token 一个 token 往后生成输出越长Decode 阶段拖得越久。其实还有一种情况是两边都慢。举个例子你让 Agent 读取大量工具调用结果再生成一份完整报告。前面的长输入会增加 Prefill 压力后面的长报告又会拉长 Decode 时间。这就是为什么很多 Agent 任务看起来比普通聊天更慢。因为它的上下文更长要处理的步骤更多最后还要给出更完整的回答。长上下文让事情慢上加慢现在很多模型都在强调长上下文几十万 token、上百万 token 的上下文窗口不再稀奇。但上下文变长并不代表模型读取这些内容是免费的。上下文越长Prefill 阶段要处理的输入就越多生成出来的 KV Cache 也就越大。KV Cache 本身会占用显存后续进入 Decode 阶段时模型每生成一个新 token也还要不断利用这些缓存。因此长上下文带来的影响不只发生在输入阶段也会延续到输出阶段。所以在实际工程中通常不会把所有内容一股脑塞进 prompt。无论是 RAG、上下文压缩、记忆筛选还是工具结果清理其重点都是控制模型每次要读取的内容减少不必要的输入和缓存负担。对 Agent 来说这一点尤其关键。如果每一步都带上完整历史、所有工具返回和全部中间过程模型看起来拿到的信息是多了但延迟和成本跟着上升了。比较合理的做法是保留必要上下文把可复用、可缓存、可摘要的内容整理好让模型少读冗余信息。只改善“开始速度”的优化有些优化可以让模型更快地开始回答但对后续的输出速度帮助有限。prompt caching 就是这种。如果一段系统提示词、工具说明或固定模板经常重复出现服务端就可以复用之前处理过的前缀减少 Prefill 阶段的重复计算。这样一来模型开口前的等待时间会缩短首个 token 也会更快出现。不过模型进入 Decode 阶段之后仍然需要一个 token 一个 token 往外生成。缓存可以减少“读题”的重复成本但不能让一篇长回答瞬间生成完。所以当你看到某个模型或服务强调“缓存命中后延迟降低”时要看它主要在优化哪个阶段。很多时候它改善的是 TTFT就是模型开始输出前的等待时间。要想提高输出阶段的速度就涉及另一种优化speculative decoding、批处理调度、KV Cache 管理、模型结构优化和推理引擎优化。这些优化关注的是 Decode 阶段目标是让模型更高效地生成 token。一个简单判断方法简单判断就看一点AI 是迟迟不开口还是开口之后写得慢。如果很久没有开始回复问题多半出在 Prefill也就是模型还在处理输入如果开始回复很快但后面生成很慢问题多半出在 Decode模型还在逐步生成输出。前者更接近TTFT看的是多久出现第一个 token后者更接近TPS看的是开始输出后每秒能生成多少 token。所以“AI 回答慢”要先拆开看慢在输入还是慢在输出。下一次看到 AI 卡住时先看它卡在哪