眼下围绕 AI 算力周期有两种针锋相对的判断:一种认为 2027 年前后算力供给见顶、形成瓶颈,推理资源趋紧;另一种预计 2028 年新建产能集中释放,供给宽松甚至引发定价崩塌。我在 4sapi.com 维护多模型中转,价格波动直接影响每个月的路由权重,所以这篇不站队,只聊接入架构怎么两头对冲。

痛点:预算编制撞上价格周期

每年做模型调用预算的时候,最省事的假设是"单价全年不变、用量线性增长"。这个假设放在算力周期争论愈演愈烈的当下,几乎注定要失效。两种周期判断对账单的影响完全相反:供给趋紧派意味着单价上行压力、高峰时段排队限流变严,甚至要为稳定供给额外付费;供给宽松派意味着单价下行,今天签下去的任何长期承诺,到兑现的时候都可能变成拖累。

更麻烦的是分母还在变大。Agent 业务的高频调用让 token 消耗曲线越来越陡,同样的价格波动幅度,落在账单上的绝对金额被显著放大。去年一次不起眼的单价调整,今年可能就是一笔需要单独解释的开支。预算从"算术题"变成了"情景题"。

还有一个次生变量值得提前写进风险清单:有讨论认为 Agent 时代的高频调用会让网络带宽接棒 GPU,成为下一个瓶颈。如果这个判断兑现,成本结构里就不只是模型单价一项在动,带宽、并发、重试都会进入账单的敏感区。

把这几件事放在一起看,真正的痛点不是"贵",而是"不可估"。预算的本质是把未来换算成数字,而算力周期辩论恰恰说明未来价格存在两个方向相反的版本。接入者能做的,不是在两个版本里挑一个来信,而是让架构在两个版本下都活得下去。

原理速览:两种周期判断,两条价格路径

先把手头的判断摆清楚。第一种判断认为,2027 年前后算力供给会见顶、形成瓶颈,推理资源趋紧,落到接入侧就是单价上行、排队变长、限流变严。第二种判断认为,2028 年新建产能集中释放,供给宽松,价格竞争加剧,甚至引发定价崩塌。

这些判断不是空对空的嘴仗,供应链消息面也在配合"周期底部已过"的情绪:存储板块走强,SK 海力士在美股创下新高,认为最差日子已经过去的声音越来越多。但情绪归情绪,产业预期反映到股价上,与传导到 API 账单上,中间隔着定价策略、竞争格局、结算周期好几层,快慢与深浅都没人敢打包票。

两派之外还有第三种声音:无论算力走向如何,Agent 时代的高频调用可能先让网络带宽接棒 GPU,成为下一个瓶颈。对接入层来说,这提醒了一件事——瓶颈会换位置,成本敏感点也会跟着换,架构里每个环节都值得预留观测点。

把两条价格路径和对应的对冲动作画在同一张图上:

              ┌─ 判断 A:2027 年前后算力供给见顶 ──► 推理资源趋紧
              │       价格路径:单价上行,排队限流变严
              │       对冲动作:锁定盘提前分批签,缓存命中率优先提
              │                 备用通道预先演练,熔断阈值收紧
现在(周期大辩论中)┤
              │
              └─ 判断 B:2028 年新建产能集中释放 ──► 供给宽松
                      价格路径:单价下行,新低价卡位出现
                      对冲动作:弹性盘保持按量,可延迟任务挪 batch
                                合约只锁小比例,保留快速切换权

这张图的关键不在于判断哪条路径会兑现,而在于每条路径旁边都预先写好了对冲动作。路径 A 兑现时,锁定盘和备用通道是安全垫;路径 B 兑现时,弹性盘和比价机制是红利入口。接入架构的任务,是让两手牌同时握在手里。

接入层的对冲框架:不预测价格,只两头下注

价格周期的走向没法预测,这不丢人,把全部筹码押在单一判断上才丢人。做法是把接入架构拆成四个可以独立调节的杠杆,每个杠杆在两种情景里都有正贡献。

