LLM 多模型选型与成本控制
线上用 LLM,选哪个模型不是"挑最强的",而是在能力、延迟和成本之间找到匹配任务的点。用顶配模型做简单分类,是把钱和延迟浪费在不需要的地方;用小模型做复杂推理,则是用便宜换来了错误率。选型的核心是分层:不同任务配不同档位的模型,再用缓存和降级把整体成本压住。
按任务难度分档
不是所有调用都该走同一个模型。把任务按"需要多少推理能力"分层:
| 任务类型 | 典型场景 | 选型倾向 |
|---|---|---|
| 简单分类/抽取 | 意图识别、情感、字段提取 | 小模型,快且便宜 |
| 改写/摘要 | 缩写、润色、格式转换 | 中档模型 |
| 复杂推理/生成 | 多步规划、代码生成、长文写作 | 强模型,必要时才用 |
关键认知:能力差距是真实的,但不是每个任务都需要最强能力。一个意图分类任务,小模型和大模型的准确率可能只差几个百分点,但成本和延迟差几倍。先用最便宜的能达标模型,不够再升档,而不是默认从最贵开始。
成本来自哪里
LLM 的计费按 Token,理解账单要先理解 Token 在哪被消耗:
text
单次成本 = (输入 Token × 输入单价) + (输出 Token × 输出单价)容易被忽略的几个成本放大器:
- 上下文越滚越长:多轮对话里,每一轮都把之前所有历史重新发给模型,长对话的后几轮成本可能是第一轮的几十倍。
- 输出比输入贵:输出 Token 单价通常是输入的 3-5 倍,让模型"长篇大论"比让它读长文本更花钱。
- 隐藏的重试:解析失败、格式不对、被安全策略拦截导致的重试,每一次都全额计费。
先做一次成本估算:把预期调用量、平均输入输出长度、单价填进去,算出月成本。很多项目在上线前根本没算过这笔账,结果第一个月账单就失控。
用缓存挡住重复调用
大量 LLM 调用其实是重复的——同样的常见问题、同样的指令模板。缓存能直接把这部分成本降到接近零:
text
用户提问 → 生成缓存 key(归一化后的问题 + 关键参数)
→ 命中缓存 → 直接返回,不计费
→ 未命中 → 调用模型 → 写入缓存 → 返回缓存生效的前提是 key 设计合理:去掉无关空格和标点、统一大小写、把易变的参数(如时间戳)排除在外。缓存要有 TTL,知识更新后旧答案要能失效。对于答案对一致性要求高的场景,把温度设为 0,相同的输入才会产生相同的输出,缓存命中率才高。
压缩上下文,控制输入
输入 Token 是可控的成本项。几个直接有效的做法:
- 不要把全量历史塞进去:多轮对话定期摘要,只保留最近几轮原文 + 早期摘要。
- 检索代替全量:与其把整本文档发给模型,不如先检索出相关片段,只发片段(这正是 RAG 的成本价值)。
- 精简 prompt:系统指令里删掉模型已经知道的常识,示例留 2-3 个有代表性的就够。
一个常见的浪费是:每次调用都把一大段固定的背景说明重复发送。把这些固定内容做缓存(部分模型支持 prompt caching),能显著降低重复输入的成本。
延迟也是成本
用户感受的不只是钱,还有等待时间。影响延迟的主要因素:
| 因素 | 影响 |
|---|---|
| 输入长度 | 模型处理输入的时间 |
| 输出长度 | 逐 Token 生成,越长越慢 |
| 模型规模 | 大模型首 Token 更慢 |
| 流式输出 | 边生成边返回,显著改善体感 |
对交互场景,优先用流式输出(streaming)——用户看到第一个字的时间远比总时长重要。对后台批处理,用更便宜的模型批量跑,延迟不敏感时不必追求首 Token 速度。
降级与兜底
模型服务会失败、会超时、会限流。线上系统不能假设调用一定成功:
- 重试:对限流和超时做指数退避重试,但对内容被拒绝(安全策略)不要盲目重试。
- 降级模型:主模型失败时,降级到一个备用模型或规则兜底,保证服务可用。
- 预算熔断:设置日/月成本上限,超过阈值自动停止调用或切到便宜模型,防止异常流量打爆账单。
把"模型不可用"当作常态来设计,而不是异常。一个只会调单一模型、没有兜底的系统,上线后迟早会在某个高峰期挂掉。
务实的选择清单
- 每个任务是否都评估过用最小够用的模型,而不是默认最强?
- 是否做过成本估算,知道月度账单大概多少?
- 重复调用有没有缓存,key 设计是否合理?
- 长对话和多轮场景有没有做上下文压缩?
- 是否有降级、重试和预算熔断,模型挂了系统还能用?
选型和成本控制不是一次性决策,而是持续的过程:上线后监控实际用量和效果,定期把升档的降回来、把没缓存的加上缓存。模型和能力都在变,今天的最优配置,三个月后可能就该重新评估。