初级专栏 JAN 10, 2026

AI 应用的成本优化:从月花 $100 到 $5

#成本优化#AI工程化#缓存策略#Prompt优化

AI 应用的成本优化:从月花 $100 到 $5

本文是【前端转 AI 全栈实战】系列第 23 篇。 上一篇:多模态 AI API:不只是文本,图片和语音也能玩 | 下一篇:AI 应用的测试和质量保障


这篇文章你会得到什么

做 AI 应用最容易被忽视的问题——花钱太快

一个小项目,每天几百次 API 调用,用 GPT-4o 一个月就是几百美元。如果上线后用户量增长,成本可以指数级爆炸。

但大多数场景下,90% 的成本是可以省掉的。这一篇教你怎么从月花 $100 降到 $5,而且效果几乎不变。


Token 计费基础

什么是 Token

Token ≈ 词的碎片。英文大约 1 token = 0.75 个单词,中文大约 1 token = 0.5-1 个字。

"Hello, world!" → 4 tokens
"你好,世界!" → 4-5 tokens (取决于模型的分词器)

Input vs Output 定价不同

模型Input 价格Output 价格说明
GPT-4o$2.5/M$10/M贵但综合能力强
GPT-4o-mini$0.15/M$0.6/M便宜 16 倍
DeepSeek Chat¥1/M¥2/M国产性价比王
Claude 3.5 Sonnet$3/M$15/M推理强但 output 贵

M = 百万 tokens

一次调用成本计算

function estimateCost(inputTokens, outputTokens, model = "gpt-4o-mini") {
  const pricing = {
    "gpt-4o":      { input: 2.5,  output: 10 },
    "gpt-4o-mini": { input: 0.15, output: 0.6 },
    "deepseek":    { input: 0.14, output: 0.28 }, // ¥1/M ≈ $0.14/M
  };

  const p = pricing[model];
  const cost = (inputTokens * p.input + outputTokens * p.output) / 1_000_000;
  return cost; // 美元
}

// 一次对话:500 input + 200 output
estimateCost(500, 200, "gpt-4o");      // $0.00325
estimateCost(500, 200, "gpt-4o-mini"); // $0.000195  ← 便宜 16 倍
estimateCost(500, 200, "deepseek");    // $0.000126  ← 便宜 25 倍

策略一:模型降级——80% 的任务不需要顶级模型

这是最有效的一招。

任务类型推荐模型为什么
简单分类/提取GPT-4o-mini / DeepSeek准确率差距 <5%
翻译DeepSeek中英翻译质量很好
代码生成Claude 3.5 Sonnet代码质量明显更好
文本摘要GPT-4o-mini够用
复杂推理/分析GPT-4o / Claude只有这类才值得用贵模型
JSON 结构化输出GPT-4o-mini格式稳定
function selectModel(taskType) {
  const modelMap = {
    classify:    "deepseek-chat",
    translate:   "deepseek-chat",
    summarize:   "gpt-4o-mini",
    generate:    "gpt-4o-mini",
    code:        "claude-3-5-sonnet-20241022",
    reasoning:   "gpt-4o",
  };
  return modelMap[taskType] || "gpt-4o-mini";
}

实际效果:把默认模型从 GPT-4o 换成 GPT-4o-mini,月成本直降 90%+。


策略二:Prompt 压缩

Prompt 越长,input token 越多,成本越高。

精简 System Prompt

❌ 冗长版(~300 tokens):
"你是一个专业的技术文档翻译专家,擅长将英文技术文档翻译成中文。你需要
保持原文的技术准确性,同时使用自然流畅的中文表达。对于专业术语,保留
英文原文并在括号中给出中文解释。请确保翻译后的文本格式与原文一致,
包括标题层级、代码块、列表等。不要添加原文没有的内容..."

✅ 精简版(~80 tokens):
"技术文档翻译。规则:保留术语英文+括号中文、保持格式、不加内容。"

