为什么一天的人工智能花费超过一个月的服务器?
非工程师用Claude Code快速构建了一个AI功能,但由于数据库列缺失导致确定性失败,自动重试机制使同一任务重复21次,单日AI成本超过整月服务器费用。本文分析了重试风暴的原因并总结了教训。
一位财务总监用Claude Code两天内构建了一个AI功能,而作为工程师的我接手后,在梳理后端代码时发现了一笔惊人的成本:单日AI调用费用竟然超过整个服务器群一个月的开销。
故事始于一张LLM API费用图表。大多数日子成本极低,唯有一天像富士山一样高耸,贡献了当月近一半的账单。起初我以为是开发者当天反复测试功能所致,但深入检查应用日志后发现真相完全不同:同一批任务,被机器自动执行了21次。
问题的核心在于任务流程:它依次调用多个LLM,然后保存结果到数据库。然而,数据库的某个列尚未添加,保存步骤因此抛出“列不存在”错误,返回500。讽刺的是,所有LLM调用都成功了(200状态码),意味着每次调用都产生了账单。相当于吃完大餐付了钱,却在出门时摔倒失忆,回到座位上重新吃一遍,重复21次。
这种“重试风暴”并非源于临时网络故障,而是两个陷阱的组合:第一,部署顺序错误——先部署了依赖新列的代码,后执行数据库迁移;第二,任务队列将500错误视为可重试的失败,自动重新运行。由于任务不具备幂等性(不跳过已处理的工作),每次重试都重新开始,导致完整成本反复产生。
财务总监得知真相后也很震惊:“调用成功了,付了钱,然后结果被扔掉?”对于非工程师来说,这确实难以理解。但这件事暴露了更深层的问题:重试不是万能的善意。确定性失败(如模式不匹配、4xx类错误)不会因重试而解决,必须立刻中止并设置重试上限。带有高不确定性成本的任务(如LLM调用)必须从一开始就实现幂等性。部署顺序应遵循“先模式后代码”,避免临时性错误。此外,如果没有成本监控(如独立密钥、预算告警),这类问题只能在收到账单后才发现。
“氛围编码”确实降低了非工程师构建生产系统的门槛,但理解系统如何出错、如何增加成本仍是另一项技能。两天可以构建功能,但防止“优雅重试”演变成“丢弃成功结果并重复计费”需要更多时间。重试不总是善意——这次经历就是最昂贵的教训。