跳到主要内容

重试并非免费:大模型重试策略的 FinOps 数学逻辑

· 阅读需 12 分钟
Tian Pan
Software Engineer

我在上季度接触的一个团队在他们的推理账单上发现了一笔 4200 美元的条目,没人能解释其来源。控制面板显示的流量正常,延迟图表也很平稳。原因最终被发现是一个 Agent 陷入了长达 6 小时的“礼貌”重试循环中,它不断地通过指数退避(最高限制为 30 秒后重启)来重放一个包含 4 万个 Token 的工具链。这套重试策略是直接从 2019 年为基于 HTTP 的 JSON 服务编写的内部 SRE 手册中照搬过来的。它运行得非常完美——只是用错了系统。

这就是那种不会出现在容量规划表中的账单。行业标准化的无状态 REST API 重试策略模式默认了三个前提,而 LLM 工作负载在悄无声息中违背了这些前提:故障是瞬时的、单次额外尝试的成本是有限的,以及重试有合理的成功机会。每一个前提曾是关键的支撑,而现在每一个都是错的。这种成本模型从未捕获的偏差,正潜伏在每一份月度账单的底部。

那些还没有根据 Token 经济学重建重试策略的团队,正在缴纳一种隐形税。这种税收随着你本就最担心的查询难度而增加——那些长文本、Agent 类以及带有深层工具链的查询。在 LLM 技术栈中,经典韧性工程提供给你的安全网,反而成了勒紧脖子的绞索。

LLM 工作负载打破的三个经典假设

重试策略作为一门学科,是围绕无状态 REST API 和幂等 RPC 成熟起来的。其思维模型假设:请求是一个固定成本的工作单元,故障通常是网络抖动或瞬时的后端故障,重试的成本大约是一个额外的单元,且第二次尝试具有独立的成功概率。这套逻辑之所以有效,是因为其中的每个变量都拥有稳定的分布。

LLM 调用违反了所有这三点。请求的成本不是一个固定单元——它是输入 Token、输出 Token、缓存命中率、推理深度和工具调用递归的函数,其中每一项在每次调用中都可能有数量级的差异。故障很少是网络抖动;它更多时候是格式错误的 JSON 字段、拒绝补全、工具返回了错误的形状,或者是耗尽了步骤预算的推理循环。而且,第二次尝试的成功概率与第一次并非相互独立——产生过畸形 Schema 的模型与再次产生畸形 Schema 的概率高度相关,因为模型所响应的输入并没有改变。

在这里,成本公式至关重要。一个合理的单次请求账单粗略模型是乘法关系:基础 Token × 缓存倍率 × 批处理倍率 × 推理倍率 × 重试倍率。重试项并不是在稳定账单之上添加的固定填充;它会乘以后面的每一项,这就是为什么配置错误的重试会让月度账单翻三倍,而不是仅增加 5%。如果团队将重试预算设为固定 5–15% 的流量增量,那是锚定了错误的成本模型——这个数字对于稳态行为来说是一个不错的启发式起点,但它无法限制长尾成本。

对于最需要重试的输入,重试成本也最高

LLM 重试经济学中隐藏的残酷之处在于,成本放大效应在你最不想放大的输入上最为显著。一个简短、格式良好的 Prompt 配合单次补全很少失败,且重放成本低廉。而一个带有 8 次工具调用、6 万个 Token 上下文窗口和深层推理链的长 Agent Prompt 则更容易失败——而一次重试会以全额 Token 成本重放整个链条,还包括由新尝试中稍微不同的前缀导致的任何缓存失效。

如果你的重试策略是无条件的(“失败时,重试最多 N 次”),那么重试带来的边际 Token 支出就会向你分布中最昂贵的请求倾斜。那 5–15% 的表面流量增长,在长尾输入上会演变成 30–50% 的账单涨幅。那些基于中位数输入基准测试每个任务成本的团队,现在正以完全不同的价格服务 P99 的输入,而汇总每日平均值的控制面板在月底账单寄到之前,根本无法发现这种偏离。

Agent 场景下的情况更为严峻。工具调用循环中的失败步骤通常会回溯到上一个一致的状态并从那里重放——这意味着重试成本不仅仅是一次额外 LLM 调用的成本,而是回溯之前所有工具调用和推理步骤的成本。我认识的一个团队发现,他们的一种失败模式的成本是正常路径的 4 倍,因为重试边界设置在了 Agent 循环处,而不是失败的子步骤处。他们一直以为重试只是 LLM 账单上的一种税;实际上,这种税征收在了每一个被回溯作废的上游工具调用上。

同样的 Prompt,同样的失败:语义相关性问题

另一个破碎的假设是统计学上的。经典的重试数学假设第二次尝试具有独立的成功概率——独立意味着失败是由请求本身之外的因素(网络、容量、瞬时过载)引起的。对于 LLM,失败通常是由请求本身引起的:一个在第一次尝试时误导模型产生畸形 JSON 的 Prompt,在第二次尝试时极有可能再次产生畸形 JSON,因为 Prompt 没有任何改变。对 Agent 循环的实证分析发现,对于结构性故障,“重试即可解决”的比例低至 20% 左右,其余的预算都浪费在了产生不同但依然失败的输出上。

这种故障模式让天真的重试策略看起来最理性,实则最无效。第一次尝试失败。重试运行。重试以不同的方式失败——这种不同足以让停滞检测器无法察觉,但又不足以让下游解析器接受。Agent 在产生同一个失败的各种变体中耗尽了重试预算,其成本表现为没有任何进展的计算支出。不改变输入的重试没有理由获得不同的结果,将温度噪声(Temperature Noise)当作重试策略,本质上只是将确定性转化为账单的一种方式。

