上一篇 下一篇 分享链接 返回 返回顶部

账单别先爆:AI 工具降本实战与网关源码分享

发布人:慈云数据-客服中心 发布时间:6小时前 阅读量:3

AI工具 如何降低成本|附源码

在过去几年里,AI 工具从“新鲜玩具”逐渐变成了企业和个人提升效率的生产力基础设施。无论是内容创作、客服答疑、数据分析、代码开发,还是合同审查、知识库问答、流程自动化,AI 都正在改变工作方式。

但很多团队在真正使用 AI 工具后,很快会遇到一个现实问题:成本越来越高

一开始只是几个人试用,每月几十美元;后来接入业务系统,调用量上升,模型费用、服务器费用、向量数据库费用、存储费用、人工维护费用叠加起来,成本可能迅速失控。尤其是当企业把 AI 能力嵌入到客服、办公系统、SaaS 产品或内部知识库中时,如果没有良好的成本控制机制,很容易出现“效果还没稳定,账单先爆炸”的情况。

本文将从实际落地角度,系统讲解 AI 工具如何降低成本,并提供一套可直接参考的源码示例,帮助你搭建一个具备缓存、模型路由、费用统计、限流控制能力的 AI 调用网关。


一、AI 工具成本主要来自哪里?

想要降低成本,首先要知道成本从哪里来。AI 工具的成本通常可以分为以下几类。

1. 模型调用费用

这是最直接的成本。

大语言模型通常按照 Token 收费,包括:

  • 输入 Token
  • 输出 Token
  • 上下文长度
  • 模型类型
  • 调用次数

例如,同样是一次问答,如果使用高性能模型,成本可能是轻量模型的数倍甚至数十倍。很多团队在早期开发时,为了追求效果,所有请求都使用最强模型,结果造成了大量不必要的浪费。

事实上,并不是所有任务都需要最贵的模型。

例如:

场景 推荐模型策略
简单分类 小模型即可
文本摘要 中等模型
复杂推理 高性能模型
代码生成 专用代码模型或高性能模型
FAQ 问答 RAG + 小模型
敏感合同审查 高性能模型 + 人工复核

2. 长上下文带来的费用

很多 AI 应用为了“让模型知道更多”,会把大量上下文直接塞进 Prompt 中。例如一次客服对话,把用户历史记录、产品文档、FAQ、系统规则全部拼进去。

这种做法虽然简单,但成本很高。

因为每次调用模型,都要重新计算这些输入 Token。假设一个请求包含 20,000 个输入 Token,一天调用 10,000 次,那么成本会非常可观。

更合理的方式是:

  • 使用向量检索,只取相关内容;
  • 对长文档做摘要;
  • 使用上下文缓存;
  • 对历史对话进行压缩;
  • 避免重复传递固定系统提示词。

3. 重复请求造成浪费

在真实业务中,很多用户问题其实高度重复。

例如:

  • “怎么退款?”
  • “发票在哪里开?”
  • “会员怎么取消?”
  • “这个功能怎么用?”
  • “忘记密码怎么办?”

如果每次都调用大模型生成答案,就会产生重复成本。对于高频、标准化问题,可以使用缓存或知识库直接返回答案。

4. 错误重试和无效调用

一些 AI 应用在接口失败时会自动重试,但如果没有控制策略,可能造成重复调用。

常见问题包括:

  • 超时后重复发起请求;
  • 前端用户连续点击导致重复请求;
  • 后端任务异常循环调用;
  • Prompt 写得不清晰导致模型反复补救;
  • 输出格式不稳定导致多次解析失败。

这些都会产生额外费用。

5. 人工维护成本

AI 成本不只是 API 费用,还包括人工成本。

如果系统没有日志、监控、评估、回放能力,出现问题后工程师需要手动排查 Prompt、输入、输出和模型参数,维护成本会越来越高。

所以,降低 AI 成本并不是单纯换一个便宜模型,而是要建立一套完整的工程化机制。


二、降低 AI 工具成本的核心思路

降低 AI 成本可以从以下几个方向入手。


1. 建立模型分层策略

