AI 应用的成本控制:从每月 4500 降到 900 的实操

AI 应用的成本失控往往不是因为「模型太贵」,而是因为设计上没做任何节约:每次都全文重发、不用缓存、不控制输出长度、不看 trace。这篇给一套可落地的降本方法,按投入产出排。

一、先搞清楚钱花在哪

# 每次调用的成本构成
1. 输入 token × 输入单价 + 输出 token × 输出单价
1. 注意:输出单价通常是输入的 2-4 倍

1. 实例:某次 RAG 问答
1. 系统提示词 300 + 检索片段 1500 + 用户问题 20 = 1820 输入
1. 生成回答 400 输出
1. 假设每百万 token 输入 ¥5、输出 ¥15
1. 成本 = 1820/1e6 * 5 + 400/1e6 * 15 ≈ ¥0.015 / 次
1. 1 万次/天 → ¥150/天 → ¥4500/月

第一个关键认知:输入是主要成本,不是输出。RAG 场景里检索片段常占输入的 80% 以上。

二、降本手段排序(按投入产出)

手段 降本幅度 实现难度 优先级
缓存相同请求 视重复率,10-50% 低 最高
压缩检索片段数量 20-40% 低 高
限制输出长度 10-30% 低 高
精简系统提示词 5-15% 低 高
按任务路由到便宜模型 50-80% 中 高
批量合并请求 10-20% 中 中
本地模型承接简单任务 视分流比例 高 中

三、缓存:最大的一块免费收益

import hashlib, json
import redis.asyncio as redis

rdb = redis.from_url("redis://localhost:6379")

async def cached_chat(messages: list, model: str, **kw) -> dict:
    """只对「确定性」请求做缓存(temperature=0 或很低)。"""
    key = "llm:" + hashlib.sha256(
        json.dumps({"m": messages, "model": model, "kw": kw},
                   sort_keys=True, ensure_ascii=False).encode()
    ).hexdigest()[:32]

    if (hit := await rdb.get(key)):
        return json.loads(hit)

    resp = await llm.chat(messages=messages, model=model, **kw)
    await rdb.setex(key, 3600, json.dumps(resp))     # 缓存 1 小时
    return resp
  • 只缓存 temperature≈0 的请求:创意类任务缓存会让用户拿到重复内容
  • 缓存键要包含完整上下文:model、messages、参数全都要,否则会串味
  • RAG 场景分两层缓存:检索结果单独缓存(更稳定),生成结果按「问题+片段哈希」缓存
  • TTL 要短:1-6 小时足够,太长会导致知识过期

四、压缩检索片段:少给但给准

import re

def lexical_overlap(sent: str, query: str) -> float:
    """句子与问题的字符 bigram 重叠率:中文不需要分词依赖即可用。"""
    def bigrams(t: str) -> set:
        t = re.sub(r'\s', '', t)
        return {t[i:i+2] for i in range(len(t) - 1)}
    a, b = bigrams(sent), bigrams(query)
    return len(a & b) / len(b) if b else 0.0

def compress_chunk(chunk: str, query: str, max_sentences: int = 3):
    """从块里挑与问题最相关的几句。"""
    sents = [s for s in re.split(r'(?<=[。!?])', chunk) if s.strip()]
    scored = sorted(sents, key=lambda s: lexical_overlap(s, query), reverse=True)
    return ''.join(scored[:max_sentences])

1. 效果:4000 字 → 约 1200 字,输入成本降 70%
1. 风险:压缩可能切掉上下文,要配合重排一起用
1. 另注:第三节的响应缓存不适用流式请求——流式返回的是迭代器,
1. 没法 json.dumps 落库,流式接口要单独处理(按增量输出完再缓存或干脆不缓存)

五、对账:4500 是怎么降到 900 的

标题的承诺要能对账。按第一节的基线(1 万次/天、单次 ¥0.015 ≈ ¥4500/月),把各手段的假设代入:

手段(假设) 计算 每月节省
缓存相同请求(重复率约 25%,命中零成本) 4500 × 25% ¥1125
压缩检索片段 + 精简提示词(输入 1820 → 820 token:片段 1500→500、提示词 300→200) 单次 ¥0.015 → 约 ¥0.010(输入 0.0041 + 输出 0.006),省 ¥0.005/次 × 22.5 万次/月 ¥1125
限制输出(400 → 200 token)+ 简单任务路由便宜模型(50% 流量、单价约 1/5) 输出省 ¥0.003/次;路由再省约 ¥0.0028/次,合计 ¥0.0058/次 × 22.5 万次/月 ¥1305

三项合计省约 ¥3555,最终约 ¥945/月——即标题说的「900 左右」。剩余成本来自未命中缓存的复杂请求(输入长、输出长、还要走贵模型)。假设一变账就变:重复率更低或简单任务占比更少,终值都会上移,这张表的口径比第二节的百分比区间更保守。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