第一个杠杆是盘子结构:把流量拆成弹性盘和锁定盘。弹性盘走按量计费,保留随时切换的自由;锁定盘走包月或预留,换取确定性和可能的折扣。第二个杠杆是供应商结构:多供应商并行,配合中转聚合做统一接入,任何单一供应商的涨价都只是路由权重表上的一行改动。第三个杠杆是单位消耗:缓存命中、batch、模型分级,把每个 token 的实际成本往下压,这个杠杆不依赖任何周期判断。第四个杠杆是治理:用量监控与预算熔断,保证任何情景下损失都有上限。

涨和跌在这套框架里是不对称的:涨价情景里最值钱的资产是切换权,降价情景里最值钱的资产是切换速度。切换权靠弹性盘和多供应商保住,切换速度靠聚合接入和预先演练好的模型映射保住。剩下的问题,是把这套框架翻译成可执行的数字,下一节从测算器开始。

接入教程:先写一个价格情景测算器

先给最小接入示例,OpenAI 兼容 SDK 风格,base_url 指向中转入口,API key 一律从环境变量读取:

import os
from openai import OpenAI

# 密钥走环境变量,不落代码库;base_url 指向中转入口
client = OpenAI(
    base_url="https://4sapi.com/v1",
    api_key=os.environ["MODEL_API_KEY"],
)

resp = client.chat.completions.create(
    model="deepseek-chat",
    messages=[{"role": "user", "content": "一句话说明 batch 接口适合什么任务"}],
)
print(resp.usage.total_tokens)  # 每次调用都把 token 数记进自建账本

有了入口,再写测算器。输入是假设单价、月 token 量、缓存命中率、batch 折扣这几组参数,输出是不同价格情景下的月成本对比:

# 价格情景测算器:所有参数都是演示值,接入决策前替换成自己的量级
# 情景 A:单价上浮(供给趋紧假设);情景 B:单价下调(供给宽松假设)

def estimate_monthly_cost(
    input_price: float,               # 演示值:每百万输入 token 单价
    output_price: float,              # 演示值:每百万输出 token 单价
    monthly_in_tokens: float,         # 演示值:月输入 token 量
    monthly_out_tokens: float,        # 演示值:月输出 token 量
    cache_hit_rate: float = 0.0,      # 演示值:缓存命中率,取值 0 到 1
    cache_price_factor: float = 1.0,  # 演示值:缓存命中价 = 输入单价 × 该系数
    batch_share: float = 0.0,         # 演示值:挪进 batch 的请求占比,0 到 1
    batch_discount: float = 1.0,      # 演示值:batch 价 = 普通价 × 该折扣
    price_factor: float = 1.0,        # 演示值:情景系数,1.2 即单价整体上浮 20%
) -> float:
    """按演示参数估算月成本,输出单位与单价的口径一致。"""
    # 缓存只作用于输入侧,先把输入拆成命中与未命中两块
    cached_in = monthly_in_tokens * cache_hit_rate
    live_in = monthly_in_tokens - cached_in
    input_cost = (
        cached_in * input_price * cache_price_factor
        + live_in * input_price
    ) / 1e6
    output_cost = monthly_out_tokens * output_price / 1e6
    raw_cost = input_cost + output_cost
    # batch 是异步低价通道,把可延迟任务挪进去换折扣
    realtime_cost = raw_cost * (1 - batch_share)
    offline_cost = raw_cost * batch_share * batch_discount
    return realtime_cost + offline_cost


demo = dict(                        # 以下全部为演示值
    input_price=14.0,               # 演示单价:每百万输入 token
    output_price=56.0,              # 演示单价:每百万输出 token
    monthly_in_tokens=3_000_000,    # 演示用量
    monthly_out_tokens=1_200_000,   # 演示用量
    cache_hit_rate=0.4,             # 演示缓存命中率
    cache_price_factor=0.25,        # 演示缓存价格系数
    batch_share=0.3,                # 演示 batch 占比
    batch_discount=0.5,             # 演示 batch 折扣
)