不要让所有请求都走最贵模型。

可以把模型分为三层:

轻量模型

适合:

  • 意图识别
  • 文本分类
  • 标签提取
  • 简单问答
  • 格式转换
  • 简单摘要

特点是速度快、价格低。

中等模型

适合:

  • 普通内容生成
  • 文档摘要
  • 客服回复
  • 结构化抽取
  • 知识库问答

这是日常业务中使用频率最高的一层。

高性能模型

适合:

  • 复杂推理
  • 多步骤规划
  • 代码生成
  • 法务、金融、医疗等高风险场景
  • 高价值用户请求

高性能模型成本较高,应当只在真正需要时调用。

示例策略

如果用户问题长度 < 100 且属于 FAQ:使用缓存或小模型
如果需要知识库检索:使用中等模型 + RAG
如果涉及复杂推理或代码:使用高性能模型
如果模型置信度低:升级到更强模型

这种模型路由机制可以显著降低平均调用成本。


2. 使用缓存减少重复调用

缓存是降低 AI 成本最直接有效的方法之一。

适合缓存的内容包括:

  • 高频 FAQ;
  • 标准客服回答;
  • 文档摘要;
  • 翻译结果;
  • 分类结果;
  • 相同 Prompt 的输出;
  • RAG 检索结果。

缓存要注意什么?

AI 输出存在一定随机性,因此缓存不适合所有场景。

适合缓存的任务通常有以下特点:

  • 用户对答案一致性要求高;
  • 问题重复率高;
  • 输出不需要强个性化;
  • Prompt 和参数相对稳定;
  • 业务允许返回历史答案。

为了提升缓存命中率,可以对用户输入进行标准化,例如:

  • 去掉多余空格;
  • 转为小写;
  • 去除无意义标点;
  • 进行同义句归一;
  • 对 Prompt 做 Hash。

3. 使用 RAG 替代超长 Prompt

RAG,全称 Retrieval-Augmented Generation,即检索增强生成。

它的核心思路是:

不要把所有知识都塞给模型,而是先检索出最相关的几段内容,再交给模型生成答案。

这样可以大幅减少输入 Token。

例如,原来你可能会把 50 页产品文档全部放入 Prompt,现在只需要检索出最相关的 3 到 5 段内容。

这不仅降低成本,还能提高答案准确性。

RAG 的成本优化技巧

  • 文档切片不要太大;
  • 检索结果数量不要过多;
  • 对文档提前做摘要;
  • 高频问题直接缓存;
  • 使用便宜的 Embedding 模型;
  • 对向量检索结果做重排序;
  • 避免把无关内容放入 Prompt。

4. 压缩历史对话上下文

聊天机器人常见的成本黑洞就是历史上下文无限增长。

用户聊得越久,每次请求携带的历史消息越多,输入 Token 成本越来越高。

可以采用以下方法:

最近消息保留

只保留最近 5 到 10 轮对话。

摘要压缩

把较早的历史对话压缩成一段摘要。

例如:

用户之前询问过退款政策、发票申请和会员取消方式。
系统已经告知用户退款需要在订单页申请,发票可在账户中心开具。
用户当前主要关注会员取消后是否还能使用剩余权益。

重要信息抽取

只保存关键信息,例如:

{
  "user_plan": "高级会员",
  "order_status": "已支付",
  "main_intent": "取消会员",
  "previous_issue": "申请退款"
}

这种方法比保存完整对话更省 Token。


5. 控制输出长度

很多团队只关注输入 Token,却忽略输出 Token。实际上,输出越长,费用也越高。

可以通过 Prompt 明确要求:

  • 回答不超过 300 字;
  • 使用三条要点;
  • 只输出 JSON;
  • 不要解释过程;
  • 不要重复问题;
  • 不要输出无关内容。

例如:

请用不超过 150 字回答用户问题,只给出可执行步骤,不要输出寒暄内容。

对于客服、FAQ、分类、抽取等场景,限制输出长度非常有效。


6. 做好限流与预算控制

AI 系统一定要有预算意识。

