AI 应用成本控制:Token 计费、缓存与模型路由策略
AI 应用成本是非线性的:用户数翻倍,成本可能翻几倍。优化第一原则是先测量——很多团队优化了只占 5% 成本的功能,而大头未被发现。
一个真实的成本失控案例
假设你做了个 AI 客服,上线第一个月很顺利。第二个月用户量翻了三倍,账单涨了远超三倍——为什么会超线性增长?
原因通常有三个叠加:
- 对话轮次变长:用户多了,多轮对话占比上升。而每轮的输入包含全部历史,第 10 轮的 token 消耗是第 1 轮的近 10 倍
- 上下文膨胀:加了 RAG 后,每轮都要塞入检索结果
- 重试与失败:网络超时、格式错误导致的重试,都在重复计费
结果是:用户数 ×3,成本可能 ×8。
这正是 AI 应用成本控制的难点——它不是线性的,容易被低估。
先搞清楚钱花在哪
优化之前必须先测量。token 成本只有两个来源:
成本 = 输入 token × 输入单价 + 输出 token × 输出单价
关键事实:输出 token 通常比输入贵 2-4 倍。
这就引出了第一个反直觉的结论:
控制输出长度,往往比控制输入更省钱。
很多人拼命优化 RAG 的检索片段数量(减少输入),却让模型生成冗长的回答(输出暴涨)。后者对成本的影响可能更大。
记录粒度要够细
至少按这几个维度切分:
- 按功能:对话、摘要、分类、RAG 检索后生成——各占多少
- 按用户:哪些用户成本高(可能是滥用)
- 按模型:哪些调用用了贵模型
- 按轮次:多轮对话的成本分布
没有这些数据,优化就是盲目的。 你可能会花大力气优化一个只占 5% 成本的功能。
策略一:模型路由(收益最大)
这是投入产出比最高的手段。
核心思路:不是所有请求都需要最强的模型。
用户请求
↓
判断复杂度
├── 简单(分类、提取、格式转换)→ 小模型(便宜 10-30 倍)
├── 中等(常规问答、摘要)→ 中档模型
└── 复杂(推理、长文分析)→ 强模型
怎么判断复杂度
几种可行的方法,从简单到复杂:
方法一:规则前置
如果请求类型明确,直接用规则分流。比如:
- 意图分类 → 小模型
- 知识问答 → 中档模型
- 复杂分析 → 强模型
最简单,也最可靠。
方法二:用小模型做路由
让一个便宜的小模型先判断「这个问题属于哪一类」,再分派。
成本是:多一次小模型调用(很便宜),可能节省一次强模型调用(很贵)。
方法三:置信度阈值
先用小模型处理,如果它的输出置信度低(或格式不合法),再升级到强模型。
关键提醒:路由判断本身也有成本。如果路由调用的成本接近直接调用小模型,那路由就不划算。 所以在低价值场景,直接用规则更合适。
实测建议
先统计你的请求分布。如果 80% 的请求都能用便宜模型处理,那整体成本能降一个数量级。
这个比例在多数业务里是成立的——因为真正的复杂推理请求其实很少。
策略二:缓存(效果立竿见影)
精确缓存
相同的问题直接返回缓存结果。
关键在于「相同」怎么定义:
- 完全匹配(hash 相同):最保险,命中率低
- 归一化后匹配(去空格、统一大小写、同义词替换):命中率提升明显
适合场景:高频常见问题。比如 FAQ 类问答,前 20 个问题可能占 50% 的请求量。
语义缓存
用向量相似度判断「这个问题和之前问过的意思一样吗」。
命中率比精确缓存高得多,但有两个风险:
- 误判:意思相近但答案不同的问题被当成同一个(比如「退款要几天」和「换货要几天」)
- 成本:每次都要算向量并检索,虽然比调用大模型便宜得多,但不是零成本
建议:设置较高的相似度阈值,宁可少命中也不要答错。
上下文缓存(Prompt Caching)
这是近两年最值得关注的优化。
原理:如果多次请求的前缀相同(比如同一份长文档、同一套系统提示词),平台可以缓存这部分的计算结果,后续请求只按较低价格计费。
典型场景:
- 对同一份长文档反复提问 → 缓存文档部分
- 固定很长的系统提示词 → 缓存提示词部分
- 多轮对话 → 缓存历史部分
效果:在某些场景下能降低 50-90% 的输入成本,同时显著降低首 token 延迟。
如果你还没用这个能力,先去检查你的平台是否支持——这可能是最容易被忽略的大额节省。
策略三:控制上下文
上下文相关的成本,来自几个叠加因素:
多轮对话的历史膨胀
第 N 轮的输入包含前 N-1 轮的全部内容。所以:
总成本 ≈ O(N²) (N 轮对话)
优化手段:
- 滑动窗口:只保留最近 K 轮完整对话
- 滚动摘要:把较早的对话压缩成摘要
- 关键信息提取:只保留事实性内容(用户提到的订单号、偏好等),丢弃寒暄
注意:压缩是有损的,可能丢失重要细节。建议保留「最近的完整 + 较早的摘要」这种混合结构。
RAG 片段数量
这是最容易过度的地方。
基本原则:3-5 个高质量片段通常优于 10-20 个混杂片段。
- 效果:片段过多会稀释注意力,反而不准确
- 成本:线性增加
具体做法:
- 先粗召回 20-50 条(便宜)
- 用重排序模型精排(比大模型便宜得多)
- 只把 Top 3-5 送进生成模型
关于这部分,向量数据库选型 里有更详细的检索优化讨论。
限制输出长度
回到开头那句话:输出比输入贵。
控制手段:
- 明确要求简洁:在提示词里写清长度上限
- 结构化输出:JSON 比自然语言节省大量 token
- max_tokens 限制:硬性截断,但要小心截断导致内容不完整
一个实用技巧:如果你的场景不需要解释,就明确说「只输出结果,不要解释」。这一条能省下大量输出 token。
策略四:批处理
如果你的任务是离线的(不需要即时响应),批处理能省很多:
- 很多平台提供批处理 API,价格通常是实时调用的一半
- 缺点是延迟高(可能几小时)
适合场景:
- 批量文档摘要
- 数据标注与清洗
- 历史数据回填
如果你的任务能等,就不要用实时 API。 这是纯粹的省钱,没有效果损失。
策略五:减少无效调用
这部分容易被忽略,但往往有意外收获。
重试的代价
失败重试是重复计费。常见失败原因:
- 输出格式不合法(JSON 解析失败)
- 超时
- 限流
优化:
- 用结构化输出而不是靠提示词约束格式,能大幅降低格式失败率
- 幂等设计:确保重试不会产生重复副作用
- 设置合理超时,避免无效等待
提前拦截
在调用模型之前先做判断:
- 敏感词/违规内容 → 直接拦截,不调模型
- 格式错误 → 直接返回错误提示
- 超长输入 → 先截断或拒绝
每一次无效的模型调用都是纯浪费。
输入预校验
很多失败源于输入本身有问题(空值、格式不对、超长)。在入口处校验,比让模型处理再失败便宜得多。
监控与告警
优化不能是一次性的,需要持续监控。
必须有的指标:
- 单次请求平均成本,按功能分组
- 成本/用户比,识别异常用户
- 缓存命中率
- 模型路由分布(多少走了便宜模型)
- 失败重试率
告警规则:
- 日成本超过阈值
- 单用户成本异常(可能是滥用或 bug)
- 缓存命中率骤降(可能是缓存失效)
设置成本上限:为每个用户或会话设置 token 预算,超限直接拒绝。这是防止单点失控的最后一道防线。
一个务实的优化顺序
按投入产出比排序,建议这个顺序:
第一步:测量
先把成本拆清楚,知道钱花在哪。不做这一步,后面都是瞎猜。
第二步:上缓存
尤其是上下文缓存(如果平台支持)和常见问题缓存。改动小,效果直接。
第三步:模型路由
统计请求分布,把简单请求导到便宜模型。收益最大,但需要先有数据支撑。
第四步:控制上下文
优化多轮历史管理、RAG 片段数量、输出长度。
第五步:批处理
离线任务改用批处理 API。
第六步:持续监控
建立告警,防止成本失控。
小结
AI 应用成本控制的核心认知:
- 成本是非线性的——用户数翻倍,成本可能翻几倍,因为多轮对话和上下文膨胀
- 输出比输入贵——控制输出长度常被忽略,但收益明显
- 路由收益最大——多数请求不需要最强模型
- 缓存见效最快——尤其别忽略上下文缓存
最后强调第一步:先测量,再优化。 很多团队花大量精力优化了一个只占 5% 成本的功能,而真正的大头(比如多轮对话的历史膨胀)没被发现——因为没人看数据。