做过 LLM 应用开发的同学都知道,token 成本是个大头。用户量上来之后,每个月光API账单就要好几万。这篇文章聊聊怎么把 LLM 应用的成本降下来,都是实际项目里踩坑踩出来的经验。
一、先看看钱都花在哪了
先算一笔账:假设你的应用每天有 1 万次请求,每次请求平均消耗 2000 个 token(输入 + 输出)。
用 GPT-4 级别模型的话:
- 输入:$0.03 / 1K tokens
- 输出:$0.06 / 1K tokens
- 每天成本:约 $40-50
- 一个月:约 $1200-1500
这还是每天 1 万请求的规模。如果用户量再翻几倍呢?
成本优化不是小事,直接决定了你的业务能不能赚钱。
下面是成本构成的直观展示:
#mermaid-svg-Ud3e4xd9cUFQ6cti{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Ud3e4xd9cUFQ6cti .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Ud3e4xd9cUFQ6cti .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Ud3e4xd9cUFQ6cti .error-icon{fill:#552222;}#mermaid-svg-Ud3e4xd9cUFQ6cti .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Ud3e4xd9cUFQ6cti .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Ud3e4xd9cUFQ6cti .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Ud3e4xd9cUFQ6cti .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Ud3e4xd9cUFQ6cti .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Ud3e4xd9cUFQ6cti .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Ud3e4xd9cUFQ6cti .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Ud3e4xd9cUFQ6cti .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Ud3e4xd9cUFQ6cti .marker.cross{stroke:#333333;}#mermaid-svg-Ud3e4xd9cUFQ6cti svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Ud3e4xd9cUFQ6cti p{margin:0;}#mermaid-svg-Ud3e4xd9cUFQ6cti .pieCircle{stroke:#000000;stroke-width:2px;opacity:0.7;}#mermaid-svg-Ud3e4xd9cUFQ6cti .pieOuterCircle{stroke:#000000;stroke-width:1px;fill:none;}#mermaid-svg-Ud3e4xd9cUFQ6cti .pieTitleText{text-anchor:middle;font-size:25px;fill:#000000;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-Ud3e4xd9cUFQ6cti .slice{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;fill:#000000;font-size:17px;}#mermaid-svg-Ud3e4xd9cUFQ6cti .legend text{fill:#000000;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:17px;}#mermaid-svg-Ud3e4xd9cUFQ6cti :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}50%40%10%LLM 应用成本构成输入 Token 费用输出 Token 费用其他(网络/存储等)
二、优化思路 1:模型分层调用
核心思路
不是所有请求都需要用最贵的大模型。
简单的问题用小模型,复杂的问题才用大模型。
怎么做
用户请求
↓
分类器:这个问题复杂吗?
├── 简单 → 用7B小模型
├── 中等 → 用70B中模型
└── 复杂 → 用大模型
实际效果
- 80% 的简单问题用小模型解决
- 15% 的中等问题用中模型
- 只有 5% 的复杂问题用大模型
总成本直接降 70-80%。
分类器怎么选
- 简单的分类规则就行(关键词匹配)
- 也可以用一个小模型做分类
- 不要为了分类再搞个大模型,那就本末倒置了
整体流程可以用下面的图来表示:
#mermaid-svg-VOiI81BqzrSAukt6{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-VOiI81BqzrSAukt6 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-VOiI81BqzrSAukt6 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-VOiI81BqzrSAukt6 .error-icon{fill:#552222;}#mermaid-svg-VOiI81BqzrSAukt6 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-VOiI81BqzrSAukt6 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-VOiI81BqzrSAukt6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-VOiI81BqzrSAukt6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-VOiI81BqzrSAukt6 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-VOiI81BqzrSAukt6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-VOiI81BqzrSAukt6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-VOiI81BqzrSAukt6 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-VOiI81BqzrSAukt6 .marker.cross{stroke:#333333;}#mermaid-svg-VOiI81BqzrSAukt6 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-VOiI81BqzrSAukt6 p{margin:0;}#mermaid-svg-VOiI81BqzrSAukt6 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-VOiI81BqzrSAukt6 .cluster-label text{fill:#333;}#mermaid-svg-VOiI81BqzrSAukt6 .cluster-label span{color:#333;}#mermaid-svg-VOiI81BqzrSAukt6 .cluster-label span p{background-color:transparent;}#mermaid-svg-VOiI81BqzrSAukt6 .label text,#mermaid-svg-VOiI81BqzrSAukt6 span{fill:#333;color:#333;}#mermaid-svg-VOiI81BqzrSAukt6 .node rect,#mermaid-svg-VOiI81BqzrSAukt6 .node circle,#mermaid-svg-VOiI81BqzrSAukt6 .node ellipse,#mermaid-svg-VOiI81BqzrSAukt6 .node polygon,#mermaid-svg-VOiI81BqzrSAukt6 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-VOiI81BqzrSAukt6 .rough-node .label text,#mermaid-svg-VOiI81BqzrSAukt6 .node .label text,#mermaid-svg-VOiI81BqzrSAukt6 .image-shape .label,#mermaid-svg-VOiI81BqzrSAukt6 .icon-shape .label{text-anchor:middle;}#mermaid-svg-VOiI81BqzrSAukt6 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-VOiI81BqzrSAukt6 .rough-node .label,#mermaid-svg-VOiI81BqzrSAukt6 .node .label,#mermaid-svg-VOiI81BqzrSAukt6 .image-shape .label,#mermaid-svg-VOiI81BqzrSAukt6 .icon-shape .label{text-align:center;}#mermaid-svg-VOiI81BqzrSAukt6 .node.clickable{cursor:pointer;}#mermaid-svg-VOiI81BqzrSAukt6 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-VOiI81BqzrSAukt6 .arrowheadPath{fill:#333333;}#mermaid-svg-VOiI81BqzrSAukt6 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-VOiI81BqzrSAukt6 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-VOiI81BqzrSAukt6 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VOiI81BqzrSAukt6 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-VOiI81BqzrSAukt6 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VOiI81BqzrSAukt6 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-VOiI81BqzrSAukt6 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-VOiI81BqzrSAukt6 .cluster text{fill:#333;}#mermaid-svg-VOiI81BqzrSAukt6 .cluster span{color:#333;}#mermaid-svg-VOiI81BqzrSAukt6 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-VOiI81BqzrSAukt6 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-VOiI81BqzrSAukt6 rect.text{fill:none;stroke-width:0;}#mermaid-svg-VOiI81BqzrSAukt6 .icon-shape,#mermaid-svg-VOiI81BqzrSAukt6 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VOiI81BqzrSAukt6 .icon-shape p,#mermaid-svg-VOiI81BqzrSAukt6 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-VOiI81BqzrSAukt6 .icon-shape .label rect,#mermaid-svg-VOiI81BqzrSAukt6 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VOiI81BqzrSAukt6 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-VOiI81BqzrSAukt6 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-VOiI81BqzrSAukt6 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
简单
中等
复杂
用户请求
分类器:这个问题复杂吗?
7B 小模型
70B 中模型
大模型
返回结果
三、优化思路2:Prompt压缩
很多人写 Prompt 喜欢写一大堆:
- 角色设定
- 背景信息
- 输出格式要求
- 各种示例
每次请求都把这些全部发给大模型,Token 消耗很大。
优化方法1:系统提示缓存
把固定的系统提示(角色设定、输出格式)做成缓存,不用每次都传。
现在很多 API 都支持 Prompt Caching 了。
优化方法2:示例动态化
不是所有示例都要放进去。根据用户问题的类型,动态选最相关的 1-2 个示例放进去就行。
优化方法3:长上下文截断
不要什么上下文都塞进去。只保留和当前问题最相关的部分。
Prompt 压缩的几种方法可以这样梳理:
#mermaid-svg-GPBIPFe0tzJ2QBgO{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-GPBIPFe0tzJ2QBgO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-GPBIPFe0tzJ2QBgO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-GPBIPFe0tzJ2QBgO .error-icon{fill:#552222;}#mermaid-svg-GPBIPFe0tzJ2QBgO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-GPBIPFe0tzJ2QBgO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-GPBIPFe0tzJ2QBgO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-GPBIPFe0tzJ2QBgO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-GPBIPFe0tzJ2QBgO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-GPBIPFe0tzJ2QBgO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-GPBIPFe0tzJ2QBgO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-GPBIPFe0tzJ2QBgO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-GPBIPFe0tzJ2QBgO .marker.cross{stroke:#333333;}#mermaid-svg-GPBIPFe0tzJ2QBgO svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-GPBIPFe0tzJ2QBgO p{margin:0;}#mermaid-svg-GPBIPFe0tzJ2QBgO .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-GPBIPFe0tzJ2QBgO .cluster-label text{fill:#333;}#mermaid-svg-GPBIPFe0tzJ2QBgO .cluster-label span{color:#333;}#mermaid-svg-GPBIPFe0tzJ2QBgO .cluster-label span p{background-color:transparent;}#mermaid-svg-GPBIPFe0tzJ2QBgO .label text,#mermaid-svg-GPBIPFe0tzJ2QBgO span{fill:#333;color:#333;}#mermaid-svg-GPBIPFe0tzJ2QBgO .node rect,#mermaid-svg-GPBIPFe0tzJ2QBgO .node circle,#mermaid-svg-GPBIPFe0tzJ2QBgO .node ellipse,#mermaid-svg-GPBIPFe0tzJ2QBgO .node polygon,#mermaid-svg-GPBIPFe0tzJ2QBgO .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-GPBIPFe0tzJ2QBgO .rough-node .label text,#mermaid-svg-GPBIPFe0tzJ2QBgO .node .label text,#mermaid-svg-GPBIPFe0tzJ2QBgO .image-shape .label,#mermaid-svg-GPBIPFe0tzJ2QBgO .icon-shape .label{text-anchor:middle;}#mermaid-svg-GPBIPFe0tzJ2QBgO .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-GPBIPFe0tzJ2QBgO .rough-node .label,#mermaid-svg-GPBIPFe0tzJ2QBgO .node .label,#mermaid-svg-GPBIPFe0tzJ2QBgO .image-shape .label,#mermaid-svg-GPBIPFe0tzJ2QBgO .icon-shape .label{text-align:center;}#mermaid-svg-GPBIPFe0tzJ2QBgO .node.clickable{cursor:pointer;}#mermaid-svg-GPBIPFe0tzJ2QBgO .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-GPBIPFe0tzJ2QBgO .arrowheadPath{fill:#333333;}#mermaid-svg-GPBIPFe0tzJ2QBgO .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-GPBIPFe0tzJ2QBgO .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-GPBIPFe0tzJ2QBgO .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GPBIPFe0tzJ2QBgO .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-GPBIPFe0tzJ2QBgO .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GPBIPFe0tzJ2QBgO .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-GPBIPFe0tzJ2QBgO .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-GPBIPFe0tzJ2QBgO .cluster text{fill:#333;}#mermaid-svg-GPBIPFe0tzJ2QBgO .cluster span{color:#333;}#mermaid-svg-GPBIPFe0tzJ2QBgO div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-GPBIPFe0tzJ2QBgO .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-GPBIPFe0tzJ2QBgO rect.text{fill:none;stroke-width:0;}#mermaid-svg-GPBIPFe0tzJ2QBgO .icon-shape,#mermaid-svg-GPBIPFe0tzJ2QBgO .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GPBIPFe0tzJ2QBgO .icon-shape p,#mermaid-svg-GPBIPFe0tzJ2QBgO .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-GPBIPFe0tzJ2QBgO .icon-shape .label rect,#mermaid-svg-GPBIPFe0tzJ2QBgO .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GPBIPFe0tzJ2QBgO .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-GPBIPFe0tzJ2QBgO .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-GPBIPFe0tzJ2QBgO :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
原始 Prompt
系统提示缓存
示例动态化
长上下文截断
精简后的 Prompt
发送给大模型
四、优化思路3:结果缓存
很多问题是重复的:
- “你们营业时间是几点?”
- “你们地址在哪?”
- “这个产品多少钱?”
这些问题每次都调用大模型,纯属浪费钱。
怎么做
# 简单的缓存逻辑
cache = {}
def answer_question(question):
# 先查缓存
if question in cache:
return cache[question]
# 缓存没有,调用大模型
result = llm.chat(question)
# 存缓存
cache[question] = result
return result
进阶版
- 用向量数据库做语义缓存
- 意思相近的问题,直接用缓存的答案
- 命中率能到 30-50%
这部分成本直接省掉一半。
结果缓存的判断流程如下:
#mermaid-svg-WBnkFwcymnJUq963{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-WBnkFwcymnJUq963 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-WBnkFwcymnJUq963 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-WBnkFwcymnJUq963 .error-icon{fill:#552222;}#mermaid-svg-WBnkFwcymnJUq963 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-WBnkFwcymnJUq963 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-WBnkFwcymnJUq963 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-WBnkFwcymnJUq963 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-WBnkFwcymnJUq963 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-WBnkFwcymnJUq963 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-WBnkFwcymnJUq963 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-WBnkFwcymnJUq963 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-WBnkFwcymnJUq963 .marker.cross{stroke:#333333;}#mermaid-svg-WBnkFwcymnJUq963 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-WBnkFwcymnJUq963 p{margin:0;}#mermaid-svg-WBnkFwcymnJUq963 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-WBnkFwcymnJUq963 .cluster-label text{fill:#333;}#mermaid-svg-WBnkFwcymnJUq963 .cluster-label span{color:#333;}#mermaid-svg-WBnkFwcymnJUq963 .cluster-label span p{background-color:transparent;}#mermaid-svg-WBnkFwcymnJUq963 .label text,#mermaid-svg-WBnkFwcymnJUq963 span{fill:#333;color:#333;}#mermaid-svg-WBnkFwcymnJUq963 .node rect,#mermaid-svg-WBnkFwcymnJUq963 .node circle,#mermaid-svg-WBnkFwcymnJUq963 .node ellipse,#mermaid-svg-WBnkFwcymnJUq963 .node polygon,#mermaid-svg-WBnkFwcymnJUq963 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-WBnkFwcymnJUq963 .rough-node .label text,#mermaid-svg-WBnkFwcymnJUq963 .node .label text,#mermaid-svg-WBnkFwcymnJUq963 .image-shape .label,#mermaid-svg-WBnkFwcymnJUq963 .icon-shape .label{text-anchor:middle;}#mermaid-svg-WBnkFwcymnJUq963 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-WBnkFwcymnJUq963 .rough-node .label,#mermaid-svg-WBnkFwcymnJUq963 .node .label,#mermaid-svg-WBnkFwcymnJUq963 .image-shape .label,#mermaid-svg-WBnkFwcymnJUq963 .icon-shape .label{text-align:center;}#mermaid-svg-WBnkFwcymnJUq963 .node.clickable{cursor:pointer;}#mermaid-svg-WBnkFwcymnJUq963 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-WBnkFwcymnJUq963 .arrowheadPath{fill:#333333;}#mermaid-svg-WBnkFwcymnJUq963 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-WBnkFwcymnJUq963 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-WBnkFwcymnJUq963 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WBnkFwcymnJUq963 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-WBnkFwcymnJUq963 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WBnkFwcymnJUq963 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-WBnkFwcymnJUq963 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-WBnkFwcymnJUq963 .cluster text{fill:#333;}#mermaid-svg-WBnkFwcymnJUq963 .cluster span{color:#333;}#mermaid-svg-WBnkFwcymnJUq963 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-WBnkFwcymnJUq963 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-WBnkFwcymnJUq963 rect.text{fill:none;stroke-width:0;}#mermaid-svg-WBnkFwcymnJUq963 .icon-shape,#mermaid-svg-WBnkFwcymnJUq963 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WBnkFwcymnJUq963 .icon-shape p,#mermaid-svg-WBnkFwcymnJUq963 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-WBnkFwcymnJUq963 .icon-shape .label rect,#mermaid-svg-WBnkFwcymnJUq963 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WBnkFwcymnJUq963 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-WBnkFwcymnJUq963 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-WBnkFwcymnJUq963 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
有
没有
用户提问
缓存中有答案吗?
直接返回缓存结果
调用大模型
将结果存入缓存
返回结果
五、优化思路4:流式输出+提前结束
大模型输出是一个token一个token生成的。
如果用户看到前几个token就知道答案了,后面的token就没必要继续生成了。
怎么做
- 流式输出
- 检测到输出已经完整了,就停止生成
- 不用非得生到最大长度
特别是做客服场景,很多问题答案很短,不用生一大堆废话。
六、优化思路5:用开源模型自部署
如果你的请求量很大(每天几十万次),用 API 就不划算了。
这时候可以考虑自部署开源模型:
- Qwen 72B
- Llama 3 70B
- DeepSeek V3
成本对比
| 调 API | 1-10 万+ | 小流量验证 |
| 自部署 | 固定几万(GPU 服务器) | 大流量稳定运行 |
| 混合方案(API+自部署) | 自部署固定成本 + API 按量成本 | 流量波动大、从验证期向稳定期过渡 |
| 当每天请求量超过 10 万次,自部署就比调 API 划算了。 |
混合方案:什么时候用、怎么算成本
如果流量波动很大(比如白天高峰、夜间低谷,或大促期间暴涨),直接全量自部署可能浪费 GPU 资源,全量调 API 又太贵。这时候可以走混合方案:把稳定的基础流量交给自部署模型扛,把突发的峰值流量走 API 兜底。
适合的流量规模: 日均请求量在 5 万-20 万之间、且存在明显波峰波谷的场景。低于 5 万直接调 API 更省心,高于 20 万且流量稳定则建议全量自部署。
成本估算逻辑:
- 自部署部分:按峰值预留 70% 的 GPU 容量,月成本 = GPU 服务器固定费用(如 3 万/月)。
- API 部分:剩余 30% 的突发流量按 API 单价计费,月成本 = 突发 token 量 × 单价。
- 总成本 = 自部署固定成本 + API 按量成本。
举个例子:某应用日均 10 万请求,其中 7 万走自部署(月固定 3 万),3 万走 API(按 $0.03/1K tokens 算,约 1.5 万),混合方案月成本约 4.5 万,比全 API 的 6-8 万省不少,又比全自部署更抗流量波动。
七、优化思路6:批量处理
如果有很多离线任务要处理(比如批量总结文章、批量生成文案),不要一个个调。
用批量API:
- 一次提交1000个请求
- 价格打5折
- 异步处理,不着急的任务慢慢跑
很多API厂商的批量任务都有折扣,能省不少钱。
八、成本监控和告警
优化不是一次性的事,要持续监控:
很多时候成本暴涨是因为:
- 死循环了
- Prompt 写错了
- 用户刷接口了
有监控才能及时发现问题。
下面是一个简单的 Python 示例,用日志记录每次调用的 token 消耗,再按天聚合统计,超过阈值就触发告警:
import time
from collections import defaultdict
from datetime import date
# 模拟:记录每次调用的 token 消耗
daily_tokens = defaultdict(int)
COST_PER_1K = 0.03 # 每 1K token 的成本(美元)
DAILY_BUDGET = 50 # 每日成本阈值(美元)
def log_usage(prompt_tokens, completion_tokens):
"""每次调用大模型后,记录 token 消耗"""
today = str(date.today())
daily_tokens[today] += prompt_tokens + completion_tokens
def check_daily_cost():
"""每天结束时检查成本,超过阈值就告警"""
today = str(date.today())
total_tokens = daily_tokens[today]
cost = total_tokens / 1000 * COST_PER_1K
if cost > DAILY_BUDGET:
# 实际项目中这里可以接入钉钉/企业微信/邮件等告警
print(f"[ALERT] 今日成本 ${cost:.2f} 已超过阈值 ${DAILY_BUDGET},请检查!")
else:
print(f"[INFO] 今日成本 ${cost:.2f},在预算范围内。")
# 模拟几次调用
log_usage(1500, 500) # 某次请求消耗 2000 token
log_usage(3000, 1000) # 某次请求消耗 4000 token
check_daily_cost()
如果想用 Prometheus + Grafana 做可视化监控,思路也类似:把每次调用的 token 数作为指标暴露给 Prometheus(比如用 prometheus_client 的 Counter),Grafana 里按天聚合展示,再配一个 Alert 规则,当 cost > 阈值 时自动告警。核心逻辑都是「先记录,再聚合,超阈值就报警」。
常见成本异常的排查步骤
成本暴涨时别慌,按下面的清单一步步排查:
监控指标建议
| 请求量(QPS) | 每秒调用次数 | 超过平时均值 3 倍触发告警 |
| 单次请求 token 数 | 平均每次消耗的 token | 超过平时均值 2 倍触发告警 |
| 每日 token 消耗总量 | 当天累计消耗 | 超过预算的 80% 触发预警,100% 触发告警 |
| 错误率 | 调用失败的占比 | 超过 5% 触发告警 |
| 重试次数 | 单次请求的重试次数 | 超过 3 次触发告警 |
| 单用户调用频率 | 单个用户的 QPS | 超过 10 次/秒触发告警 |
核心思路:先看请求量有没有变,再看单次 token 有没有变,最后按用户和功能定位到具体问题。 把这几类指标配上阈值,成本异常基本都能第一时间发现。
成本监控与告警的完整流程可以这样设计:
#mermaid-svg-HdaXEwPoqLDRioM6{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-HdaXEwPoqLDRioM6 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-HdaXEwPoqLDRioM6 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-HdaXEwPoqLDRioM6 .error-icon{fill:#552222;}#mermaid-svg-HdaXEwPoqLDRioM6 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-HdaXEwPoqLDRioM6 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-HdaXEwPoqLDRioM6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-HdaXEwPoqLDRioM6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-HdaXEwPoqLDRioM6 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-HdaXEwPoqLDRioM6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-HdaXEwPoqLDRioM6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-HdaXEwPoqLDRioM6 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-HdaXEwPoqLDRioM6 .marker.cross{stroke:#333333;}#mermaid-svg-HdaXEwPoqLDRioM6 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-HdaXEwPoqLDRioM6 p{margin:0;}#mermaid-svg-HdaXEwPoqLDRioM6 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-HdaXEwPoqLDRioM6 .cluster-label text{fill:#333;}#mermaid-svg-HdaXEwPoqLDRioM6 .cluster-label span{color:#333;}#mermaid-svg-HdaXEwPoqLDRioM6 .cluster-label span p{background-color:transparent;}#mermaid-svg-HdaXEwPoqLDRioM6 .label text,#mermaid-svg-HdaXEwPoqLDRioM6 span{fill:#333;color:#333;}#mermaid-svg-HdaXEwPoqLDRioM6 .node rect,#mermaid-svg-HdaXEwPoqLDRioM6 .node circle,#mermaid-svg-HdaXEwPoqLDRioM6 .node ellipse,#mermaid-svg-HdaXEwPoqLDRioM6 .node polygon,#mermaid-svg-HdaXEwPoqLDRioM6 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-HdaXEwPoqLDRioM6 .rough-node .label text,#mermaid-svg-HdaXEwPoqLDRioM6 .node .label text,#mermaid-svg-HdaXEwPoqLDRioM6 .image-shape .label,#mermaid-svg-HdaXEwPoqLDRioM6 .icon-shape .label{text-anchor:middle;}#mermaid-svg-HdaXEwPoqLDRioM6 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-HdaXEwPoqLDRioM6 .rough-node .label,#mermaid-svg-HdaXEwPoqLDRioM6 .node .label,#mermaid-svg-HdaXEwPoqLDRioM6 .image-shape .label,#mermaid-svg-HdaXEwPoqLDRioM6 .icon-shape .label{text-align:center;}#mermaid-svg-HdaXEwPoqLDRioM6 .node.clickable{cursor:pointer;}#mermaid-svg-HdaXEwPoqLDRioM6 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-HdaXEwPoqLDRioM6 .arrowheadPath{fill:#333333;}#mermaid-svg-HdaXEwPoqLDRioM6 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-HdaXEwPoqLDRioM6 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-HdaXEwPoqLDRioM6 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HdaXEwPoqLDRioM6 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-HdaXEwPoqLDRioM6 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HdaXEwPoqLDRioM6 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-HdaXEwPoqLDRioM6 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-HdaXEwPoqLDRioM6 .cluster text{fill:#333;}#mermaid-svg-HdaXEwPoqLDRioM6 .cluster span{color:#333;}#mermaid-svg-HdaXEwPoqLDRioM6 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-HdaXEwPoqLDRioM6 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-HdaXEwPoqLDRioM6 rect.text{fill:none;stroke-width:0;}#mermaid-svg-HdaXEwPoqLDRioM6 .icon-shape,#mermaid-svg-HdaXEwPoqLDRioM6 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HdaXEwPoqLDRioM6 .icon-shape p,#mermaid-svg-HdaXEwPoqLDRioM6 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-HdaXEwPoqLDRioM6 .icon-shape .label rect,#mermaid-svg-HdaXEwPoqLDRioM6 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HdaXEwPoqLDRioM6 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-HdaXEwPoqLDRioM6 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-HdaXEwPoqLDRioM6 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
是
否
每次调用大模型
记录 token 消耗
按天/按用户/按功能聚合
成本是否超过阈值?
触发告警
继续监控
排查异常原因
定位问题并修复
九、总结一下
LLM成本优化的几个核心方向:
| 模型分层调用 | 70-80% | 中 |
| 结果缓存 | 30-50% | 低 |
| Prompt压缩 | 20-30% | 低 |
| 自部署开源模型 | 50%+(大流量时) | 高 |
| 批量处理 | 30-50% | 低 |
最划算的组合:模型分层 + 结果缓存 + Prompt压缩
不用动架构,改改代码就能省一半以上的成本。
先把这几个简单的做了,再考虑要不要自部署。
网硕互联帮助中心




评论前必须登录!
注册