建议设置以下限制:

  • 单用户每日调用次数;
  • 单用户每日 Token 上限;
  • 单接口 QPS;
  • 单业务线月度预算;
  • 高价模型调用审批;
  • 异常调用报警;
  • 失败重试次数限制。

如果没有限流机制,一次 Bug、一次爬虫攻击或一次异常循环任务,都可能造成巨大费用。


7. 监控每一次调用成本

很多 AI 成本失控,本质上是因为“不知道钱花在哪里”。

至少要记录以下信息:

  • 用户 ID;
  • 业务场景;
  • 使用模型;
  • 输入 Token;
  • 输出 Token;
  • 总费用;
  • 响应时间;
  • 是否命中缓存;
  • 是否触发重试;
  • 请求状态;
  • Prompt 版本。

当这些数据积累起来后,你就能回答几个关键问题:

  • 哪个业务线最费钱?
  • 哪类问题最常出现?
  • 哪个 Prompt 成本最高?
  • 哪个模型性价比最好?
  • 缓存命中率是多少?
  • 高价模型是否被滥用?

只有可观测,才能可优化。


三、AI 成本优化网关源码示例

下面提供一个简化版 AI 调用网关示例,使用 Node.js + Express 实现,具备以下功能:

  • AI 请求统一入口;
  • 简单模型路由;
  • Prompt Hash 缓存;
  • 费用估算;
  • 用户限流;
  • 调用日志记录;
  • 可替换为真实大模型 API。

说明:以下代码为教学示例,实际生产环境建议使用 Redis、数据库、消息队列、监控系统和更完善的鉴权机制。


1. 项目结构

ai-cost-gateway/
├── package.json
├── server.js
├── aiClient.js
├── cache.js
├── rateLimiter.js
├── cost.js
└── logger.js

2. package.json

{
  "name": "ai-cost-gateway",
  "version": "1.0.0",
  "description": "AI cost optimization gateway demo",
  "main": "server.js",
  "type": "commonjs",
  "scripts": {
    "start": "node server.js",
    "dev": "node server.js"
  },
  "dependencies": {
    "express": "^4.18.3",
    "crypto-js": "^4.2.0"
  }
}

安装依赖:

npm install

3. cache.js:简单内存缓存

const CryptoJS = require("crypto-js");

const cacheStore = new Map();

/**
 * 对输入内容生成稳定 Hash
 */
function createCacheKey(payload) {
  const raw = JSON.stringify(payload);
  return CryptoJS.SHA256(raw).toString();
}

/**
 * 获取缓存
 */
function getCache(key) {
  const item = cacheStore.get(key);

  if (!item) return null;

  const now = Date.now();

  if (item.expireAt && item.expireAt < now) {
    cacheStore.delete(key);
    return null;
  }

  return item.value;
}

/**
 * 设置缓存
 */
function setCache(key, value, ttlSeconds = 3600) {
  const expireAt = Date.now() + ttlSeconds * 1000;

  cacheStore.set(key, {
    value,
    expireAt
  });
}

module.exports = {
  createCacheKey,
  getCache,
  setCache
};

4. rateLimiter.js:用户限流

const userUsage = new Map();

const DAILY_LIMIT = {
  requests: 100,
  tokens: 50000
};

function getTodayKey() {
  return new Date().toISOString().slice(0, 10);
}

function checkRateLimit(userId) {
  const today = getTodayKey();
  const key = `${userId}:${today}`;

  if (!userUsage.has(key)) {
    userUsage.set(key, {
      requests: 0,
      tokens: 0
    });
  }

  const usage = userUsage.get(key);

  if (usage.requests >= DAILY_LIMIT.requests) {
    return {
      allowed: false,
      reason: "今日请求次数已达上限"
    };
  }

  if (usage.tokens >= DAILY_LIMIT.tokens) {
    return {
      allowed: false,
      reason: "今日 Token 使用量已达上限"
    };
  }

  return {
    allowed: true,
    usage
  };
}

function updateUsage(userId, tokens) {
  const today = getTodayKey();
  const key = `${userId}:${today}`;

  if (!userUsage.has(key)) {
    userUsage.set(key, {
      requests: 0,
      tokens: 0
    });
  }

  const usage = userUsage.get(key);
  usage.requests += 1;
  usage.tokens += tokens;
}

