codecamp

Grok 长上下文分档计费

200k 定价悬崖是「看起来只影响长请求、实际吃掉大半账单」的典型陷阱。它的真实含义不是「超出 200k 的部分更贵」,而是「只要 prompt 达到阈值,整个请求的所有 token 都按高档计费」——输入、缓存输入、输出一起跳档。这一节用可算的账把这件事钉死,并接上 1.3 已经讲过的组合层教训。

按 2026-11-04 官方 models 页的注释:请求 prompt 达到阈值时,整请求所有 token 按高档计费(F5)。下面用 grok-4.7 的单价演示:<200k 为 2.00/0.50/6.00,≥200k 为 4.00/1.00/12.00(USD/1M tokens)。

一、问题不是「超出的部分」,而是「整请求跳档」

最容易被误导的理解是「只有第 200001 个 token 起才贵」。错了——官方规则是整请求跳档。同一个请求,prompt 恰好跨过 200k,账单直接约翻倍(因为输入和输出单价都翻倍)。下面把这件事算成可复算的数字。

二、最小可运行示例:阈值探测器与拆分演示

下面的脚本不联网、不需要真实密钥。它先算「同一组 token 跨过阈值」的倍数,再演示「把一个 250k 的 prompt 拆成两个 125k」能省多少。

"""200k 阈值计费:同一请求跨过阈值,整请求所有 token 按高档。"""

PRICE_LOW = {"in": 2.0, "cached": 0.5, "out": 6.0}
PRICE_HIGH = {"in": 4.0, "cached": 1.0, "out": 12.0}
THRESHOLD = 200_000

def price(prompt: int, cached: int, output: int) -> float:
    """cached 是 prompt 中命中缓存的那部分,只能按缓存价计一次,不能按输入价再计一次。"""
    tier = PRICE_HIGH if prompt >= THRESHOLD else PRICE_LOW
    return ((prompt - cached)/1e6)*tier["in"] + (cached/1e6)*tier["cached"] + (output/1e6)*tier["out"]

def offline_check() -> None:
    # 同一组 token:prompt 恰好跨过 200k
    under = price(199_999, 0, 5_000)
    over = price(200_000, 0, 5_000)
    cliff = over / under
    print(f"低于阈值:${under:.4f}  高于阈值:${over:.4f}  倍数:{cliff:.2f}")
    # 拆分:把 250k 的 prompt 拆成两个 125k(总 token 不变,只改档位)
    single = price(250_000, 0, 5_000)
    split = price(125_000, 0, 2_500) + price(125_000, 0, 2_500)
    saving = (1 - split / single) * 100
    print(f"单请求(高档):${single:.4f}  拆两半(低档):${split:.4f}  省:{saving:.1f}%")
    # 缓存输入:5 万 token 按 $1.00 计一次,不能按 $4.00 再计一次
    no_cache = price(250_000, 0, 5_000)
    half_cache = price(250_000, 50_000, 5_000)
    saved_by_cache = no_cache - half_cache
    print(f"5万缓存输入:${half_cache:.4f}(比全价省 ${saved_by_cache:.4f})")
    assert 1.99 < cliff < 2.01, "跨阈值应约 2 倍"
    assert 49 < saving < 51, "拆分应约省一半"
    assert abs(saved_by_cache - (50_000/1e6)*3.0) < 1e-9, "缓存节省应等于 (4.00-1.00)×5万"

if __name__ == "__main__":
    offline_check()

真正上线时,把 price() 接进你的本地记账(见 5.1),每个请求先判断是否跨阈值再累加;split 思路则用于「单个超长请求」的改造——前提是拆分后语义仍可独立回答。

三、阈值触发与应对

情形 触发条件 应对 注意
单请求跨档 单个 prompt ≥ 200k 拆请求 / 压缩上下文 拆分会改请求结构,需验证语义
长对话累积 多轮历史把 prompt 推过阈值 Context Compaction(见 3.2) 压缩后保真度需自测
缓存命中 稳定前缀命中缓存 缓存单价仍随档跳 高档下缓存也贵一倍
组合层放大 少数长请求占总 token 大头 先治长尾再治其他 见下方与 1.3 的衔接