省了 ~220 tokens,每次调用节省 ~70%。一万次调用就是 220 万 tokens。

动态上下文——只传需要的

// ❌ 每次都传完整的对话历史
messages: fullHistory // 可能 50 条消息,几千 tokens

// ✅ 只传最近 N 条
function trimHistory(history, maxMessages = 10) {
  if (history.length <= maxMessages) return history;
  const systemMsg = history.find(m => m.role === "system");
  const recent = history.slice(-maxMessages);
  return systemMsg ? [systemMsg, ...recent] : recent;
}

上下文摘要压缩

async function compressHistory(history) {
  if (history.length < 20) return history;

  // 把前面的对话压缩成摘要
  const oldMessages = history.slice(0, -10);
  const recentMessages = history.slice(-10);

  const summary = await callAI(
    "用 100 字概括以下对话的关键信息",
    oldMessages.map(m => `${m.role}: ${m.content}`).join("\n"),
    { model: "gpt-4o-mini", max_tokens: 200 }
  );

  return [
    { role: "system", content: `之前的对话摘要:${summary}` },
    ...recentMessages,
  ];
}

策略三:缓存——相同问题不重复花钱

很多 AI 调用的输入是重复的。同一个页面翻译、同一段代码审查——结果都一样,为什么要花两次钱?

简单内存缓存

const cache = new Map();

async function callAIWithCache(prompt, options = {}) {
  const cacheKey = JSON.stringify({ prompt, model: options.model });
  const ttl = options.cacheTTL || 3600000; // 默认 1 小时

  const cached = cache.get(cacheKey);
  if (cached && Date.now() - cached.time < ttl) {
    return cached.result;
  }

  const result = await callAI(prompt, options);

  cache.set(cacheKey, { result, time: Date.now() });

  // 防止内存泄漏
  if (cache.size > 1000) {
    const oldest = cache.keys().next().value;
    cache.delete(oldest);
  }

  return result;
}

Redis 缓存(生产环境)

import hashlib
import json
import redis

r = redis.Redis(host="localhost", port=6379, db=0)

def call_ai_cached(prompt: str, model: str = "gpt-4o-mini", ttl: int = 3600):
    cache_key = f"ai:{hashlib.md5(f'{model}:{prompt}'.encode()).hexdigest()}"

    cached = r.get(cache_key)
    if cached:
        return json.loads(cached)

    result = call_ai(prompt, model=model)

    r.setex(cache_key, ttl, json.dumps(result, ensure_ascii=False))
    return result

语义缓存(高级)

“请假流程是什么”和”怎么请假”是同一个问题,但文本不同。

用 Embedding 做相似度匹配,语义相似的问题命中同一条缓存:

def semantic_cache_get(query: str, threshold: float = 0.95):
    query_embedding = get_embedding(query)

    # 在已有缓存的 embedding 中找最相似的
    for key, item in cache_store.items():
        similarity = cosine_similarity(query_embedding, item["embedding"])
        if similarity > threshold:
            return item["result"]

    return None

策略四:本地模型兜底

用 Ollama 跑本地小模型,处理简单任务完全免费

# 安装 Ollama(本地运行 AI 模型)
# https://ollama.ai
ollama pull qwen2:7b    # 通义千问 7B,中文好
ollama pull llama3:8b    # Llama 3 8B,英文好
// Ollama API 兼容 OpenAI 格式
import OpenAI from "openai";

const localClient = new OpenAI({
  baseURL: "http://localhost:11434/v1",
  apiKey: "ollama", // Ollama 不需要 key,随便填
});

async function callLocal(prompt) {
  const response = await localClient.chat.completions.create({
    model: "qwen2:7b",
    messages: [{ role: "user", content: prompt }],
  });
  return response.choices[0].message.content;
}

分级策略