module.exports = {
  checkRateLimit,
  updateUsage
};

5. cost.js:费用估算

这里使用示例价格,并不代表真实价格。你可以根据实际模型供应商价格修改。

const MODEL_PRICE = {
  small: {
    input: 0.000001,
    output: 0.000002
  },
  medium: {
    input: 0.000005,
    output: 0.00001
  },
  large: {
    input: 0.00002,
    output: 0.00006
  }
};

/**
 * 简化 Token 估算:
 * 中文场景可以粗略按字符数估算;
 * 生产环境建议使用模型对应 tokenizer。
 */
function estimateTokens(text) {
  if (!text) return 0;
  return Math.ceil(String(text).length * 0.8);
}

function estimateCost(model, inputTokens, outputTokens) {
  const price = MODEL_PRICE[model] || MODEL_PRICE.medium;

  return inputTokens * price.input + outputTokens * price.output;
}

module.exports = {
  estimateTokens,
  estimateCost
};

6. aiClient.js:模型路由与模拟调用

const { estimateTokens } = require("./cost");

/**
 * 根据任务复杂度选择模型
 */
function selectModel({ prompt, taskType }) {
  const textLength = prompt.length;

  if (taskType === "classify" || taskType === "extract") {
    return "small";
  }

  if (taskType === "code" || taskType === "reasoning") {
    return "large";
  }

  if (textLength < 200) {
    return "small";
  }

  if (textLength < 2000) {
    return "medium";
  }

  return "large";
}

/**
 * 模拟 AI 调用
 * 生产环境中可以替换为 OpenAI、Claude、Gemini、通义、智谱等 API。
 */
async function callAI({ model, prompt, maxOutputTokens = 500 }) {
  const inputTokens = estimateTokens(prompt);

  // 模拟输出
  const answer = `这是由 ${model} 模型生成的回答。已根据你的问题进行处理:${prompt.slice(
    0,
    80
  )}...`;

  const outputTokens = Math.min(
    estimateTokens(answer),
    maxOutputTokens
  );

  await new Promise(resolve => setTimeout(resolve, 200));

  return {
    answer,
    usage: {
      inputTokens,
      outputTokens,
      totalTokens: inputTokens + outputTokens
    }
  };
}

module.exports = {
  selectModel,
  callAI
};

7. logger.js:调用日志

function logAIRequest(data) {
  const log = {
    time: new Date().toISOString(),
    ...data
  };

  console.log(JSON.stringify(log, null, 2));
}

module.exports = {
  logAIRequest
};

8. server.js:统一 AI 网关入口

const express = require("express");

const {
  createCacheKey,
  getCache,
  setCache
} = require("./cache");

const {
  checkRateLimit,
  updateUsage
} = require("./rateLimiter");

const {
  estimateCost
} = require("./cost");

const {
  selectModel,
  callAI
} = require("./aiClient");

const {
  logAIRequest
} = require("./logger");

const app = express();

app.use(express.json());

