上个月财务把 API 账单发给我,4,832 元。我当时第一反应是"是不是哪里算错了",因为我们的调用量真的不大——日均 1,000 次左右,一个内部知识问答工具而已。
后来我把日志导出来拆了一遍,发现钱不是均匀花掉的。4% 的超长上下文请求,吃掉了 36% 的成本。 而其中相当一部分,是重复的、可以合并的、甚至根本不需要调模型的。
这篇文章给你三样东西:
我见过太多人上来就改代码——换个便宜模型、砍掉几轮对话,结果账单没降多少,功能倒是坏了。
原因很简单:你不知道钱花在哪,就不知道该砍哪一刀。
不需要 Grafana,不需要 Prometheus。一个 SQLite + 一个 Python 脚本,半小时搞定。
第一步:建表
第二步:包一层调用函数
第三步:跑一个日报
跑出来大概是这样:
=== 近 7 天 === 总调用: 7000 总成本: 1127.00 元 日均成本: 161.00 元 --- 按场景 --- calls cost cost_pct scene long_doc 280 688.0 61.0 normal_qa 2660 304.0 27.0 quick_query 3500 135.0 12.0
看到这个表,你就知道该动哪了。
下面每一个 Prompt 都可以单独用,不需要改代码。
把你现在的 system prompt 丢进去,让它帮你砍。
你是一个 Prompt 优化专家。我会给你一段系统提示词,请你: 1. 删除所有重复的礼貌用语(请、麻烦、非常感谢等) 2. 删除空洞的角色修饰词(非常专业的、经验丰富的、资深的) 3. 合并语义重复的句子 4. 保留所有涉及安全、合规、拒答的指令,一个字都不能删 5. 保留所有输出格式要求 输出格式: - 原文 token 数(估算) - 精简后文本 - 精简后 token 数(估算) - 删除了什么,为什么 待处理提示词: """ {你的提示词} """
我用这个 Prompt 把 1,240 token 压到了 310 token,一次就成。
用来做模型路由,判断一个问题该走小模型还是大模型。
判断下面这个问题的复杂度,只输出一个词:simple、normal 或 complex。 判断标准: - simple:事实查询、格式转换、简单分类,答案短且确定 - normal:需要理解上下文、需要总结或改写 - complex:需要多步推理、涉及金额/法务/医疗、或需要生成代码 问题:{user_question}
配合 max_tokens=5, temperature=0 使用,单次成本几乎为零。
把"一个任务调多次模型"合并成一次。
从下面的文本中提取以下信息,严格按 JSON 格式返回,不要输出任何其他内容: { "todos": [{"task": "", "owner": "", "deadline": ""}], "risks": [""], "decisions": [""], "followups": [""] } 要求: - 没有的信息留空数组或空字符串,不要编造 - 时间统一格式化为 YYYY-MM-DD - 责任人只填姓名,不带职位 文本: {content}
我原来调 4 次,现在调 1 次,成本降 72%。
回答规则: - 直接给结论,不解释推理过程 - 总长度控制在 {N} 字以内 - 如果答案超过 {N} 字,只保留最关键的部分 - 不要用"根据您提供的文档"这类开场白 问题:{question}
我实测下来,平均输出 token 从 620 降到 210。
用来标定缓存阈值,别照抄网上的 0.95。
你是语义相似度标注专家。我会给你一组问题对,请你判断每一对 是否在问"同一件事"(即答案可以互换)。 判断标准: - 同一个问题的不同说法 → 是 - 相关但答案不同的问题 → 否 - 一个是另一个的子集 → 否 输出 JSON 数组,每项包含 index 和 is_same(true/false)。 问题对: {问题对列表}
标 200 条,用不同阈值跑,选准确率 > 98% 的那个。
我标出来的结果:0.95 对应准确率 98.6%、召回 41%。0.92 召回能到 58% 但准确率掉到 93%,出现过把"快排"和"归并排序"判成同一个的错误,不能用。
降级前必须验证,别拍脑袋切。
你是模型效果评估专家。我会给你同一个任务在两个模型下的输出, 请你判断两者在"任务完成度"上是否有实质差异。 判断标准: - 如果两个输出都能正确完成任务,只是措辞不同 → 无实质差异 - 如果新模型的输出遗漏了关键信息、格式错误、或结论错误 → 有实质差异 输出: 1. 结论:有差异 / 无差异 2. 理由(50 字内) 任务输入: """ {原始请求} """ 模型 A 输出: """ {GPT-4o 输出} """ 模型 B 输出: """ {GPT-4o-mini 输出} """
抽 100 条测,差异率低于 5% 就切。我实测意图分类 1.8%、实体抽取 2.1%,都切了。代码生成 11%,没敢动。
同义问题直接返回缓存答案,不调模型。
用 bge-small-zh 这种小模型做 embedding,本地跑,零 API 成本。
效果:调用量 1,000 → 660,成本 161 → 108 元。
这里踩过一个坑:规则匹配是按顺序的,先匹配到的赢。我一开始把 entity_extract 排在 code_generation 前面,结果"提取订单号并生成一个 JSON"被判成实体抽取走 mini,输出的 JSON 少了一层嵌套,前端直接报错。改成复合任务优先之后,差异率从 2% 降到 0.8%。
效果:成本 108 → 52 元。
用 Prompt 1 跑一遍,1,240 → 310 token。
但有一条红线:涉及"不能做什么"的指令一个字不能删。我删过一条"不得提供医疗诊断建议",测试环境跑了两天没事,上线第三天有用户问"我最近头疼,你们这个软件能不能帮我记录症状",模型真的开始给建议了,还说"建议服用布洛芬"。
效果:成本 52 → 34 元。
用 Prompt 3,一个任务一次调用。
判断能不能批,标准不是"是不是异步",是"结果晚 24 小时出来,业务能不能接受"。
我们有个功能是用户上传文档后生成摘要,一开始判断这是异步任务走了批处理。但用户上传完就在页面上等着,24 小时内出结果等于不可用。后来改回实时了。
效果:局部成本降 72%。
流式本身不省 token,但它解决了一个隐藏成本:用户等不及刷新页面导致的重复请求。我们改完之后首字时间从 3.1s 降到 0.6s,重复请求从 8% 降到 0.3%。
效果:成本 34 → 15.4 元,用户中途放弃率 23% → 6%。
把上面五件事整合成一个模块,复制就能跑。
这个模块把缓存、分级、截断、流式全串起来了。你只需要把 MODEL_MAP 里的模型名换成你实际用的,就能跑。
尝试一:把 temperature 调到 0 提升缓存命中率。
想法很直接:让输出确定,同样输入必然同样输出。实际效果一般,回答变得很死板,用户投诉变多,又调回去了。而且命中率只从 34% 涨到 37%,收益远不如预期。
尝试二:自建 7B 小模型替代部分调用。
部署了个 7B 的模型处理意图分类,理论上能省更多。实际跑下来准确率比 mini 低 6 个点,加上 GPU 和运维成本,算总账不划算,放弃了。
结论:API 的规模效应不是自建能比的。除非你的调用量大到能摊薄 GPU 成本,否则别折腾。
手段 | 降本贡献 | 工程量 | 先做哪个 |
|---|---|---|---|
Prompt 精简 | 35% | 半天 | ⭐ 首选 |
语义缓存 | 33% | 2-3 天 | ⭐ 次选 |
模型分级 | 52%(叠加) | 1 周 | 推荐 |
批处理 | 72%(局部) | 3-5 天 | 看场景 |
流式截断 | 29% | 2 天 | 有 C 端必做 |
最终:4,832 元/月 → 461 元/月,降幅 90.5%。
成本优化这件事,最难的从来不是技术,是你有没有认真看过那张账单。
文中模型名称做了脱敏处理,成本按公开定价折算。不同厂商定价差异较大,请以你自己的账单为准。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。