通过模型替换、缓存策略和Prompt压缩等手段,将月均AI API开销从420美元降至28美元,并附具体代码实现。
说真的——上个月我打开 OpenAI 的账单,差点把咖啡喷出来。我每周都在烧掉一大笔钱,却完全不知道钱花到哪里去了。我当时真的以为自己"用 AI 干点事情"是明智之举。结果发现,我基本上是在把钱当纸烧。
问题在于:当你开始用 AI API 搭建东西时,没人告诉你的事——所有人默认使用的模型,在你实际处理的 90% 事情上,贵得离谱。更糟糕的是?你根本注意不到,因为回复看起来挺正常的。只有账单来的时候你才会注意到。
我花了几个星期拆解我的整套方案,换模型、加缓存、压缩 prompt,全方位优化。说实话,效果简直离谱。从每月大约 420 美元降到了大约 28 美元。同样的产品,同样的质量,只是更聪明的选择。
这是我把学到的东西、实际在用的代码、以及一路上犯过的蠢错误分享出来。如果你是一个独立开发者或独立 hacker 在做 AI 功能,坐好听着。
我认识的几乎每个开发者都会默认选 GPT-4o。我也一样,直到大约三周前。GPT-4o 确实很棒。但同时它每百万输出 tokens 要 10 美元。听起来不贵,直到你意识到一个"中等"聊天机器人每月要处理数百万 tokens。
问题不在 GPT-4o 本身。问题在于用它来做这些事情……比如判断用户消息是不是退款请求。或者总结一段文字。或者把"hello"翻译成西班牙语。这就像是雇一个米其林星级厨师给你做烤面包。
这是我希望六个月前就有人塞到我面前的表格:
看那个分类那行。0.60 美元/百万 vs 0.01 美元/百万。相差六十倍。对于一个小型模型完全可以碾压的、说白了就是很简单的任务来说。
我把分类器换过去大概花了二十分钟。第一周就省了大约 80 美元。
这是最大的杠杆。其他的策略加在一起,都没有选对更便宜的模型效果显著。
我现在是这么做的。我在代码里维护一个小映射:
MODEL_MAP = {
"chat": "deepseek-v4-flash", # $0.25/M
"code": "deepseek-coder", # $0.25/M
"simple": "Qwen/Qwen3-8B", # $0.01/M
"reasoning": "deepseek-reasoner", # $2.50/M
}
然后在任何东西发送到模型之前,我在 prompt 本身上运行一个快速分类器,来判断它是什么类型的任务。把简单的路由到 Qwen3-8B,把真正需要推理的工作发给 deepseek-reasoner,用 deepseek-v4-flash 做通用聊天。
你知道最疯狂的部分是什么吗?对于大多数查询,用户根本无法分辨差异。我在自己的产品上做了两周 A/B 测试。完成率差异在 1% 以内。
下面是在实践中用 Global API 的样子(我后来切换过去的,后面会详细说):
import requests
API_BASE = "https://global-apis.com/v1"
def chat(user_input, task_type):
model = MODEL_MAP[task_type]
resp = requests.post(
f"{API_BASE}/chat/completions",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": model,
"messages": [{"role": "user", "content": user_input}]
}
)
return resp.json()
就这样。这就是整个策略。而且它是我省钱的大头。
这个做起来真的很有意思。理念是:不要假设每个请求都需要最好的模型。先试便宜的,检查回复是否足够好,只有在不够好的时候才升级。
我为一个垂直 SaaS 产品运行一个客服机器人,大概 80% 的来访消息实际上是同样五个问题的不同问法。"我怎么重置密码。""在哪里找到我的 API key。""我能退款吗。"诸如此类。
那我为什么要把这些发给 2.50 美元/百万的推理模型?我不会。下面是我的实际路由函数:
def smart_generate(prompt, max_budget=0.50):
"""先试便宜的,质量不够就升级"""
resp = call_model("Qwen/Qwen3-8B", prompt)
if quality_check(resp) >= 0.8:
return resp # 80%+ 的请求在这里处理
# 第二层:标准 ($0.25/M)
resp = call_model("deepseek-v4-flash", prompt)
if quality_check(resp) >= 0.9:
return resp # 15% 的请求
# 第三层:高级 ($0.78-$2.50/M)
return call_model("deepseek-reasoner", prompt) # 5% 的请求
quality_check 函数本身就是一个兔子洞——我用一个小型的 embedding 模型来将回复与几个"好答案"示例进行比较。对于明显的情况效果出奇地好。
那个客服机器人?以前每月要花 420 美元。现在 28 美元。同样的运行时间,同样的客户满意度分数(我检查过)。这个数学算下来真的很有意思。
这个是列表里最"显而易见"的策略,但很多人跳过了它。如果用户问同样的问题两次,你在付两次钱。为什么?
我加了一个简单的基于 MD5 的缓存,效果就像白捡的钱:
import hashlib, json, time
cache = {}
def cached_chat(model, messages, ttl=3600):
key = hashlib.md5(
json.dumps({"model": model, "messages": messages}).encode()
).hexdigest()
if key in cache:
entry = cache[key]
if time.time() - entry["time"] < ttl:
return entry["response"] # 缓存命中 — $0 成本
response = requests.post(
f"{API_BASE}/chat/completions",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"model": model, "messages": messages}
).json()
cache[key] = {"response": response, "time": time.time()}
return response
对于 FAQ 机器人和文档查询功能,50-80% 的缓存命中率完全正常。这意味着你一半的流量是免费的。
我现在甚至用 embedding 缓存语义相似的查询,但那本身就是另一篇文章了。先从精确匹配开始,这已经是一个巨大的胜利。
我以前有这些巨大的 system prompt。数千个 tokens 的"你是一个有用的助手……" boilerplate。而且每个请求都会包含全部内容。
然后我算了算账,差点哭出来。
一个 2000 tokens 的 system prompt 是真金白银。按 DeepSeek V4 Flash 的价格(0.25 美元/百万输入 tokens),每个请求大约 0.0005 美元。很便宜,对吧?但每天 10,000 个请求?那光是 system prompt 每天就要 5 美元。每月 150 美元。就为了那些话。
所以我开始压缩:
def compress_prompt(text, target_ratio=0.5):
"""发送前压缩长 prompt"""
if len(text) < 500:
return text # 已经够短了
# 用一个便宜的模型来总结上下文
summary = call_model("Qwen/Qwen3-8B",
f"用 {int(len(text)*target_ratio)} 个字符总结这个:{text}"
)
return summary
原文指出,把一个 2000 tokens 的 prompt 压缩到 400 tokens 可以节省 0.024 美元/请求。每天 10K 请求就是每天 240 美元,或者每年 87,600 美元。这不是笔误。八万七千美元。就这一个优化。
我在启动时把 system prompt 过一遍压缩器,缓存结果,从此再也不用付全价了。
这个太简单了,感觉像作弊。与其发送 100 个单独的请求,不如发送 1 个包含 100 个条目的请求。
原文展示了这个模式:
# 之前:3 个独立调用(3× 输入 tokens)
for question in questions:
response = client.chat.completions.create(
model="deepseek-v4-flash",
messages=[{"role": "user", "content": question}]
)
# 之后:1 个批量调用(共享上下文)
你节省了 overhead tokens,节省了连接时间,而且大多数模型处理批量输入的效果都很好。我把它用在批量处理客户反馈、为一批页面生成 SEO 描述、总结一批文章——任何我在对列表做相同任务的场景。
说实话,一旦我开始持续这样做,光这一项每月账单就节省了大约 15%。
这是我长期忽略的事情。大多数模型的默认 max_tokens 设置比实际需要的高得多。如果你要把一条消息分类为"退款"或"不退款",你不需要 4000 tokens 的输出。你大概只需要 5 个。
我设置了按任务的 max_tokens 限制,输出成本就这么……断崖式下跌。
分类:max_tokens=10 聊天回复:max_tokens=500 代码生成:max_tokens=2000
听起来微不足道。当你在处理数千个请求时,加起来很快。
这是更高级的玩法,我不会什么都做,但对于我最高频的任务(客服机器人的意图分类),我在大约 500 条历史工单上微调了一个小型 Qwen 模型。
微调成本:大约 5 美元一次性。