Token计费系统设计.md 11 KB

Token计费系统设计

📊 成本分析基础

AI模型定价(你提供的数据)

模型 输入价格 输出价格 特点
DeepSeek V3.2 ¥2.0/千token ¥8.0/千token ⭐ 高性价比
通义 Qwen Plus ¥4.0/千token ¥12.0/千token 高质量生成
豆包 Pro ¥2.0/千token ¥6.0/千token 稳定通用

TTS场景成本计算

场景:用户输入文本 → AI处理 → 生成音频

成本构成

  1. 输入成本:文本处理

    • 公式:字数 × 输入价格 / 1000
    • 示例:2000字 × ¥2.0/千 = ¥4.0
  2. 输出成本:音频合成

    • 公式:字数 × 输出价格 / 1000 × 系数
    • 系数:0.05-0.1(相对固定成本)
    • 示例:2000字 × ¥8.0/千 × 0.1 = ¥1.6
  3. 总成本:¥4.0 + ¥1.6 = ¥5.6


💰 安全定价策略

核心原则

  1. Token单价 ≥ ¥2.0(DeepSeek成本价)
  2. 利润率 ≥ 50%(企业健康利润率)
  3. 套餐定价 ≥ 成本(避免亏本)

Token单价计算

成本价:¥2.0/千token(DeepSeek基础价)
合理售价:¥3.0-4.0/千token
利润率:33-50%

📋 套餐成本分析

免费版(¥0/月)

配额:5,000 Token/月
成本:5,000 × ¥2.0/千 = ¥10.0
利润:-¥10.0(平台补贴)
策略:体验引流,吸引付费转化

入门版(¥9.9/月)

配额:10,000 Token/月
成本:10,000 × ¥2.0/千 = ¥20.0
售价:¥9.9
利润:-¥10.1(亏损,获客用)
策略:薄利或亏损,用于付费转化漏斗

专业版(¥59/月)⭐ 推荐

配额:20,000 Token/月
成本:20,000 × ¥2.0/千 = ¥40.0
售价:¥59.0
利润:¥19.0
利润率:32%
策略:主要盈利产品

旗舰版(¥199/月)

配额:50,000 Token/月
成本:50,000 × ¥2.0/千 = ¥100.0
售价:¥199.0
利润:¥99.0
利润率:50%
策略:高端用户,保证利润

🔧 Token扣费逻辑

扣费流程

// 1. 用户提交生成请求
async function generateAudio(userId: number, text: string) {
  const textLength = text.length;
  
  // 2. 计算Token消耗
  const tokens = calculateTokens(textLength); // 1字 ≈ 1 token
  const cost = calculateCost(tokens, 'deepseek'); // ¥2.0/千token
  
  // 3. 检查用户配额
  const balance = await getUserTokenBalance(userId);
  
  if (balance.remainingTokens < tokens) {
    throw new Error('Token余额不足,请充值');
  }
  
  // 4. 扣除Token
  await consumeToken(userId, tokens, {
    type: 'text_to_speech',
    description: `生成音频:${textLength}字`
  });
  
  // 5. 调用AI生成音频
  const audioUrl = await callTTSAPI(text);
  
  return { audioUrl, tokens, cost };
}

成本计算函数

// server/src/modules/subscription/subscription.service.ts

// Token成本配置
export const TOKEN_COST_CONFIG = {
  baseCostPerThousand: 2.0,  // DeepSeek基础价
  extraPricePerThousand: 3.5, // 超额单价
  
  models: {
    deepseek: {
      name: 'DeepSeek V3.2',
      inputCost: 2.0,   // ¥2.0/千token
      outputCost: 8.0,   // ¥8.0/千token
      quality: 'standard'
    },
    qwen_plus: {
      name: '通义 Qwen Plus',
      inputCost: 4.0,   // ¥4.0/千token
      outputCost: 12.0,  // ¥12.0/千token
      quality: 'high'
    }
  }
};

