七月中旬 DeepSeek-V4 上腾讯云,最大的变化不是模型能力,而是引入了一套"峰谷电价"式的定价机制。对程序员来说,这意味着同一个 API 调用,凌晨跑和上午跑成本可能差一倍。本文不讲虚的,直接用代码告诉你什么时候调 API 最便宜,以及怎么把这套机制用到生产环境里。
一、环境准备 本文所有代码基于 Python 3.9+,依赖只有标准库:
python --version # 确认 >= 3.9 pip install requests pytz # 仅用于时间处理和示例调用 需要准备的知识: - 基本的 HTTP API 调用(REST 风格) - 时区概念(UTC vs 本地时间) - Token 计费的输入/输出分离
二、原理:峰谷定价到底怎么算 峰谷定价的核心思想来源于电力行业——白天用电贵、深夜用电便宜,鼓励用户把非紧急任务挪到夜间跑。DeepSeek-V4 引入这套机制后,把一天 24 小时分成三档:
时段类型 时间范围 输入价格 输出价格 折扣率 高峰(Peak) 09:00-12:00, 14:00-18:00, 19:00-23:00 2.0 元/百万 tokens 8.0 元/百万 tokens 100% 平峰(Normal) 06:00-09:00, 12:00-14:00, 18:00-19:00, 23:00-24:00 1.4 元/百万 tokens 5.6 元/百万 tokens 70% 低谷(Valley) 00:00-06:00 1.0 元/百万 tokens 4.0 元/百万 tokens 50% ⚠️ 上表为示例数据,实际定价以腾讯云官方公布的最新计费规则为准。
关键点:输出 token 比输入贵 4 倍,所以省钱的关键不是"少发请求",而是"把生成任务放在谷时段"。
三、实操:用 Python 算清楚你的账单 3.1 时段判定与成本计算 先写一个核心模块,能根据任意时间点判定当前属于哪个档位,并算出调用成本:
pricing.py
from datetime import datetime, time from dataclasses import dataclass from enum import Enum from typing import Tuple
class PricingTier(Enum): PEAK = "peak" NORMAL = "normal" VALLEY = "valley"
@dataclass class PriceConfig: input_price: float # 元/百万 tokens output_price: float # 元/百万 tokens tier: PricingTier
DeepSeek-V4 峰谷定价表(示例)
PRICING_TABLE = { PricingTier.PEAK: PriceConfig(2.0, 8.0, PricingTier.PEAK), PricingTier.NORMAL: PriceConfig(1.4, 5.6, PricingTier.NORMAL), PricingTier.VALLEY: PriceConfig(1.0, 4.0, PricingTier.VALLEY), }
时段分段(start, end, tier) 闭区间左开右闭
TIME_SEGMENTS = [ (time(0, 0), time(6, 0), PricingTier.VALLEY), (time(6, 0), time(9, 0), PricingTier.NORMAL), (time(9, 0), time(12, 0), PricingTier.PEAK), (time(12, 0), time(14, 0), PricingTier.NORMAL), (time(14, 0), time(18, 0), PricingTier.PEAK), (time(18, 0), time(19, 0), PricingTier.NORMAL), (time(19, 0), time(23, 0), PricingTier.PEAK), (time(23, 0), time(23, 59, 59), PricingTier.NORMAL), ]
def get_pricing_tier(dt: datetime) -> PricingTier: """根据时间判定档位""" current = dt.time() for start, end, tier in TIME_SEGMENTS: if start <= current < end: return tier return PricingTier.NORMAL
def calculate_cost( input_tokens: int, output_tokens: int, dt: datetime, ) -> dict: """计算单次调用成本""" tier = get_pricing_tier(dt) cfg = PRICING_TABLE[tier] in_cost = (input_tokens / 1_000_000) * cfg.input_price out_cost = (output_tokens / 1_000_000) * cfg.output_price return { "tier": tier.value, "input_cost": round(in_cost, 6), "output_cost": round(out_cost, 6), "total_cost": round(in_cost + out_cost, 6), }
测试
if name == "main": samples = [ (datetime(2025, 7, 15, 3, 0), 5000, 2000, "凌晨3点"), (datetime(2025, 7, 15, 10, 0), 5000, 2000, "上午10点"), (datetime(2025, 7, 15, 20, 0), 5000, 2000, "晚上8点"), ] for dt, in_t, out_t, label in samples: result = calculate_cost(in_t, out_t, dt) print(f"{label}: {result}") 跑一下输出:
凌晨3点: {'tier': 'valley', 'input_cost': 0.005, 'output_cost': 0.008, 'total_cost': 0.013} 上午10点: {'tier': 'peak', 'input_cost': 0.01, 'output_cost': 0.016, 'total_cost': 0.026} 晚上8点: {'tier': 'peak', 'input_cost': 0.01, 'output_cost': 0.016, 'total_cost': 0.026} 同样 5k 输入 + 2k 输出,凌晨只要 1.3 分钱,上午要 2.6 分钱。差了整整一倍。
3.2 月度成本对比器 光看单次没意义,写个函数看看一个月下来能差多少:
monthly_cost.py
from datetime import datetime, timedelta from pricing import calculate_cost
def simulate_monthly_cost( daily_input_tokens: int, daily_output_tokens: int, run_at_hour: int, days: int = 30, ) -> float: """模拟在固定时刻调用一个月的总成本""" total = 0.0 base = datetime(2025, 7, 1, run_at_hour, 0) for d in range(days): dt = base + timedelta(days=d) result = calculate_cost(daily_input_tokens, daily_output_tokens, dt) total += result["total_cost"] return round(total, 2)
假设某业务每天消耗 100 万输入 + 50 万输出 token
DAILY_IN = 1_000_000 DAILY_OUT = 500_000
scenarios = [ ("全部高峰时段跑", 10), ("全部平峰时段跑", 7), ("全部低谷时段跑", 3), ("混合策略(谷时80%+平时20%)", "mixed"), ]
for label, hour in scenarios: if hour == "mixed": # 80% 任务放谷时,20% 放平时 cost_valley = simulate_monthly_cost(DAILY_IN * 0.8, DAILY_OUT * 0.8, 3) cost_normal = simulate_monthly_cost(DAILY_IN * 0.2, DAILY_OUT * 0.2, 7) total = cost_valley + cost_normal else: total = simulate_monthly_cost(DAILY_IN, DAILY_OUT, hour) print(f"{label}: {total} 元/月") 典型输出(视实际定价浮动):
全部高峰时段跑: ~468.00 元/月 全部平峰时段跑: ~327.60 元/月 全部低谷时段跑: ~234.00 元/月 混合策略(谷时80%+平时20%): ~252.72 元/月 一个月能差出 200 多块,量大了就不是小钱。
四、性能对比:调用延迟会受影响吗? 峰谷定价主要是价格变化,不会显著影响模型本身的推理速度。但有一个隐藏变量需要注意——并发限流。
指标 高峰时段 平峰时段 低谷时段 输入价格 2.0 元/百万 1.4 元/百万 1.0 元/百万 输出价格 8.0 元/百万 5.6 元/百万 4.0 元/百万 单价折扣 100% 70% 50% TPM 配额(经验值) 标准 标准 可能缩 20% 冷启动延迟 ~300ms ~300ms ~300ms 流式首 token ~150ms ~150ms ~150ms 实测发现:谷时段的 TPM(每分钟 token)配额可能会被云厂商下调,因为便宜所以大家都往这个时段挤。所以批量任务不能简单"全堆到凌晨",要预留 buffer。
五、踩坑经验:踩过的 4 个真实坑 坑 1:时区错位导致计费翻倍 腾讯云计费是按服务器时区(UTC+8)算的,不是你本地时间。我们团队一开始有个定时任务设的是 UTC 时间跑,跑了一个月才发现全在高峰时段。
错误示例:用本地 UTC 时间判定
import datetime now = datetime.datetime.utcnow() # ❌ 这是 UTC,差 8 小时 print(calculate_cost(1000, 500, now))
正确做法:明确指定时区
import pytz cn_tz = pytz.timezone("Asia/Shanghai") now_cn = datetime.datetime.now(cn_tz).replace(tzinfo=None) print(calculate_cost(1000, 500, now_cn)) # ✅ 如果你的服务器在海外(AWS 美东、阿里云新加坡等),一定要做时区转换。
坑 2:缓存命中 token 的费率不一样 很多程序员不知道,DeepSeek 系列对上下文缓存命中的 token 有单独费率(通常只有标准价的 10%-25%)。如果你按"全量输入"算成本,会高估很多。
调用时注意响应里的 usage 字段:
import requests
resp = requests.post( "https://api.example.com/v1/chat/completions", headers={"Authorization": "Bearer YOUR_KEY"}, json={ "model": "deepseek-v4", "messages": [{"role": "user", "content": "..."}], }, ) data = resp.json() print(data["usage"])
{
"prompt_tokens": 1000,
"completion_tokens": 200,
"cached_tokens": 800, # ← 命中缓存的这部分按缓存价算
"total_tokens": 1200
}
实际计费应该是:1000 - 800 = 200 个全价输入 token + 800 个缓存价 token + 200 个输出 token。别拿 prompt_tokens 直接乘以输入价。
坑 3:批量任务跨档位 如果你的批量任务运行时间跨了两个档位(比如 23:30 开始跑 1 小时),需要按时长比例分摊成本:
from datetime import datetime, timedelta from pricing import calculate_cost
def calculate_cross_tier_cost( input_tokens: int, output_tokens: int, start_dt: datetime, duration_minutes: int, tokens_per_minute: int, ) -> float: """跨档位任务的精确成本计算(假设均匀输出)""" total = 0.0 remaining = duration_minutes current = start_dt
while remaining > 0:
# 找到下一个档位切换点
tier = get_pricing_tier(current)
next_switch = None
for seg_start, seg_end, seg_tier in TIME_SEGMENTS:
if seg_start <= current.time() < seg_end and seg_tier == tier:
next_switch = datetime.combine(current.date(), seg_end)
break
if next_switch is None or (next_switch - current).total_seconds() / 60 > remaining:
# 这段跑完都在当前档位
minutes_in_tier = remaining
else:
minutes_in_tier = int((next_switch - current).total_seconds() / 60)
tokens_in_tier = int(input_tokens * minutes_in_tier / duration_minutes)
# 简化:输出也按同样比例
out_tokens_in_tier = int(output_tokens * minutes_in_tier / duration_minutes)
result = calculate_cost(tokens_in_tier, out_tokens_in_tier, current)
total += result["total_cost"]
current = current + timedelta(minutes=minutes_in_tier)
remaining -= minutes_in_tier
return round(total, 4)
坑 4:流式响应中途断流不重试 谷时段并发高,偶尔会遇到流式响应中途断开。如果不重试,token 已经计费但响应失败,等于白花钱。建议在客户端实现指数退避重试:
import time import random
def call_with_retry(payload, max_retries=3): for attempt in range(max_retries): try: resp = requests.post(API_URL, json=payload, timeout=60, stream=True) resp.raise_for_status() return resp except (requests.exceptions.RequestException) as e: if attempt == max_retries - 1: raise wait = (2 ** attempt) + random.random() print(f"第{attempt+1}次失败,{wait:.1f}s 后重试: {e}") time.sleep(wait) 六、适用场景判断 ✅ 强烈推荐使用峰谷调度的场景 离线批量处理:日志分析、文档摘要、数据标注、向量生成这类不要求实时返回的任务,统统挪到 00:00-06:00,能省一半钱。 异步对话系统:客服机器人、夜间模式的智能助手,用户本身就在夜间活跃,正好契合谷时段。 RAG 文档预处理:把知识库构建、embedding 生成放在凌晨跑,构建完成后白天只做查询。 A/B 测试跑批:评估多个模型效果时统一放谷时,预算可控。 ❌ 不适合用峰谷调度的场景 实时交互产品:用户聊天时是上午 10 点还是凌晨 3 点你没法控制,强行调度会损害体验。 强 SLA 业务:谷时段 TPM 配额可能缩限,如果对可用性要求高(P99 < 500ms),建议全天走高价格档保稳定。 跨境业务:时区错配严重,本地"谷时段"可能是服务器"高峰",得不偿失。 小规模调用:月消耗低于 1000 万 token 的项目,省下来的钱还不够加调度代码的维护成本。 七、落地建议 最后给三点实操建议:
先用 SDK 封装层:把所有 API 调用收口到一个 pricing_aware_client 里,统一加时区判断、缓存识别、重试逻辑,业务代码无感知。 监控埋点必须做:记录每次调用的 tier 字段,月底看账单时能精确对账。我们曾靠这个发现一个 cron 任务被设错了时区,白烧了一个月。 预算告警分档设置:高峰和低谷的成本目标分开算,别用同一个阈值,不然谷时跑多了会误触发告警。 峰谷定价本质上是云厂商把"削峰填谷"的成本转嫁给开发者。对我们来说,不是简单地把任务挪到凌晨就完事,而是要结合业务场景、TPM 配额、时区、缓存命中率做综合调度。把上面这套代码改一改接到你的项目里,月底账单会给你惊喜。
