串行工具调用瀑布:Agent循环中隐藏的延迟税
如果你曾剖析过一个莫名其妙跑得很慢的AI Agent,大概率会发现一个瀑布。Agent调用工具A,等待,再调用工具B,等待,再调用工具C——即便B和C根本不依赖A的结果。你为1倍的工作量付出了3倍的延迟。
这个模式并非边缘情况,而是几乎所有Agent框架的默认行为。模型在单次响应中返回多个工具调用,执行循环则逐一按顺序运行它们。修复并不复杂,但前提是要有一种可靠的方法来识别哪些调用真正相互独立。
如果你曾剖析过一个莫名其妙跑得很慢的AI Agent,大概率会发现一个瀑布。Agent调用工具A,等待,再调用工具B,等待,再调用工具C——即便B和C根本不依赖A的结果。你为1倍的工作量付出了3倍的延迟。
这个模式并非边缘情况,而是几乎所有Agent框架的默认行为。模型在单次响应中返回多个工具调用,执行循环则逐一按顺序运行它们。修复并不复杂,但前提是要有一种可靠的方法来识别哪些调用真正相互独立。
黑色星期五的流量峰值来了。传统 API 服务的应对方式是启动更多容器。60 秒之内,你的容量就扩充到三倍。自动扩缩容器做了它一贯的事,你安然入睡。
但如果用同一个自动扩缩容器跑 LLM,结果就大相径庭了。新的 GPU 实例要在四分钟的模型权重加载之后才能上线。等那时候,你的请求队列已经塞满,现有 GPU 在半途生成的请求的内存压力下颠簸挣扎,用户盯着转圈圈的加载动画发呆。增加更多算力没有任何帮助——瓶颈根本不在你以为的地方。
AI 推理负载打破了让响应式自动扩缩容在传统服务中奏效的大多数假设。理解其中的原因,是构建能够扛住流量峰值的系统的前提。
你的 GPU 监控面板正在欺骗你。利用率显示 60%,推理集群看起来健康无虞。用户却在经历 8 秒的首 Token 时间(TTFT)。值班工程师检查内存——正常。计算——正常。然而队列在增长,延迟在飙升。这就是将传统容量规划应用于 LLM 工作负载时会发生的事:你信赖的指标指向了错误的地方,真正的瓶颈在用户开始抱怨之前一直不可见。
根本问题在于:LLM 消耗的是一种本质上不同的资源。CPU 服务交换的是计算和内存。LLM 服务交换的是 Token——而 Token 的行为与请求截然不同。
你将昂贵的 LLM 换成了更快、更便宜的蒸馏模型。延迟增加了,成本上升了,质量下降了。你感到困惑并回滚了版本,因为你刚刚花了三周时间做的优化工作反而让一切变得更糟。
这并非假设。这是生产环境 AI 系统中最常见的失败模式之一,它源于一个诱人但错误的心理模型:优化某个组件就能优化整个系统。
你正在运行一个由 LLM 驱动的应用,你的 p99 延迟为 4 秒。你已经优化了提示词,减少了输出长度,并切换到了流式传输。但这个数字几乎没变。问题不在于你的代码——而是在你无法控制的黑盒内部运作的物理学和排队论。
每个推理服务商在你的第一次 API 调用之前,就已经通过数十项架构决策决定了你应用的性能上限。KV 缓存淘汰策略、连续批处理(continuous batching)调度、分块预填充(chunked prefill)块大小——文档中没有提到这些,你也无法配置,但它们决定了你不得不面对的延迟和成本曲线。
这篇文章将解释推理基础设施内部究竟发生了什么,为什么它会产生不可避免的延迟底线,以及你真正能做的少数几件事。
大多数团队决定使用端侧 LLM 推理的方式,就像他们决定重写数据库时一样:冲动行事,仅仅是为了应对原本可以用更廉价方案解决的问题。推介词总是令人心动——无需网络往返、完全隐私、零推理成本——而且初始原型也验证了这一点。然而,在发布六个月后,模型开始悄无声息地输出更差的结果,新的操作系统更新打破了量化兼容性,而那些使用廉价安卓手机的用户正在运行一个你无法推送更新的版本。
本指南旨在让你在看清现实的情况下做出决策。在特定场景下,端侧推理确实是正确的选择,但其成本结构与团队预期的不同,且生产环境中的失效模式与云端 LLM 部署几乎完全不同。
大多数 AI 工程团队都有着相同的故事。他们从一个真正需要 LLM 的难题开始。然后,一旦 LLM 基础设施到位,每一个新问题在他们眼中都成了那把锤子下的钉子。六个月后,他们甚至在调用 GPT-4o 来检查电子邮件地址是否包含 “@” 符号 —— 并且还在为此付费。
这种 “直接用模型” 的本能反应现在是 AI 应用中不必要的复杂性、虚高成本和脆弱生产系统的主要驱动力。这并不是因为工程师们粗心大意。而是因为 LLM 确实令人印象深刻,工具链降低了使用门槛,而且一旦你构建了 LLM 流水线,增加另一次调用感觉成本极低。事实并非如此。
你的 AI 功能上线了。在预发环境中,响应时间看起来还不错。一周后,生产环境开始出现神秘的 p99 尖峰——在中等负载下,延迟从 800ms 飙升至 8 秒,而 GPU 压力正常,模型没有报错,也找不到明显原因。你扩容了更多副本,没有改善。你对模型服务做了性能剖析,没有问题。你加了缓存,还是没用。
最终,有人查了数据库连接池的等待时间。从第三天起,它的利用率就已经高达 95%。
这是 AI 生产事故中最常见的一类,却鲜有人谈及——因为连接池耗尽的表现很像模型变慢。症状出现在错误的层级:你看到的是 LLM 调用延迟高,而不是数据库查询慢,所以定位问题往往需要数天,而用户一直在忍受降级的响应。