真正关键的区别在于瞬时故障(供应商 503、频率限制 429、网络超时——此时重试具有独立概率)和语义故障(格式错误的输出、工具形状不匹配、拒绝访问——此时不改变输入的重试与自身高度相关)。经典的重试策略将两者统一视为“失败,再试一次”。LLM 重试策略必须区分它们,因为这两者的单次尝试成本数学模型和解决概率完全不同。

重塑令牌机制的重试预算模式

这种让成本可预测性回归的模式(经典重试策略曾假定这种预测性存在)由四个核心组成部分组成。大多数团队拥有一到两个,但很少能集齐全部四个。

单次请求和单次会话的令牌上限。 在进行任何重试之前,为该逻辑工作单元设定总令牌消耗的硬上限。该上限在会话边界而非仅仅是请求边界强制执行,因此无论失控的智能体 (agent) 循环发出了多少个子请求,都会触碰上限。这在机制上等同于成本维度的熔断器。预执行策略的强制执行至关重要,因为另一种选择——在发票上才发现成本激增——正是该模式要防止的故障模式。

重试时回退到更廉价的模型。 如果在边缘模型 (frontier model) 上的首次尝试失败,重试不应是对同一模型的原样重放——它应该回退到更低廉的层级,或者采用结构完全不同的提示词。经济逻辑很直接:边缘模型的重试成本与原始调用几乎相同,而如果原始调用是因为非瞬时性原因失败的,那么重试只有 20% 的概率能解决问题。廉价模型的重试成本仅为原始调用的零头,并能吸收由于模型过度自信而非能力上限导致的失败。对于供应商侧的停机,回退策略是彻底切换到另一个供应商,并配合熔断器将故障供应商移出轮询,进入冷却期。

语义故障分类器。 重试决策不是“调用是否失败”,而是“调用是否以重试能解决的方式失败”。429 或 503 错误表示“是”;格式错误的 JSON 或拒绝回答则表示“可能不是”,至少在不改变输入的情况下不是。分类器通常是几行匹配错误类型和输出形状的代码,其任务是决定重试、修改后重试(使用包含验证错误的修正提示词),还是快速失败。修改后重试路径——将解析器错误反馈给模型——是经验性获益点所在,因为它实际上改变了模型响应的输入。

重试预算应采用令牌桶模式,而非次数计数。 经典的重试预算是“每分钟 N 次重试”。LLM 的重试预算作为令牌桶 (token bucket) 更为实用:该调用方每分钟最多可消耗 X 个重试令牌。一个 40k 令牌调用的失败完成比一个 2k 令牌调用的失败完成消耗更多的重试预算,这才是正确的逻辑,因为预算试图限制的正是成本放大效应。当桶空了,调用方会进入降级路径——使用缓存响应、简化提示词或人工介入。

如何进行监控以预见账单激增

重试引发的成本飙升之所以表现为月末账单惊吓而非月中告警,是因为标准仪表盘的计量单位错了。QPS 和延迟图表将失败合并为单个计数器。成本放大的重试是不可见的,因为仪表盘显示的是“请求速率”,而账单显示的是“令牌消耗”——而两者之间的关系正是重试风暴所扭曲的变量。

让这一切变得可见的监控指标具有几个不可协商的形式。为每次运行标记结果状态:已接受 (accepted)、已拒绝 (rejected)、已放弃 (abandoned)、超时 (timeout)、工具错误 (tool-error)、重试耗尽 (retry-exhausted)。跟踪故障成本占比——即在非“已接受”结果上产生的月度令牌支出百分比——并在超过阈值时发出告警。将每次重试尝试的成本与首次尝试的成本分开统计,这样重试率的回归就能体现为一条成本线,而不仅仅是一个计数器。此外,要捕捉每个会话和每个租户的重试令牌消耗,因为如果没有这些,一个租户的重试风暴耗尽共享预算导致其他客户抱怨延迟的“吵闹邻居” (noisy-neighbor) 情况将无从察觉。

更深层的组织转变是,重试策略不再是平台团队写完后就束之高阁的东西。成本放大取决于提示词分布、工具调用形状和模型组合——所有这些都会随着每次产品发布而演进。经历过最严重事故的团队会将重试策略视为季度审查的内容,桌子的一侧是成本数据,另一侧是可靠性数据,寻找两者背道而驰的情况。

值得铭记的感悟

2018 年的 SRE 指南正确地指出重试是韧性原语 (resilience primitive)——并且也正确地指出,出错时的成本是有界的。这两句话对于服务向调用方暴露的大多数 API 表面仍然适用。但 LLM 调用点是一个例外,而且这个例外足够大,以至于如果团队不加修改地应用该指南,就会因为站在错误的一边而发现那个边界。

针对 LLM 的重试并不是“再次进行相同的调用”。它是在非均匀成本分布上的概率性重投 (re-roll),其成功概率与前一次尝试的失败相关,且价格标签随输入的难度而缩放。本文中的重试预算模式是为该分布重新设定边界的最低配置。在你需要之前就部署它的团队支付的是一笔小额的重构成本。而在出现 4,200 美元的账单项目之后才部署它的团队,支付的是账单金额加上重构成本。

成本可预测性曾经是重试原语本身的一种属性。现在,它是你构建在其之上的重试策略的一种属性。

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