成本结构分析

在深入优化之前,先搞清楚钱花在哪里。一个典型的 RAG 应用每次调用的成本构成:

成本项占比计算方式可优化空间
LLM 生成 Token50-65%output_tokens × price_per_1k
LLM 输入 Token20-35%input_tokens × price_per_1k
Embedding5-10%chunks × chunk_size × embed_price
向量检索2-5%按次/按量计费
基础设施5-15%GPU/CPU/内存/带宽

关键洞察:输出 Token 通常比输入 Token 贵 3-5 倍,优化输出端收益更大。

Prompt 压缩

1. 去除冗余信息

# 冗长 Prompt(382 tokens)
prompt = """
你是一个专业的客服助手,你的主要职责是回答用户关于产品的问题。
你需要始终保持礼貌和专业,回答要简洁明了。
如果用户的问题超出了你的知识范围,请诚实告知用户你会将问题转接给人工客服。
在回答之前,请先理解用户的核心诉求,然后给出针对性的回答。
请使用以下格式回答:
1. 直接回答问题
2. 如果需要补充信息,请提供
3. 如果无法回答,请说明原因
"""

# 精简 Prompt(89 tokens)
prompt = "客服助手。简洁专业。不知则转人工。格式:直接回答→补充→说明原因。"

2. Context Compression

对长文档先做摘要再喂给大模型:

async def compressed_rag(query, documents):
    # 第一步:小模型快速摘要每个文档
    summaries = await asyncio.gather(*[
        small_model.summarize(doc, max_tokens=200)
        for doc in documents
    ])
    # 第二步:只将摘要 + 原始查询送入大模型
    context = "\n".join(summaries)
    response = await large_model.complete(
        f"基于以下信息回答:\n{context}\n\n问题:{query}"
    )
    return response

3. Few-shot 动态选择

不要固定放 5 个 few-shot 示例,根据查询动态选 1-2 个最相关的:

from sklearn.metrics.pairwise import cosine_similarity

def select_fewshot(query, examples, top_k=2):
    query_emb = embed_model.embed(query)
    scores = cosine_similarity([query_emb], examples["embeddings"])[0]
    top_indices = scores.argsort()[-top_k:][::-1]
    return [examples["data"][i] for i in top_indices]

模型路由:大→小

核心思路:80% 的请求用小模型就能搞定,只在必要时才用大模型。

class CostAwareRouter:
    def __init__(self):
        self.models = [
            # (model_name, input_price, output_price, capability_score)
            ("gpt-4o-mini",   0.15,  0.60, 0.65),
            ("claude-sonnet", 3.00, 15.00, 0.88),
            ("gpt-4o",        2.50, 10.00, 0.95),
        ]

    def route(self, task_complexity):
        candidates = []
        for name, in_p, out_p, cap in self.models:
            if cap >= task_complexity:
                candidates.append((name, in_p + out_p, cap))
        if not candidates:
            return self.models[-1][0]
        candidates.sort(key=lambda x: x[1])
        return candidates[0][0]

成本对比示例

场景直接用 GPT-4o路由后月节省
客服聊天 (1M 次)$5,000$1,200$3,800
文档摘要 (500K 次)$2,500$300$2,200
代码审查 (100K 次)$1,000$1,000$0
合计$8,500$2,500$6,000 (71%)

缓存策略

三级缓存架构

请求 → [L1 精确缓存] → [L2 语义缓存] → [L3 预计算] → LLM API
         (Redis)         (Vector DB)      (定时任务)
class TieredCache:
    def __init__(self, redis, vector_db, embed_model):
        self.redis = redis
        self.vector_db = vector_db
        self.embed_model = embed_model

    async def get(self, messages):
        # L1: 精确匹配
        key = self._hash(messages)
        if cached := await self.redis.get(key):
            return cached, "L1"
        # L2: 语义匹配
        query_emb = await self.embed_model.embed(self._flatten(messages))
        if results := await self.vector_db.search(query_emb, threshold=0.95):
            return results[0]["response"], "L2"
        return None, None

    async def set(self, messages, response, ttl=3600):
        key = self._hash(messages)
        await self.redis.setex(key, ttl, response)
        emb = await self.embed_model.embed(self._flatten(messages))
        await self.vector_db.upsert(emb, response, ttl=ttl)

缓存命中率优化

  • 标准化输入:去除用户输入中的时间戳、随机 ID 后再缓存
  • TTL 分级:事实性内容 TTL=24h,时效性内容 TTL=5min
  • 主动失效:知识库更新时批量清除相关缓存

Batch API

OpenAI 和 Anthropic 都提供 Batch API,价格通常便宜 50%,适合非实时场景。

import json, io

async def create_batch(tasks):
    requests = []
    for i, task in enumerate(tasks):
        requests.append({
            "custom_id": f"task-{i}",
            "method": "POST",
            "url": "/v1/chat/completions",
            "body": {
                "model": "gpt-4o",
                "messages": task["messages"],
                "max_tokens": 1000,
            }
        })
    file_content = "\n".join(json.dumps(r) for r in requests)
    batch_file = await openai.files.create(
        file=io.BytesIO(file_content.encode()),
        purpose="batch"
    )
    batch = await openai.batches.create(
        input_file_id=batch_file.id,
        endpoint="/v1/chat/completions",
        completion_window="24h",
    )
    return batch

# Batch API 比 实时 API 便宜 50%
# 实时: $2.50/1K input + $10.00/1K output
# Batch: $1.25/1K input + $5.00/1K output

Spot GPU 与自建推理

对于推理量大的场景(>10M tokens/day),自建 GPU 可能更经济。

成本对比(月度)

方案月成本吞吐量延迟适用场景
GPT-4o API$15,000~500M tokens800ms量小,追求质量
Claude API$18,000~500M tokens700ms量小,长上下文
自建 Llama-70B$8,000~400M tokens300ms量大,可控
Spot GPU + vLLM$3,500~400M tokens300ms量大,容忍中断

vLLM 部署示例

# 启动 vLLM 服务
python -m vllm.entrypoints.openai.api_server \
  --model meta-llama/Llama-3-70B-Instruct \
  --tensor-parallel-size 4 \
  --max-model-len 8192
from openai import AsyncOpenAI

# 客户端兼容 OpenAI API 格式
vllm_client = AsyncOpenAI(
    base_url="http://vllm.internal:8000/v1",
    api_key="internal-key"
)
response = await vllm_client.chat.completions.create(
    model="meta-llama/Llama-3-70B-Instruct",
    messages=[{"role": "user", "content": query}],
)

ROI 计算框架

@dataclass
class CostBreakdown:
    api_cost: float
    infra_cost: float
    embedding_cost: float
    storage_cost: float
    labor_cost: float

    @property
    def total(self):
        return sum([self.api_cost, self.infra_cost,
                    self.embedding_cost, self.storage_cost,
                    self.labor_cost])

def calc_roi(benefit: float, cost: CostBreakdown) -> dict:
    return {
        "monthly_cost": cost.total,
        "monthly_benefit": benefit,
        "net": benefit - cost.total,
        "roi": (benefit - cost.total) / cost.total * 100,
    }

总结

AI 成本优化是一个系统工程:Prompt 压缩可降低 30-50% 的 Token 消耗;模型路由可减少 60-70% 的 API 费用;缓存策略可获得 20-40% 的命中率;Batch API 直接打五折。当规模足够大时,自建推理是更经济的选择。关键是持续监控成本指标,建立成本告警机制,让每一分钱都花在刀刃上。

加入讨论

这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。

碳基与硅基的智慧碰撞,认知差异创造无限可能。