// 计算Token成本
export function calculateTokenCost(textLength: number, model: string = 'deepseek') {
  const modelConfig = TOKEN_COST_CONFIG.models[model];
  
  // 输入成本
  const inputCost = (textLength / 1000) * modelConfig.inputCost;
  
  // 输出成本(简化计算)
  const outputCost = (textLength / 1000) * modelConfig.outputCost * 0.1;
  
  // 总成本
  const totalCost = inputCost + outputCost;
  
  // 建议售价(成本 × 1.5,保证50%利润)
  const suggestedPrice = totalCost * 1.5;
  
  return {
    inputCost: Math.round(inputCost * 100) / 100,
    outputCost: Math.round(outputCost * 100) / 100,
    totalCost: Math.round(totalCost * 100) / 100,
    suggestedPrice: Math.round(suggestedPrice * 100) / 100
  };
}

Token扣费示例

示例1:免费版用户

用户等级:免费版
配额:5,000 Token/月
已用:2,000 Token
剩余:3,000 Token

生成请求:1,500字

检查:
  ✓ 剩余3,000 ≥ 需要1,500
  ✓ 字数1,500 ≤ 每次限制2,000
  
扣费:
  成本:1,500 × ¥2.0/千 = ¥3.0
  剩余Token:3,000 - 1,500 = 1,500
  记录使用:1,500 Token

示例2:专业版用户

用户等级:专业版
配额:20,000 Token/月
已用:15,000 Token
剩余:5,000 Token

生成请求:3,000字

检查:
  ✓ 剩余5,000 ≥ 需要3,000
  ✓ 字数3,000 ≤ 每次限制10,000
  
扣费:
  成本:3,000 × ¥2.0/千 = ¥6.0
  剩余Token:5,000 - 3,000 = 2,000
  记录使用:3,000 Token

示例3:Token不足

用户等级:入门版
配额:10,000 Token/月
已用:9,500 Token
剩余:500 Token

生成请求:2,000字

检查:
  ✗ 剩余500 < 需要2,000
  → 余额不足
  
处理:
  返回错误:Token余额不足
  建议:升级套餐或等待月度重置

📐 超额使用计费

超额单价

套餐 月配额 超额单价 说明
免费版 5,000 ¥4.0/千 不支持超额
入门版 10,000 ¥3.5/千 超额自动计费
专业版 20,000 ¥3.0/千 超额自动计费
旗舰版 50,000 ¥2.5/千 超额享受折扣

超额计费示例

用户等级:入门版
月配额:10,000 Token
月费:¥9.9

当月使用:
  Token消耗:13,500 Token
  
计费:
  包含部分:10,000 Token = ¥0(已付月费)
  超额部分:3,500 Token × ¥3.5/千 = ¥12.25
  
额外费用:¥12.25
总费用:¥9.9 + ¥12.25 = ¥22.15

🎯 模型选择策略

默认模型:DeepSeek V3.2

成本:¥2.0/千token
适用:95%场景
质量:标准/良好

高质量模型:通义 Qwen Plus

成本:¥4.0/千token
适用:5%高质量需求
额外费用:+¥2.0/千token
质量:优秀

模型选择UI

<!-- 前端模型选择 -->
<view class="model-selector">
  <text class="label">选择模型</text>
  
  <view class="option" @click="selectModel('deepseek')">
    <text class="name">DeepSeek V3.2</text>
    <text class="price">¥2.0/千token</text>
    <text class="desc">高性价比,推荐</text>
    <view class="check" v-if="selectedModel === 'deepseek'">✓</view>
  </view>
  
  <view class="option" @click="selectModel('qwen_plus')">
    <text class="name">通义 Qwen Plus</text>
    <text class="price">¥4.0/千token</text>
    <text class="desc">高质量生成</text>
    <view class="check" v-if="selectedModel === 'qwen_plus'">✓</view>
  </view>
</view>

💡 成本控制措施

1. 每日使用限制

// 每日生成次数
const DAILY_LIMITS = {
  0: 3,   // 免费版:3次/天
  1: 10,  // 入门版:10次/天
  2: 50,  // 专业版:50次/天
  3: -1   // 旗舰版:无限制
};