三件要强调的事:

  • 拆请求的前提是「拆分后仍能独立回答」。把一份合同拆成两段分别问,可能丢失跨段约束;这种情况下该用压缩而非硬拆。
  • 缓存不能免跳档。阈值看的是 prompt 规模,不是是否命中缓存;高档下缓存输入单价同样翻倍(1.00 vs 0.50)。
  • 组合层的教训(接 1.3):在整本书的成本账里,真正吃预算的不是「有多少请求跨阈值」,而是「跨阈值的那些请求带了多少 token」。1.3 已经算过:2% 的长请求(prompt 在 20 万量级)能吃掉约 67% 的账单。所以优化顺序是「缓存与长尾请求 → 输出长度」,只给请求数占比而不给 token 占比,会算出完全相反的假象。

四、预期输出与异常分支

运行阈值探测器,预期输出:

低于阈值:$0.4300  高于阈值:$0.8600  倍数:2.00
单请求(高档):$1.0600  拆两半(低档):$0.5300  省:50.0%
5万缓存输入:$0.9100(比全价省 $0.1500)

换成真实账单核对时,若出现异常,按下面顺序定位:

现象 优先怀疑 第一步动作
账单高得离谱 少数长请求跨档 按 token 量而非请求数排查
拆了反而更贵 拆分增加输出量 核算拆分后总输出是否失控
缓存没省钱 高档下缓存也翻倍 重算缓存单价
阈值判断错 用了过期阈值 核对官方 models 页当前注释

最后一行尤其重要:省 50.0% 是在「拆分不改变总 token 量、只改变计费档位」的假设下成立的。现实里拆分往往增加输出,所以它是上限而非保证——把 split 改成带真实输出增量的版本,你就能看到省幅收窄。

五、判据卡

判断项 该这么做 不该这么做
看阈值 整请求跳档,输入输出都翻倍 以为只有超出部分贵
治长尾 先压跨阈值的 token 量 只按请求数占比优化
超长单请求 能独立回答就拆,否则压缩 无脑拆导致语义丢失
用缓存 稳定前缀降输入单价 以为缓存能免跳档
出错排查 先按 token 量定位 先怪模型或重发

这张卡的重点是先治长尾再治其他。五类现象里「账单高得离谱」和「缓存没省钱」常常同源:没把阈值当整请求跳档,表现一个是总账一个是缓存,但修法都在「按 token 量而非请求数」上。

六、来源与核验

  • 官方模型页:https://docs.x.ai/developers/models(核验日期 2026-11-04)。200k 阈值「整请求所有 token 按高档计费」的注释、各模型 <200k 与 ≥200k 单价以该页为准(F4、F5)。
  • 组合层教训来自 1.3 的成本模型(已按真实 token 量修正):2% 长请求约占总账单 67%;该结论以 2026-11-04 的单价与示例参数为准,重算请以官方当前价目。
  • 价格、额度与区域可用性以控制台当前页面为准。

七、动手试

  1. 把正文的 cached 用例扩展到低档(199_999 prompt):验证低档下缓存单价同样是输入价的四分之一(0.50 vs 2.00),并解释为什么两档的缓存折扣比例一致。
  2. 把 split 改成带输出增量的版本(例如拆分后总输出从 5k 变成 6k),重算省幅,确认它低于 50%。想一想:什么任务拆分后输出增量最小?
  3. 用 1.3 的 Workload 思路,构造一个「长请求占 2% 但占总 token 67%」的组合,验证组合层结论。再反过来构造一个「长请求占 30% 但只占 10% 账单」的组合,说明两种情形下的优化优先级为什么不同。
Grok 推理强度四档取舍
Grok 模型选型判据卡
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }