更新于

LLM 成本异常检测


LLM 账单突然上涨,表面上是“调用变多了”,根因却可能完全不同:某个版本把完整对话重复塞进 prompt、失败请求进入无限重试、路由规则误把普通任务切到高成本模型,或者一个租户在短时间批量导入数据。只看每日总额,往往只能在损失发生后确认结果,无法告诉值班人异常从哪里开始。

成本异常检测要解决的不是“今天比昨天贵不贵”这么简单,而是持续判断:当前用量是否偏离了它本应处于的范围,偏离来自哪个维度,是否需要立刻处置。下面给出一套不依赖特定供应商、可以从小规模逐步扩展的工程方案。

一、先区分业务增长与系统异常

成本上涨不一定是事故。注册用户增长、付费客户扩容或批处理任务集中执行,都会带来合理增量。反过来,总成本没有明显变化,也可能藏着严重异常:某个功能成本翻倍,同时另一个功能流量下降,两者在总盘上互相抵消。

因此检测目标不能只有一个全局金额。至少要从四层观察:全站、租户、功能和模型。每层回答的问题不同:

检测层级典型异常判断时需要的上下文
全站总体 burn rate 突升工作日、活动、批任务窗口
租户单客户突发放量套餐、历史峰值、限额
功能新版本单次任务变贵发布版本、prompt 版本
模型路由比例或单价口径变化模型名、路由原因、价格版本

业务增长通常能在请求数、活跃租户数等指标上得到解释;系统异常则常表现为“单位任务成本”或“失败成本占比”突然变化。把总额拆成“任务量 × 单次任务成本”,是排除误报的第一步。

二、原始数据必须能支持回钻

检测算法再复杂,如果输入只有每日账单总额,也无法定位根因。建议每次模型调用生成一条成本事件,至少记录 request_id、时间、租户、功能、模型、输入与输出 token、缓存 token、状态、重试序号、prompt 版本和估算金额。

{
  "request_id": "req_demo_01",
  "tenant_id": "tenant_a",
  "feature": "contract_summary",
  "model": "model_route_standard",
  "input_tokens": 12600,
  "output_tokens": 940,
  "retry_attempt": 2,
  "status": "success",
  "prompt_version": "summary-v17",
  "estimated_cost": 0.084
}

这里的金额只是示例,不代表任何厂商价格。生产系统应让事件关联版本化价格表,并保留原始 token 口径。这样价格配置调整后可以重算历史数据,也能避免把“价格变了”误判成“应用行为变了”。更完整的记账结构可以参考 LLM Token 成本账本设计

三、用多条基线代替一个固定阈值

“每小时超过固定金额就报警”适合早期止损,却很容易在流量周期明显的系统里反复误报。周一上午与周日凌晨、本月结算日与普通工作日,本来就不应该共享同一个期望值。

一个实用的起点是同时维护三条基线:

  1. 短周期基线:最近若干时间窗的移动中位数,用于发现突然跳变。
  2. 同期基线:过去几周相同星期、相同时段的分布,用于吸收业务周期。
  3. 单位基线:每次成功任务或每千次请求的成本,用于区分流量增长与效率退化。

相较均值,中位数和分位数不容易被少量极端值拉偏。团队不必一开始就引入复杂机器学习模型;只要历史窗口干净、维度合理,当前值 > 历史中位数 + 若干倍离散范围 就能覆盖大量真实事故。阈值中的倍数必须用自家历史回放确定,而不是照抄通用数字。

四、分层检测才能兼顾速度与噪声

检测频率越高、切分维度越细,响应越快,但误报和计算成本也会增加。可以采用由粗到细的两级结构:

  • 第一级每几分钟扫描全局和主要业务线,发现 burn rate、单位任务成本或失败成本占比异常。
  • 第二级只对可疑时间窗做租户、功能、模型、版本和重试原因下钻,生成贡献度排名。

例如全站成本抬升 40%,二级分析发现“合同摘要 + prompt v17”贡献了增量的 78%,且请求量只增加 5%,那么值班人应优先检查 prompt 和上下文拼装,而不是先限制全部用户。反之,如果增量均匀分布在多个功能,且成功任务数同步增加,更可能是正常业务增长。

低流量维度尤其需要保护。一个每天只有两次调用的功能,从一次涨到两次就是 100% 增长,却没有统计意义。常见做法是增加最小样本量或最小金额门槛,只有相对偏离和绝对影响同时满足时才通知人工。

五、把异常类型直接映射到排查路径

告警如果只写“成本超过基线”,值班人仍要从零开始查。更有效的方式是由指标组合推断异常类型,并在告警中附上排查入口:

指标组合更可能的原因优先检查
请求数不变,输入 token 上升上下文膨胀prompt 版本、历史消息裁剪
失败成本与重试次数同步上升重试风暴429/5xx、退避与幂等
请求量不变,高成本路由占比上升路由漂移模型路由规则、fallback
单租户成本突升,单位成本稳定客户突发用量配额、批量任务、账号安全
输出 token P95 上升截止条件失效max_tokens、停止序列、工具循环

这类规则不要求百分之百自动判断根因,它的价值是把十几分钟的手工查询压缩为一个明确的调查方向。涉及错误重试时,可结合 LLM API 错误重试策略设计 检查退避、重试上限和不可重试错误分类。

六、告警要包含证据,而不只是严重级别

一条可处置的成本告警,至少应回答五个问题:何时开始、偏离基线多少、预计每小时额外消耗多少、前三个贡献维度是什么、最近是否有版本发布。最好同时给出代表性 request_id,让工程师能直接跳到 trace。

严重级别应由“异常置信度 × 财务影响 × 持续时间”共同决定。短暂小尖峰可以只进观察面板;连续多个窗口异常且额外消耗持续扩大,再升级到即时通知。对于已经确认的活动或批任务,应设置带过期时间的静默规则,避免永久豁免掩盖未来事故。

检测和止损也应解耦:检测器提供证据与建议,预算控制层决定降级、限流还是熔断。具体分级动作可参考 AI API 预算告警与自动熔断,不要让一个噪声较高的实验检测器直接关闭核心链路。

七、上线前用历史回放验证

异常检测不能只靠“上线后看看”。先准备一段包含工作日、周末、发布日和批任务的历史事件,标记已知事故,再回放不同窗口和阈值。评估时同时看召回率、误报次数、平均提前发现时间,以及每条告警能否定位到正确贡献维度。

上线初期建议只记录、不自动处置。每周复盘误报:是节假日周期没建模、业务活动没登记、样本量太小,还是价格版本发生变化。调整完成后再逐步把高置信度规则接入限流或降级。检测规则、基线版本和静默操作都应留下审计记录,便于解释某次事故为什么报警或没有报警。

八、相关阅读

如果你希望先统一多模型调用入口,再按租户、功能和模型沉淀成本事件,YoTradeApi 可以减少不同供应商协议带来的接入与统计口径差异。