app.post("/api/ai", async (req, res) => {
  const startTime = Date.now();

  try {
    const {
      userId = "anonymous",
      prompt,
      taskType = "chat",
      cache = true,
      maxOutputTokens = 500
    } = req.body;

    if (!prompt) {
      return res.status(400).json({
        error: "prompt 不能为空"
      });
    }

    // 1. 用户限流检查
    const limitResult = checkRateLimit(userId);

    if (!limitResult.allowed) {
      return res.status(429).json({
        error: limitResult.reason
      });
    }

    // 2. 模型路由
    const model = selectModel({
      prompt,
      taskType
    });

    // 3. 生成缓存 Key
    const cacheKey = createCacheKey({
      prompt,
      taskType,
      model,
      maxOutputTokens
    });

    // 4. 查询缓存
    if (cache) {
      const cached = getCache(cacheKey);

      if (cached) {
        logAIRequest({
          userId,
          taskType,
          model,
          cacheHit: true,
          inputTokens: 0,
          outputTokens: 0,
          cost: 0,
          latencyMs: Date.now() - startTime
        });

        return res.json({
          fromCache: true,
          model,
          answer: cached.answer,
          usage: {
            inputTokens: 0,
            outputTokens: 0,
            totalTokens: 0
          },
          cost: 0
        });
      }
    }

    // 5. 调用 AI
    const result = await callAI({
      model,
      prompt,
      maxOutputTokens
    });

    const {
      inputTokens,
      outputTokens,
      totalTokens
    } = result.usage;

    // 6. 费用估算
    const cost = estimateCost(
      model,
      inputTokens,
      outputTokens
    );

    // 7. 更新用户使用量
    updateUsage(userId, totalTokens);

    // 8. 写入缓存
    if (cache) {
      setCache(cacheKey, {
        answer: result.answer
      }, 3600);
    }

    // 9. 记录日志
    logAIRequest({
      userId,
      taskType,
      model,
      cacheHit: false,
      inputTokens,
      outputTokens,
      totalTokens,
      cost,
      latencyMs: Date.now() - startTime
    });

    return res.json({
      fromCache: false,
      model,
      answer: result.answer,
      usage: result.usage,
      cost
    });

  } catch (error) {
    console.error(error);

    return res.status(500).json({
      error: "服务器内部错误"
    });
  }
});

app.listen(3000, () => {
  console.log("AI cost gateway running at http://localhost:3000");
});

9. 启动服务

node server.js

测试请求:

curl -X POST http://localhost:3000/api/ai \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "user_001",
    "prompt": "请总结一下 AI 工具如何帮助企业降低运营成本",
    "taskType": "summary",
    "cache": true,
    "maxOutputTokens": 300
  }'

第一次请求会调用模型,第二次相同请求会命中缓存。

返回示例:

{
  "fromCache": false,
  "model": "small",
  "answer": "这是由 small 模型生成的回答。已根据你的问题进行处理:请总结一下 AI 工具如何帮助企业降低运营成本...",
  "usage": {
    "inputTokens": 22,
    "outputTokens": 57,
    "totalTokens": 79
  },
  "cost": 0.000136
}

四、生产环境如何继续优化?

上面的源码只是一个最小可用示例。如果要用于真实业务,还可以继续增强。


1. 使用 Redis 替代内存缓存

内存缓存的问题是服务重启后数据会丢失,而且多实例之间无法共享。

生产环境建议使用 Redis:

  • 支持 TTL;
  • 支持分布式共享;
  • 性能高;
  • 适合缓存高频问答;
  • 可统计缓存命中率。

2. 使用数据库记录调用明细

建议将每次调用写入数据库,例如 MySQL、PostgreSQL 或 ClickHouse。

数据表可以包含:

