Token 成本控制:从账单震惊到精准预算的三层防线
前四篇文章搭好了 Agent、监控、Gateway、RAG 知识库。系统跑起来了,但运维的直觉告诉我:该算账了。
这篇文章给整个链条加上成本控制——三层防线,从缓存到路由到预算,让 AI 系统像管理服务器成本一样可预测。
Token 成本到底有多贵
先看定价表。各模型的价格差异巨大——最贵的比最便宜的高 18 倍:
| 模型 | 输入 $/1M tokens | 输出 $/1M tokens | 千次调用* |
|---|---|---|---|
| gpt-4o | 2.50 | 10.00 | $4.50 |
| gpt-4o-mini | 0.15 | 0.60 | $0.27 |
| deepseek-chat | 0.14 | 0.28 | $0.20 |
| qwen-plus | 0.80 | 2.00 | $1.20 |
| claude-3-haiku | 0.25 | 1.25 | $0.50 |
| claude-3.5-sonnet | 3.00 | 15.00 | $6.00 |
*假设每次 1000 input + 200 output tokens
一个日均 1000 次 Agent 调用的系统,选 gpt-4o 月成本 $135,选 deepseek-chat 只要 $6。差 22 倍。
所以成本控制的核心问题不是”怎么省钱”,而是:什么时候该用便宜的模型,什么时候必须用贵的?
三层防线架构
用户请求
│
├─ 防线 1: 语义缓存
│ └─ 相似问题 → 缓存答案(0 Token)
│
├─ 防线 2: 分级路由
│ └─ gpt-4o-mini → 不满意?→ gpt-4o
│
└─ 防线 3: 预算管控
└─ 月度预算 > 80% → 告警,> 100% → 硬拒绝
防线 1:语义缓存
传统缓存是字符串精确匹配——“Pod 重启了”和”Pod 起不来了”是两个不同 key,哪怕意思一样。
语义缓存用 Embedding 计算相似度——“Pod 重启”和”容器不断被杀死”的余弦相似度可能高达 0.95,命中缓存。
class SemanticCache:
def lookup(self, question: str) -> str | None:
# 1. 精确匹配(同一问题)
key = sha256(question)
if key in self._cache:
return self._cache[key].answer
# 2. 语义匹配(相似问题)
q_embedding = self.embeddings.embed_query(question)
for entry in self._cache.values():
if cosine_similarity(q_embedding, entry.embedding) >= 0.92:
return entry.answer # 命中!
return None # 未命中,需要调用 LLM
命中率取决于场景:
- 客服系统(问题高度重复)→ 命中率 60-80%
- 技术问答(问题多样性高)→ 命中率 20-40%
- 闲聊对话 → 不适合缓存
相似度阈值的权衡:
0.95→ 保守,只有几乎相同的问题才命中,误匹配趋近零0.85→ 激进,更多命中但可能答非所问
建议从 0.92 起步,根据业务反馈调优。
防线 2:分级路由
便宜模型能回答的问题,不要用贵模型。逻辑很简单:便宜先上,不满足条件再升级。
class TieredRouter:
tiers = [
("gpt-4o-mini", float("inf"), ...), # 第一级:便宜
("gpt-4o", float("inf"), ...), # 第二级:贵
]
def route(self, messages):
for model_name, _, llm in self.tiers:
answer = llm.invoke(messages).content
if self._is_satisfactory(answer):
return answer, model_name, cost # 便宜模型搞定了
# 所有级别都试过了,返回最后结果
def _is_satisfactory(self, answer: str) -> bool:
if len(answer) < 20:
return False
# 拒绝信号
if any(s in answer for s in ["不知道", "无法", "对不起"]):
return False
return True
实际效果:
| 问题类型 | 命中 tier | 成本 |
|---|---|---|
| “Kubernetes 是什么” | mini | ~$0.0001 |
| “这个 YAML 配置怎么优化” | mini | ~$0.0001 |
| “复杂的分布式事务设计” | 4o | ~$0.0020 |
| “帮我审查这份架构方案” | 4o | ~$0.0030 |
大部分日常问题被 mini 拦截,只有真正需要推理能力的才走 4o。
防线 3:预算管控
缓存和路由减少消耗,预算管控设硬上限——防止账单在不知情的情况下炸掉。
class BudgetManager:
def spend(self, model, prompt_tokens, completion_tokens) -> bool:
cost = token_cost(model, prompt_tokens, completion_tokens)
if self.spent + cost > self.monthly_budget:
return False # 硬拒绝
self.spent += cost
if self.spent_percent >= 95:
alert("🚨 预算即将耗尽!")
elif self.spent_percent >= 80:
alert("⚠️ 预算已使用 80%")
告警规则:
| 阈值 | 动作 | 原因 |
|---|---|---|
| 80% | ⚠️ 邮件/IM 告警 | 提前预警,有时间调整 |
| 95% | 🚨 紧急告警 + 自动降级 | 只允许便宜模型 |
| 100% | ❌ 硬拒绝 | 防止超额计费 |
集成到现有系统
回到前面几篇文章的架构,成本控制作为外层包装:
# 之前(无成本控制)
answer = agent.invoke({"messages": [HumanMessage(content=q)]})
# 之后(三层防线)
llm = CostControlledLLM(budget=50.0, cache_threshold=0.92)
# 防线 1: 语义缓存
cached = llm.cache.lookup(q)
if cached:
return cached
# 防线 2+3: 预算检查 + 分级路由
answer = llm.router.route(messages)
llm.budget.spend(model, prompt_tokens, completion_tokens)
llm.cache.store(q, answer, tokens_used)
成本控制模块是外挂的——不影响 Agent 的业务逻辑,可以随时开关。
实际收益估算
假设一个日均 1000 次调用的 Agent 系统:
| 策略 | 日 Token | 日成本 | 月成本 |
|---|---|---|---|
| 全用 gpt-4o | 1.2M | $3.60 | $108.00 |
| 全用 gpt-4o-mini | 1.2M | $0.22 | $6.50 |
| 三层防线 | 0.6M | $0.08 | $2.50 |
三层防线相比全用 gpt-4o 降低 97%,相比全用 mini 降低 62%。
节省来自:
- 语义缓存命中 30% → 这些请求 0 Token
- 分级路由 → 80% 流量被 mini 拦截
- 预算管控 → 防止异常调用
完整代码
- 成本控制模块:demo/token-cost/cost_control.py
- Demo 脚本:demo/token-cost/demo.py
系列总结
五篇文章,从 Agent 工程到成本管控,形成了一条完整的 AI 系统生产化能力链:
Agent 工程 → 构建能干活、能调用工具的 AI 系统
AI 可靠性 → 监控一切、控制成本、不翻车
AI 基础设施 → 统一网关、管理模型、不绑死一家
这是一个运维工程师视角的 AI 实战体系——不是”怎么用 ChatGPT”,而是怎么把 AI 当成基础设施来运维。