AI Coding 烧钱如流水?一文讲透 Token 经济学:路由、缓存与上下文压缩如何把成本砍半
📖 摘要:AI Coding 已从「编码提效」进入「成本治理」阶段。隐性成本(缓存未命中、重试、工具失败、人工复核)常被忽略,单模型盲目调用让账单失控。本文用纯 Python 手写模型路由、Prompt Caching 压测与上下文压缩三件套,并装进统一 Gateway,给出可落地的 Token 经济学降本方案与生产避坑。
🏷️ 关键词:AI Coding,Token 经济学,模型路由,Prompt Caching,上下文压缩
目录
- 一、为什么 AI Coding 成本会失控
- 二、Token 经济学的四个基本量
- 三、核心武器一:模型路由
- 四、核心武器二:Prompt Caching 与上下文工程
- 五、核心武器三:上下文压缩
- 六、实战:把三件套装进统一 Gateway
- 七、三条生产避坑
- 八、总结
一、为什么 AI Coding 成本会失控
很多团队上 AI Coding 工具的第一反应是「快了」,第二反应是「账单怎么这么厚」。问题不在模型单价,而在成本结构被低估。
1.1 被忽略的隐性成本
公开榜单里的「每百万 Token X 美元」只是冰山一角。真实账单由以下几块叠加:
- 缓存未命中:每次都重传 system prompt、项目上下文、工具定义,意味着本可命中的前缀缓存全部失效。
- 重试与工具失败:Agent 调工具报错、解析失败、自检不通过,会触发多轮重试,Token 成倍增长。
- 长推理强度:开了高 reasoning effort 或长链规划,输出 Token 可能是简单问答的 5~10 倍。
- 人工复核时间:模型答错时往往最自信,错误产物进入代码库后的排查成本,常常比调用费更贵。
一句话:成功任务成本 ≠ 调用费。应以「成功完成任务的单位成本」衡量,而不是只看 tokens/s 或单次单价。
1.2 一个量级估算(示例数据)
下面是一组示意数据,仅作演示,用来建立直觉:
| 项目 | 数值 |
|---|---|
| 日均 Agent 调用次数 | 10,000 |
| 平均每次输入 Token | 18,000 |
| 平均每次输出 Token | 2,000 |
| 输入单价(旗舰档) | $3 / 百万 |
| 输出单价(旗舰档) | $15 / 百万 |
| 缓存命中率 | 30% |
| 工具失败重试率 | 25% |
粗算日均账单:(18000×0.7×3 + 2000×15) / 1e6 × 10000 × 1.25 ≈ $495/天,月度接近 $15k。后面三件套的目标,就是把这个数字砍到一半以下。
二、Token 经济学的四个基本量
在动手之前,先把账算清楚。一个有成本意识的 Agent 调用层,至少要盯住四个量。
2.1 输入/输出 Token 单价
几乎所有厂商的输入价都远低于输出价(典型 1:5)。因此省输出比省输入更划算——这直接决定了后面的路由策略:能交给小模型完成的任务,绝不用旗舰模型硬扛。
2.2 缓存命中率 Prompt Caching
把稳定不变的前缀(system prompt、工具 schema、项目索引)标记为可缓存段,命中后输入单价可降到原来的 1/10。这是性价比最高的一招,没有之一。
2.3 缓存生命周期 TTL
缓存不是无限活着的。前缀一旦变化(哪怕多一行日志),整段缓存失效。因此要让「会变的内容」放在尾部、「不变的内容」放在头部,最大化前缀复用。
2.4 推理强度与成本档位
多数新模型提供 effort / cost_tier 参数(low→max)。日常补全用 low,复杂重构用 high,而不是一刀切。OpenRouter 的 Auto 路由正是用「社区真实消费的 55T Token 数据」按任务类型匹配模型——本质是「用钱投票」取代「厂商拍脑袋」。
三、核心武器一:模型路由
3.1 路由的本质:按任务难度选模型
模型路由(Model Routing)的核心理念只有一句:让合适的模型做合适的事。把「改个变量名、补个 import」交给轻量 Flash 模型,把「跨文件重构、复杂 bug 定位」才交给旗舰模型。差距不是能力,而是单位成本。
3.2 手写一个分层路由器(Python)
下面是一段纯标准库、可直接 python route.py 跑通的分层路由器骨架。它根据任务标签与预估复杂度,决定走哪个档位的模型,并带兜底降级。
3.2.1 路由决策逻辑
# route.py —— 分层模型路由器(纯标准库,示意)
from dataclasses import dataclass
from typing import Literal
Tier = Literal["flash", "standard", "frontier"]
# 示例单价(美元 / 百万 Token),仅作演示
PRICING = {
"flash": {"in": 0.10, "out": 0.40},
"standard": {"in": 0.75, "out": 3.00},
"frontier": {"in": 3.00, "out": 15.00},
}
# 任务难度 → 默认档位
SIMPLE_TASKS = {"rename", "import", "format", "docstring", "test_boilerplate"}
HARD_TASKS = {"refactor", "debug", "arch_review", "multi_file"}
def route(task: str, est_tokens: int) -> Tier:
"""按任务类型 + 预估规模选择模型档位。"""
base = task.split(":")[0]
if base in SIMPLE_TASKS:
tier: Tier = "flash"
elif base in HARD_TASKS:
tier = "frontier" if est_tokens > 12000 else "standard"
else:
tier = "standard"
# 超长上下文强制升档,避免小模型截断重跑(更贵)
if est_tokens > 30000:
tier = "frontier"
return tier
def cost_of(tier: Tier, in_tok: int, out_tok: int, cache_hit: float = 0.0) -> float:
p = PRICING[tier]
eff_in = in_tok * (1 - cache_hit * 0.9) # 缓存命中后输入价再降 90%
return (eff_in * p["in"] + out_tok * p["out"]) / 1_000_000
if __name__ == "__main__":
for t, n in [("rename:foo", 4000), ("debug:null_pointer", 18000),
("refactor:auth_module", 40000)]:
tier = route(t, n)
print(f"{t:28s} -> {tier:9s} 单次成本 ${cost_of(tier, n, 2000):.5f}")
运行输出示例:
rename:foo -> flash 单次成本 $0.00080
debug:null_pointer -> standard 单次成本 $0.00600
refactor:auth_module -> frontier 单次成本 $0.12600
可以看到:简单的改动走 flash,单次成本不到一厘;只有真正超长、高难的任务才升到 frontier。
3.2.2 兜底与降级
生产环境要加两道保险:① 旗舰模型超时/限流时,自动降级到 standard 并重试;② 连续 N 次降级失败再报警,而不是静默吞错。降级策略本身也要计入成本模型——降级后若任务失败重跑,反而更贵。
3.3 接入 OpenRouter / OmniRoute 的思路
不想自己维护路由规则时,可直接接 OpenRouter 的 openrouter/auto 或 OmniRoute 这类「单端点、340+ provider」网关:它们在服务端按任务类型与社区真实消费数据自动选模型。自己写路由器的价值在于可控、可审计、可对齐内部成本红线,适合对账单敏感的企业场景。
四、核心武器二:Prompt Caching 与上下文工程
4.1 系统化复用前缀
把以下内容固定放在消息头部并显式标记缓存断点:system prompt、工具/函数 schema、项目结构索引、高频复用的代码约定。把易变内容(用户最新指令、工具返回)放到尾部。这样同一会话的后续调用能命中长前缀缓存。
4.2 缓存命中率压测脚本
上线前先用脚本压一轮,确认命中率达到预期(示例用随机模拟,真实环境替换为你的网关日志):
# cache_probe.py —— 缓存命中率与节省测算(示意)
import random
def simulate_cache_hit(prefix_changed_rate: float, calls: int = 2000) -> float:
hits = 0
for _ in range(calls):
# 前缀不变的调用视为命中
if random.random() > prefix_changed_rate:
hits += 1
return hits / calls
if __name__ == "__main__":
for rate in (0.5, 0.1, 0.02):
hr = simulate_cache_hit(rate)
saving = hr * 0.9 # 命中后输入价降 90%
print(f"前缀变更率 {rate:.2f} -> 命中率 {hr:.1%}, 输入成本节省约 {saving:.1%}")
经验值:前缀变更率压到 5% 以下,输入成本通常能降 80%+。代价是工程上要严格控制「头部不变、尾部可变」的约束。
五、核心武器三:上下文压缩
5.1 为什么上下文会膨胀
Agent 多轮对话 + 工具返回会把上下文撑到几万 Token。GitHub 趋势里的 headroom 就是专门做这件事的(令牌减少 60~95%)。核心思路:旧轮次摘要化、只保留近期原始内容、长工具输出截断或抽关键字段。
5.2 摘要式压缩实现(Python)
下面是一段确定性、可运行的压缩骨架(真实场景可在「摘要」处接一个小模型,但保留 heuristic 兜底以保证可控):
# compress.py —— 对话上下文摘要式压缩(纯标准库,示意)
from dataclasses import dataclass
from typing import List
@dataclass
class Turn:
role: str
text: str
def compress_turns(turns: List[Turn], keep_recent: int = 4) -> List[Turn]:
"""保留最近 keep_recent 轮原文,更早的轮次折叠为一句摘要。"""
if len(turns) <= keep_recent:
return turns
old, recent = turns[:-keep_recent], turns[-keep_recent:]
# 真实环境:此处调用小模型生成摘要;这里用确定性 heuristic 兜底
summary_text = f"[历史摘要] 已折叠 {len(old)} 轮对话,关键词:" + ",".join(
sorted({t.role for t in old})
)
return [Turn("system", summary_text)] + recent
if __name__ == "__main__":
turns = [Turn("user", f"第{i}轮需求") for i in range(12)]
compressed = compress_turns(turns, keep_recent=4)
print(f"原始轮数 {len(turns)} -> 压缩后 {len(compressed)} 轮")
把压缩装进 Gateway 后,长任务的平均输入 Token 通常能砍掉一半以上——而输入往往是大头。
六、实战:把三件套装进统一 Gateway
6.1 统一调用层架构
把路由、缓存、压缩收口到一个 Gateway 类里,业务代码只调 gateway.complete(),成本策略对上层透明:
业务/Agent ──> Gateway.complete(task, messages)
├─ compress(messages) # 上下文压缩
├─ route(task, est_tokens) # 选模型档位
├─ cache_aware_build() # 构造可缓存前缀
└─ call_provider() # 真实/模拟调用
6.2 每任务成本埋点
每完成一次调用,记一条成本事件(模型、in/out Token、cache_hit、耗时、是否重试)。这是做「成功任务单位成本」看板的数据底座,也是后续优化 ROI 的依据。注意:日志若含 system prompt 与工具返回,必须做脱敏与访问控制,避免敏感信息随可观测数据外泄。
七、三条生产避坑
- 别只看单价,看成功任务成本:重试、工具失败、人工复核都要计入。建同一真实任务集,记录质量、成功率、P50/P95 延迟与人工介入率,再决定迁移。
- 缓存全量可观测会扩大数据面:事件日志记录了推理、工具结果和上下文,必须同步设计脱敏、保留期、租户隔离与访问审计,否则成本省下的钱不够填安全漏洞。
- 降级不是免费午餐:旗舰限流时降级到小模型,若任务失败重跑反而更贵。降级阈值与重试次数要写进成本模型,定期回测。
八、总结
AI Coding 的下半场,比的不是「谁的模型最强」,而是「谁能把单位成功成本压到最低」。本文给出三条可落地的主线:模型路由(按难度选档、带兜底降级)、Prompt Caching(头部不变、尾部可变,把输入成本砍 80%+)、上下文压缩(摘要式折叠,长任务输入减半),并强调用统一 Gateway 收口 + 每任务成本埋点。把这「三件套」装上,配合三条生产避坑,把月度账单砍半并非口号。
本文示例代码均为演示性骨架,价格、Token 数、命中率均为示意数据;接入真实 API 时请替换为你自有的网关、鉴权与计费口径,并对日志做脱敏处理。
跨平台发布提示:本文目录采用可移植 HTML 锚点(非平台专属快捷词),可直接同步到掘金、知乎、公众号等平台。

374

被折叠的 条评论
为什么被折叠?