async function smartCall(prompt, taskType) {
  // 简单任务 → 本地模型(免费)
  if (["classify", "extract_keywords", "format"].includes(taskType)) {
    return callLocal(prompt);
  }

  // 中等任务 → 便宜的云模型
  if (["translate", "summarize", "qa"].includes(taskType)) {
    return callCloud(prompt, { model: "deepseek-chat" });
  }

  // 复杂任务 → 最好的模型
  return callCloud(prompt, { model: "gpt-4o" });
}

策略五:减少不必要的调用

前端防抖

// 用户打字时不要每个字都调 AI
function debounce(fn, delay = 1000) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
  };
}

const debouncedAI = debounce(async (input) => {
  const result = await callAI(input);
  renderResult(result);
}, 1000);

inputEl.addEventListener("input", (e) => debouncedAI(e.target.value));

客户端预判断

async function handleUserInput(input) {
  // 太短的输入不调 AI
  if (input.trim().length < 5) {
    return "请输入更详细的问题";
  }

  // 纯打招呼不调 AI
  const greetings = ["你好", "hi", "hello", "在吗"];
  if (greetings.includes(input.trim().toLowerCase())) {
    return "你好!有什么可以帮你的?";
  }

  // 重复问题不调 AI
  if (input === lastInput) {
    return lastResult;
  }

  return callAI(input);
}

限制 max_tokens

// ❌ 不设限,AI 可能输出 4000 tokens
await callAI(prompt);

// ✅ 按任务设限
await callAI(prompt, { max_tokens: 200 });  // 分类任务
await callAI(prompt, { max_tokens: 500 });  // 摘要任务
await callAI(prompt, { max_tokens: 2000 }); // 代码生成

成本监控

不监控就不知道钱花在哪。

# 简单的成本追踪
import time

class CostTracker:
    def __init__(self):
        self.records = []

    def log(self, model, input_tokens, output_tokens, task_type):
        pricing = {
            "gpt-4o":      {"input": 2.5,  "output": 10},
            "gpt-4o-mini": {"input": 0.15, "output": 0.6},
            "deepseek":    {"input": 0.14, "output": 0.28},
        }
        p = pricing.get(model, pricing["gpt-4o-mini"])
        cost = (input_tokens * p["input"] + output_tokens * p["output"]) / 1_000_000

        self.records.append({
            "time": time.time(),
            "model": model,
            "input_tokens": input_tokens,
            "output_tokens": output_tokens,
            "cost": cost,
            "task_type": task_type,
        })

    def daily_report(self):
        today = [r for r in self.records if r["time"] > time.time() - 86400]
        total_cost = sum(r["cost"] for r in today)
        by_model = {}
        for r in today:
            by_model.setdefault(r["model"], 0)
            by_model[r["model"]] += r["cost"]

        return {
            "total_cost": f"${total_cost:.4f}",
            "calls": len(today),
            "by_model": by_model,
        }

优化效果对比

假设一个 AI 应用每天 1000 次调用,每次平均 500 input + 300 output tokens:

策略月成本节省
全用 GPT-4o$127.5-
换 GPT-4o-mini$7.6594%
+ Prompt 压缩 30%$5.3696%
+ 缓存命中 50%$2.6898%
+ 简单任务用本地模型$1.3499%

从 $127 降到 $1.34,效果几乎不变。


总结

  1. 模型降级是最大杠杆——80% 的任务用 GPT-4o-mini 或 DeepSeek 就够了。
  2. Prompt 压缩——精简 System Prompt、动态裁剪上下文、摘要压缩历史。
  3. 缓存——内存缓存 / Redis 缓存 / 语义缓存,相同问题不花两次钱。
  4. 本地模型兜底——Ollama + 小模型处理简单任务,完全免费。
  5. 减少不必要调用——前端防抖、预判断、限制 max_tokens。
  6. 监控——记录每次调用的 model、tokens、cost,才知道钱花在哪。

下一篇预告24 | AI 应用的测试和质量保障


讨论话题:你的 AI 项目每月花多少钱?用了什么省钱策略?评论区聊聊。

评论