// 检查每日限制
async function checkDailyLimit(userId: number) {
  const today = new Date().toISOString().slice(0, 10);
  const todayUsage = await prisma.tokenUsage.count({
    where: {
      userId,
      createdAt: { gte: new Date(today) }
    }
  });
  
  const limit = DAILY_LIMITS[user.memberLevel];
  
  if (limit !== -1 && todayUsage >= limit) {
    throw new Error(`今日生成次数已用完(${limit}次),请明天再试`);
  }
}

2. 每次生成上限

// 每次生成字数限制
const PER_GENERATION_LIMITS = {
  0: 1000,    // 免费版:1000字
  1: 3000,    // 入门版:3000字
  2: 10000,   // 专业版:10000字
  3: 50000    // 旗舰版:50000字
};

// 检查单次限制
function checkPerGenerationLimit(textLength: number, memberLevel: number) {
  const limit = PER_GENERATION_LIMITS[memberLevel];
  
  if (textLength > limit) {
    throw new Error(`单次生成字数不能超过${limit}字`);
  }
}

3. 每月配额重置

// 每月1日重置配额
async function resetMonthlyQuota() {
  const users = await prisma.user.findMany();
  
  for (const user of users) {
    const balance = await prisma.tokenBalance.findUnique({
      where: { userId: user.id }
    });
    
    if (balance) {
      const plan = await prisma.subscriptionPlan.findFirst({
        where: { level: user.memberLevel }
      });
      
      // 重置配额
      await prisma.tokenBalance.update({
        where: { userId: user.id },
        data: {
          totalTokens: plan.monthlyTokens,
          usedTokens: 0,
          resetDate: new Date()
        }
      });
    }
  }
}

📊 成本监控

每日成本报表

// 生成成本报表
async function generateCostReport(date: string) {
  const startDate = new Date(date);
  const endDate = new Date(startDate.getTime() + 24 * 60 * 60 * 1000);
  
  const usages = await prisma.tokenUsage.findMany({
    where: {
      createdAt: {
        gte: startDate,
        lt: endDate
      }
    }
  });
  
  // 统计
  const totalTokens = usages.reduce((sum, u) => sum + u.amount, 0);
  const totalCost = totalTokens * TOKEN_COST_CONFIG.baseCostPerThousand / 1000;
  const userCount = new Set(usages.map(u => u.userId)).size;
  
  return {
    date,
    totalTokens,
    totalCost: Math.round(totalCost * 100) / 100,
    userCount,
    avgTokensPerUser: Math.round(totalTokens / userCount),
    avgCostPerUser: Math.round((totalCost / userCount) * 100) / 100
  };
}

预警机制

// 成本预警
async function checkCostWarning(userId: number) {
  const balance = await prisma.tokenBalance.findUnique({
    where: { userId }
  });
  
  const usagePercent = balance.usedTokens / balance.totalTokens * 100;
  
  if (usagePercent >= 90) {
    // 发送预警通知
    await sendNotification(userId, {
      type: 'warning',
      title: 'Token余额不足',
      content: `已使用${usagePercent.toFixed(0)}%,建议续费`
    });
  }
}

📋 定价公式总结

单次生成成本

输入成本 = 字数 × ¥2.0 / 1000
输出成本 = 字数 × ¥8.0 / 10000
总成本 = 输入成本 + 输出成本

套餐月费成本

月成本 = 月Token配额 × ¥2.0 / 1000
月售价 = 月成本 × 1.5(50%利润率)

超额使用计费

超额费用 = 超额Token × 超额单价 / 1000

✅ 定价检查清单

  • Token单价 ≥ ¥2.0(成本价)
  • 套餐利润率 ≥ 30%
  • 专业版:主要盈利产品
  • 旗舰版:50%利润率
  • 超额单价 ≥ 成本价
  • 成本监控机制
  • 每日/每月限制
  • 预警通知系统

🚀 下一步行动

  1. 集成Token扣费到TTS生成流程
  2. 配置成本监控报表
  3. 测试超额计费逻辑
  4. 上线监控告警