base_cost  = estimate_monthly_cost(**demo)                    # 基线情景
tight_cost = estimate_monthly_cost(**demo, price_factor=1.2)  # 情景 A:上浮 20%
loose_cost = estimate_monthly_cost(**demo, price_factor=0.7)  # 情景 B:下调 30%
print(f"基线月成本:{base_cost:.1f}")
print(f"情景 A(单价上浮 20%):{tight_cost:.1f}")
print(f"情景 B(单价下调 30%):{loose_cost:.1f}")

# 再看内部杠杆:把缓存命中率从 0.4 提到 0.6(演示值),重跑情景 A
demo_hedged = {**demo, "cache_hit_rate": 0.6}
tight_hedged = estimate_monthly_cost(**demo_hedged, price_factor=1.2)
print(f"情景 A + 提高缓存命中率:{tight_hedged:.1f}")

读结果的方式比数字本身重要:先看基线与情景 A 的差值,那是价格周期带来的敞口;再看情景 A 与"情景 A + 提高缓存命中率"的差值,那是内部杠杆能吃掉的部分。内部差值能盖过价格差值,说明优化优先于择时;盖不过,说明盘子结构需要提前调整。所有参数都是演示值,替换成真实量级之后,结论才算数。

缓存与 batch:不依赖周期判断的省钱钥匙

四个杠杆里,单位消耗是唯一完全握在自己手里的。缓存命中率靠工程提上来:把稳定的系统提示和长上下文放在 prompt 前部并保持前缀稳定,避免每次调用都重复携带同一份背景材料;把几乎不变的知识放到缓存友好的位置,把高频变化的内容留在尾部。命中率每提高一档,输入侧实际单价就往下走一档,而且这条收益在两种周期情景里同样成立。

batch 的逻辑类似:把可以延迟的任务——评测跑分、标注预跑、夜间报表、历史数据回填——挪进异步低价通道,实时通道留给真正需要即时响应的调用。batch 折扣乘的是"可延迟任务占比",占比由调度策略决定,同样不依赖周期判断。

cache_price_factor 和 batch_discount 这两个参数值得在测算器里单独拉出来看:每调一档,相当于给外部单价波动加了一层内部保险。外部价格不可控,内部系数可控,风险管理的常识就是先用可控项去对冲不可控项。

多供应商与中转聚合:把单一涨价风险摊薄

单一供应商是涨价情景下的全额敞口。多供应商策略分三步:第一步协议层统一,所有通道都用 OpenAI 兼容接口,把切换成本压到改一行 base_url;第二步模型映射层抽象,业务代码只描述需要的能力,映射层决定用哪个模型、走哪个通道;第三步路由权重动态化,价格、延迟、成功率三个维度定期复核,权重表跟着调。

我维护的中转把横向比价做成了每周的常规动作:出现新价格,先在测试通道验证输出质量,再灰度切一部分流量,确认稳定后全量切换。这套流程的意义不在于每次都抢到最低价,而在于单一供应商的议价压力被隔离——涨价的传导被多通道摊薄,降价的红利也能第一时间接进来。

有一条例外必须写明:聚合的目的自始至终是负载均衡与计费优化,所有通道都来自合法授权的官方或授权渠道,各家的服务条款、限速规则和 SLA 一条都不绕。接入架构优化的是成本结构,不是合规边界。

用量监控与预算熔断:给损失设上限

监控和熔断是整个对冲框架的兜底。熔断器不需要复杂,三级动作加一个人工复核就够用:

def check_budget(daily_cost, daily_budget, monthly_cost, monthly_budget):
    # 阈值系数均为演示值,按业务可接受的风险水平调整
    if daily_cost >= daily_budget:
        return "hard_stop"   # 当日预算打穿:暂停非关键任务队列
    if daily_cost >= daily_budget * 0.8:
        return "degrade"     # 触及八成:切便宜模型,可延迟任务挪 batch
    if monthly_cost >= monthly_budget * 0.9:
        return "review"      # 月度逼近红线:触发人工复核与权重调整
    return "ok"

