一套由非工程负责人用 Claude Code 快速上线的 SaaS,被工程师接手后,先在账单上露了馅:某一天的 AI 费用,约占整月 LLM 账单一半,还高过整月服务器成本。

反常点不在“用户突然特别爱用 AI”。原文披露,异常来自同一租户的一批重型批处理任务,被任务队列重复执行了 21 次。

更要命的是,LLM API 调用本身都成功返回,也都产生了计费。失败发生在后面:结果写入数据库时,生产库缺少新字段,任务报 500,然后被队列自动重试。

这类事故看起来像账单问题,底层其实是工程边界问题:成功的外部调用,被一次确定性数据库错误反复作废。

账单为什么会被放大:成功调用被丢弃了

这条链路很短,也很典型。

批处理先调用多个 LLM,拿到结果后写库。新代码已经上线,但数据库迁移没有跟上。生产库缺字段,写入失败,任务返回 500。

队列看到 500,就按策略重跑。可前面的 LLM 调用已经完成,供应商不会因为你的数据库没写进去就退费。

下一轮重跑时,系统又没有 item 级状态,也没有跳过已完成内容。于是整批任务从头再来。一次成功调用,变成 21 次成功计费。

环节实际发生了什么为什么会烧钱该下的判断
LLM 调用调用成功返回每次重跑都会重新计费不是 LLM API 失败重试
数据库写入缺少字段,写入失败成功结果无法落库故障是确定性的
队列策略500 自动重试同一批任务跑了 21 次稳定性机制放大成本
批处理设计没有幂等跳过不能复用已完成结果重跑变成重复扣费

我更在意的是“成功之后失败”这个细节。

传统后端任务重试几次,主要消耗自己的 CPU、队列和数据库。LLM 应用不一样。只要外部模型调用成功,成本已经发生。后面的保存失败,不会撤销前面的账单。

这就是 LLM 后端最容易低估的地方:重试不再只是可靠性工具,也可能是账单放大器。

这不是低代码的锅,但快速上线会放大老问题

原文提到,这套 SaaS 由非工程负责人用 Claude Code 快速上线。这个信息容易被读歪,好像事故的原因是“非工程人员写了生产系统”。我不太买账。

根因更具体:代码先于数据库迁移上线,队列对 500 自动重试,批处理缺少幂等跳过机制。三件事叠在一起,才把一次确定性错误放大成成本事故。

AI 编程工具降低了做功能的门槛,但没有替你取消生产系统的旧规矩。数据库迁移、任务队列、幂等、回滚、告警,这些东西还是要有人兜底。

支付系统早就吃过这类亏。Stripe 这类 API 支持 Idempotency-Key,就是为了避免网络抖动或重试造成重复创建对象、重复扣款。LLM 调用不是支付,但在工程上已经很接近“成本型副作用”。

它一旦成功,就会落到账单上。

对接手这类系统的技术负责人,现实动作会很具体:

  • 先暂停或限流高成本批处理,不要等月底账单再复盘。
  • 延后上线依赖新表、新字段的大任务,确认迁移先完成。
  • 把 LLM 调用从“普通函数调用”改成“有成本、有状态、可中止的外部操作”。

对负责 LLM 后端的工程师,优先级也很清楚:先查队列重试,再查幂等,再查账单归因。不要只盯接口错误率。这个案例里,接口错误率未必能告诉你钱正在被重复花掉。

限制也要说清楚。目前原文只确认单一租户的一批任务被重复执行 21 次,不能把它写成全站事故,也不能推断公司规模、具体损失金额或云厂商问题。

证据能支撑的结论是:一批高成本任务,在确定性故障下被自动重试放大了。

这已经足够值得警惕。

接下来该观察什么:三道闸有没有补上

这类事故修不修得住,别只看一句“我们已经修复”。要看三道闸有没有补上。

观察变量应该看到什么没有的话会怎样
重试边界确定性错误进入失败队列或人工处理字段缺失、权限错误会继续烧钱
幂等记录item 级状态、结果缓存、已完成跳过批处理重跑时重复调用 LLM
成本监控按租户、任务、环境拆账和告警只能在月度账单里发现损失

确定性错误不该无限重试。column does not exist、参数格式错误、权限错误,这些都不是“等一等就会好”的问题。指数退避解决不了 schema 没迁移。

成本型任务也要能去重。批处理至少要记录到单个 item:哪些已调用,哪些已保存,哪些失败可重试。必要时,LLM 结果应该先落到可恢复位置,再进入后续写库流程。

部署顺序更不能省。依赖新字段的代码上线前,数据库迁移要先完成。若必须灰度,也要保证旧字段和新字段可以短期共存。

成本监控要按租户、任务和环境拆开。生产密钥和测试密钥分离,单任务费用上限,异常 token 消耗告警,都不是锦上添花。它们是止损装置。

接下来最该看的变量,其实只有两个:一是队列能不能识别“不可重试错误”;二是每次 LLM 调用能不能被追踪到具体租户、任务和业务对象。

如果这两点没有,团队就只能在账单里看事故的残影。

开头那张反常账单,真正暴露的不是用户多用了 AI,而是系统不知道一次成功调用已经花过钱。服务器时代,重试多半是在买稳定;LLM 时代,重试无界,就可能是在重复付款。