CREATE TABLE ai_call_logs (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  user_id VARCHAR(100),
  task_type VARCHAR(50),
  model VARCHAR(50),
  prompt_hash VARCHAR(128),
  input_tokens INT,
  output_tokens INT,
  total_tokens INT,
  cost DECIMAL(12, 8),
  cache_hit BOOLEAN,
  latency_ms INT,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

有了这些数据,就可以做成本报表、异常分析和模型效果评估。


3. 增加 Prompt 版本管理

Prompt 一旦上线,就不应该随意修改。因为 Prompt 改动会影响:

  • 输出质量;
  • 成本;
  • 缓存命中率;
  • 评估结果;
  • 业务稳定性。

建议给每个 Prompt 增加版本号:

{
  "promptName": "customer_service_reply",
  "version": "v3",
  "model": "medium"
}

这样可以对比不同版本的成本和效果。


4. 引入语义缓存

普通缓存只能命中完全相同的问题,而语义缓存可以命中意思相近的问题。

例如:

怎么退款?
如何申请退款?
订单能退吗?
我想退钱怎么办?

这些问题语义相似,可以复用同一个答案。

实现方式一般是:

  1. 对用户问题生成 Embedding;
  2. 在向量数据库中查找相似问题;
  3. 如果相似度超过阈值,直接返回缓存答案;
  4. 否则调用模型并写入语义缓存。

语义缓存对客服和知识库问答非常有效。


5. 对高价模型增加审批或降级策略

高价模型不应该被无节制调用。

可以设计策略:

  • 普通用户默认不能调用高价模型;
  • 只有复杂任务才自动升级;
  • 低价值请求使用小模型;
  • 超出预算后自动降级;
  • 高价模型失败时降级到中等模型;
  • 对内部员工开放更高额度。

6. 建立离线评估集

成本优化不能只看价格,还要看效果。

如果一味使用便宜模型,可能导致回答质量下降,最终增加人工客服压力,反而总成本更高。

建议准备一批真实问题作为评估集,例如:

  • 100 条客服问题;
  • 100 条摘要任务;
  • 100 条分类任务;
  • 100 条代码任务。

每次调整模型、Prompt 或参数后,自动跑评估,比较:

  • 准确率;
  • 用户满意度;
  • 平均 Token;
  • 平均成本;
  • 响应时间;
  • 人工接管率。

真正的优化目标应该是:在满足业务质量的前提下,让单位任务成本最低


五、AI 成本优化的实战清单

下面是一份可以直接执行的检查清单。

模型选择

  • [ ] 是否所有任务都在使用最贵模型?
  • [ ] 是否区分了分类、摘要、问答、推理、代码等任务?
  • [ ] 是否有模型路由机制?
  • [ ] 是否统计了不同模型的成本和效果?

Prompt 优化

  • [ ] Prompt 是否过长?
  • [ ] 是否包含无关上下文?
  • [ ] 是否限制输出长度?
  • [ ] 是否存在重复说明?
  • [ ] 是否有 Prompt 版本管理?

缓存机制

  • [ ] 高频问题是否缓存?
  • [ ] 是否使用 Redis?
  • [ ] 是否统计缓存命中率?
  • [ ] 是否考虑语义缓存?
  • [ ] 缓存是否设置合理过期时间?

RAG 知识库

  • [ ] 是否把整篇文档都塞进 Prompt?
  • [ ] 是否只检索相关片段?
  • [ ] 文档切片是否合理?
  • [ ] 是否对长文档做摘要?
  • [ ] 是否过滤低相关内容?

限流与预算

  • [ ] 是否限制单用户每日调用次数?
  • [ ] 是否限制 Token 使用量?
  • [ ] 是否设置业务线预算?
  • [ ] 是否对异常调用报警?
  • [ ] 是否限制失败重试次数?

日志与监控

  • [ ] 是否记录每次调用成本?
  • [ ] 是否记录输入输出 Token?
  • [ ] 是否记录模型、场景、用户?
  • [ ] 是否可以按业务线统计费用?
  • [ ] 是否能发现成本异常增长?

六、总结

AI 工具降低成本的关键,不是简单地“换便宜模型”,而是建立系统化的成本控制能力。

真正有效的做法包括:

  1. 模型分层:不同任务使用不同模型;
  2. 缓存复用:高频问题不重复调用;
  3. RAG 检索:减少无效上下文;
  4. 上下文压缩:避免历史对话无限增长;
  5. 输出限制:控制生成长度;
  6. 限流预算:防止异常消耗;
  7. 日志监控:知道钱花在哪里;
  8. 持续评估:平衡成本与效果。

对于企业来说,AI 的价值不只是“能不能用”,而是“能否稳定、低成本、可规模化地用”。当你的 AI 系统具备缓存、路由、限流、监控和评估能力后,成本通常可以下降 30% 到 80%,同时系统稳定性和可维护性也会显著提升。

如果你正在做 AI 应用,不建议一开始就追求复杂架构,而是可以先搭建一个统一的 AI 网关,把所有模型调用集中管理起来。只要入口统一,后续无论是切换模型、统计费用、做缓存、加限流,都会变得容易很多。

上文提供的源码就是一个最小版本的 AI 成本优化网关。你可以基于它继续扩展 Redis 缓存、数据库日志、语义缓存、RAG 检索和可视化报表,从而逐步构建一套适合自己业务的 AI 成本控制体系。

目录结构
全文