三级动作的设计逻辑是"先降级、再改道、最后停":非关键任务先换更便宜的模型,可延迟任务挪进 batch,实在不行暂停低优先级队列。恢复不做全自动,人工复核之后再放行,避免风暴结束前又烧穿一次。

监控维度除了 token 和金额,还有两个容易被忽略的口径:一个是缓存命中的真实率,也就是自统计命中率与账单折扣口径的偏差;另一个是请求放大系数,Agent 一次任务链会拆成多少次底层调用,重试风暴期间这个系数会异常抬升。这两个指标漂移,往往比单价变动更早暴露成本问题。

策略对照表:四种姿势 × 两种情景

接入策略 情景 A:2027 前后供给趋紧、单价上行 情景 B:2028 产能释放、单价下行
按量计费 涨价全额传导,账单跟着单价走;好处是不受合约约束,随时可以切换供应商或模型 降价红利立即到账,一个动作都不用做;适合当主力盘子,吃满下行行情
包月 / 预留 已锁定的部分不受涨价影响,覆盖率越高越抗涨;代价是锁定周期内的灵活性 相对市场价变贵,锁得越多越被动;只适合覆盖稳定的基线流量
多供应商并行 任一家涨价,流量切向未涨价通道,冲击被摊薄;比价筹码始终在手 降价通道出现即接入,红利不缺席;代价是运维与对账成本上升
中转聚合 统一入口下横向比价成为日常动作,涨价传导被权重表吸收 新低价第一时间接入测试与灰度,切换速度就是红利兑现速度
辅助杠杆 情景 A:供给趋紧 情景 B:供给宽松
缓存命中 直接抵消单价上行,还顺带减少高峰期的调用次数 照常生效,与降价红利叠加
batch 接口 高峰期让出实时通道,可延迟任务避峰 折让照吃,宽松预期下低价通道通常更从容
用量熔断 防止单价上行放大超额,损失有上限 控住总量,比价与调整更从容

读这张表的要点是:没有全胜的姿势,只有组合的胜率。锁定盘扛涨价,但在降价行情里吃亏;弹性盘吃降价,但在涨价行情里裸奔;聚合两头不吃大亏,但也吃不满任何一头。组合思路是把基线流量适度锁定、增量保持按量、全量走聚合、缓存与 batch 常态化——具体比例没有标准答案,用上面的测算器按自己的用量结构跑出来,比例参数本身也只是演示性质。

避坑清单:三组检查项

锁价合约

用量熔断

缓存与 batch 的审计

锁价合约最容易踩的坑是"锁住了价格,丢掉了弹性"。包月和预留用灵活性换折扣,代价在模型版本变更时显形:锁定周期里模型下线、能力退化,或者出现明显更优的替代,条款里有没有替换与退出机制,决定这份合约是保险还是枷锁。用量熔断的坑在于"阈值定了但动作没排练",触发瞬间执行的应该是演练过的降级流程,而不是临时开会。缓存与 batch 的审计则是防止账面省钱变成隐形支出:没命中的部分按原价走,batch 超时重跑,都会把折扣悄悄吃回去。

成本与风险提示

总结

这期的主线只有一句话:价格周期无法预测,接入架构可以两头对冲。先把 2027 供给见顶与 2028 产能释放两条价格路径摆上桌,再拆出四个可独立调节的杠杆——盘子结构、供应商结构、单位消耗、用量治理;配套交付一个价格情景测算器、一张四种接入策略在两种情景下的对照表,以及锁价合约、用量熔断、缓存与 batch 审计三组避坑清单。

这套打法来自我在 4sapi(https://4sapi.com)维护多模型中转的日常:不判断周期,只维护一张随时可调的权重表和一份随时可跑的成本测算。算力辩论还会继续,只要账单在可控轨道上,辩论吵到哪边都不慌。

欢迎在评论区聊聊更信哪种周期判断,以及手头接入架构的对冲做法。