目录
6380 字
32 分钟
推理模型:test-time compute 买到了什么,又买不到什么

一、同一道题,多想一会儿确实更对#

先看一道小学题:

3 个人 3 天做 3 个零件,9 个人 9 天做几个零件?

标准模型的典型回答是 9:人数和天数都乘了 3,答案就乘 3。推理模型会先把速率拆出来:3 人 3 天做 3 个,说明 3 人 1 天做 1 个,也就是 1 人 1 天做 1/3 个;9 人 9 天就是 9 × 9 × 1/3 = 27。它多花了几百个 token,把一个会被直觉带偏的题做对了。

这个对比很容易让人得出一个结论:多想一会儿 = 更聪明。但把同一套配置换到另一类任务上,结论会立刻变形。

比如从一份采购合同里抽「付款账期」。合同正文写「验收后 30 日内付款」,补充条款写「账期以附件二为准」,附件二又写「月结 60 天」。标准模型可能直接返回 30;推理模型则会写一段很长的推理,论证「正文优先」「附件是补充」「以验收日为起点」,最后给出一个看起来很严谨的 30 天,或者 60 天——它没有停下来指出这三处互相冲突。

两件事放在一起,才是这篇文章的起点:test-time compute 不是一枚「质量旋钮」。它是一组把推理时间换成准确率的手段,有明确的适用条件,也有明确的失效方式。用对了,它能把一个做不对的任务抬过可用线;用错了,它只是让你为同一个错误多付几倍的钱。

二、先把「推理模型」拆成两件事#

「推理模型」这个词经常把两个层面的东西混在一起:

层面发生了什么你能否在调用时改变
训练侧用可验证奖励(RLVR)或长思维链数据,让模型学会先展开再回答不能,取决于你选的模型
推理侧在生成时投入更多算力:更长的思维链、多条样本、搜索、迭代能,取决于你的调用参数与编排

一个模型可以在训练侧被专门训练成「愿意长时间思考」,也可以在推理侧被要求「多想几步」;两者可以叠加,但不是一回事。推理侧的手段并不要求模型经过推理训练——自洽性投票、best-of-n、树搜索,这些方法在普通指令模型上也能用,只是收益通常更小。

另一个容易踩的坑是计费单位。推理模型产生的 thinking token(不同厂商叫 reasoning token、thinking token 或内部推理 token)通常按输出 token 计费,而且会计入 max_tokens / max_completion_tokens 这类总预算。也就是说:

  • 你看到的输出可能只有 200 个 token,账单上却按 2,200 个输出 token 算;
  • 预算给少了,模型可能把预算全花在思考上,最后返回一个空答案或半截答案;
  • 「思维链不可见」不等于「思维链不花钱」。

后面所有的成本计算,都建立在这一点上。

三、四个旋钮,四种成本形状#

把推理侧的手段拆开,常用的其实是四个旋钮。它们买的不是同一种东西,成本曲线也不一样。

旋钮做法买到什么成本随什么增长典型失效条件
更长思维链让模型在给出答案前展开更多步骤、回溯、验算单条轨迹更深,减少「跳步」错误输出 token 线性增长前提理解错、知识缺失、无验证信号
并行采样 + 投票独立采样 k 条,按多数票或加权投票选答案降低随机错误,提升「至少一条对」的概率输出 token × k错误高度相关,样本不独立
搜索 + 验证器生成多个候选,用规则、测试或打分模型挑选把「生成能力」换成「选择能力」候选数 + 验证器调用验证器并不比生成器可靠
迭代修订生成 → 批评 → 修改,重复若干轮修正表面错误、补全遗漏轮数 × 单轮成本没有外部反馈时震荡,甚至越改越差

它们有一个共同的上限:正确路径必须已经在模型的输出分布里,而且你得有办法把它认出来。 前者决定「采样有没有用」,后者决定「采样之后能不能选对」。这两个前提,值得单独拆开看。

四、前提一:路径覆盖——样本再多,也救不回共享的错误前提#

自洽性(self-consistency)的常见说法是:采样 k 条思维链,取多数答案,准确率就会上升。这个说法隐含了一个很强的假设:样本之间是独立的。现实里,模型的多条样本往往共享同一个错误前提。

写一个小模拟就能看清这件事。假设:

  • 有 15% 的概率,模型从一开始就理解错了题意(q = 0.15)。这时 k 条样本会一起错,而且错得一致;
  • 在理解正确的前提下,每条样本有 60% 的概率得到正确答案(p = 0.60),否则随机落到 20 个错误答案之一。
import random, collections
def simulate(k, q=0.15, p=0.60, trials=50000, seed=7):
rng = random.Random(seed)
maj = any_ok = 0
for _ in range(trials):
if rng.random() < q:
votes = ["shared_wrong"] * k # 共享错误前提:k 条一起错
else:
votes = ["right" if rng.random() < p else f"w{rng.randrange(20)}"
for _ in range(k)]
top = collections.Counter(votes).most_common(1)[0][0]
maj += top == "right"
any_ok += "right" in votes
return maj / trials, any_ok / trials
for k in (1, 3, 5, 9, 15):
m, a = simulate(k)
print(f"k={k:<2} majority={m:.3f} pass@k={a:.3f}")

输出:

k=1 majority=0.512 pass@k=0.512
k=3 majority=0.629 pass@k=0.795
k=5 majority=0.773 pass@k=0.843
k=9 majority=0.836 pass@k=0.849
k=15 majority=0.848 pass@k=0.849

三个读数值得注意:

  1. pass@k 的上限是 0.85,不是 1。 因为 15% 的情况下所有样本共享同一个错误前提,采样再多也覆盖不到正确路径。这就是「路径覆盖」的上限。
  2. 多数投票也会撞到同一个上限。 k 从 1 加到 15,多数投票从 0.512 升到 0.848,然后停住。它并没有把「至少一条对」变成「交付的那条对」的免费转换器。
  3. k=5 时,pass@k 是 0.843,多数投票只有 0.773。 中间那 7 个百分点,就是「选择器」的缺口。候选里有正确答案,但你没能把它选出来。

这个模拟的参数是人为设定的,但结构在真实任务里很常见:模型把「附件二」当成「附件一」,把「税前」读成「税后」,把「不含运费」漏掉——这些错误不会因为采样次数增加而分散,只会被重复采样放大成一种「共识」。

所以看到一个「多采样几条、取多数」的方案时,先问两个问题:

  • 这个任务的错误,是分散的随机错误,还是共享的前提错误?前者投票有用,后者投票有害。
  • 你有没有一个独立于采样过程的选择器?如果没有,多数投票只是成本较低的选择器,不是可靠的选择器。

五、前提二:可判定——没有验证器,搜索只是掷骰子#

第二个前提是「可判定」:你得能在多个候选里判断哪个更对。

验证器的强弱,直接决定了 test-time compute 的回报。把验证器按可靠性排一下:

验证器例子可靠性成本
精确规则数学答案比对、单位检查、正则、JSON Schema高(前提是规则写对)低
可执行测试单元测试、类型检查、SQL 约束、编译高(覆盖到就算数)中
环境状态工具返回、数据库查询、页面实际渲染结果高(但只覆盖被观测到的部分)中到高
交叉约束多个字段互相校验、金额合计、日期先后中(能抓矛盾,未必能给正解)低
奖励模型 / PRM过程奖励模型、打分器中(分布外会失准)中
LLM-as-a-Judge另一个模型打分低到中(与生成器同源时有系统性偏差)中
人工编辑、标注、复核高高

一个反直觉的结论是:best-of-n 的效果上限由验证器决定,而不是由 n 决定。 如果验证器把一个错误答案排在第一,采样 100 条也只是给这个错误答案增加候选;如果验证器和生成器同源、共享同一套偏好,它会把生成器的错误也一起「验证」过去。

这也是为什么推理模型在数学和代码上看起来进步明显:这两类任务恰好有便宜、可靠、可自动化的验证器。数学题可以对答案,代码可以跑测试。换到开放写作、战略判断、需求优先级,验证器要么很贵(人工),要么很弱(LLM 打分),test-time compute 的回报就会明显下降。

六、买不到的四样东西#

把「买不到」的部分单独列出来,比列「买到了什么」更有用。

6.1 买不到缺失的知识#

模型不知道某个内部 API 的签名,多想十分钟也不会知道。它更可能做的是:根据命名习惯编一个看起来合理的签名,再用一段严谨的推理证明这个签名「应该」成立。推理能力会把「不知道」包装成「想清楚了」。

知识缺失的解法是检索、工具、上下文注入,不是提高推理预算。判断方法也很简单:如果正确答案依赖一个模型训练时不可能见过的事实(内部文档、今天的数据、你刚改的接口),先补上下文,再谈 reasoning budget。

6.2 买不到正确的题意#

题目本身有歧义时,更长的思维链往往会加固模型选中的那一种解释。它会把「我假设这里指的是 X」写成一段不容置疑的推导,而不是停下来问「你说的 X 是哪一个」。

前文的合同例子就是这一类:三处条款冲突,正确动作是报告冲突、请求澄清;推理模型却可能在几种解释里选一个,然后把它论证得很像那么回事。对歧义输入,更好的做法是约束输出结构——要求它先列出「我识别到的歧义与假设」,再给答案;或者把「无法确定」作为一个合法输出。

6.3 买不到外部执行与状态#

「这个用户上个月的订单有没有退款」「这段代码在 Node 22 上能不能跑」「今天的汇率是多少」——这些问题的答案不在参数里,也不在思维链里。推理可以帮你决定调用哪个工具、怎么组合结果,但不能替代调用本身。

Agent 场景里常见的误判是:把「规划得更细」当成「执行得更对」。规划再细,工具返回 500 就是 500。预算应该分给「规划 + 验证 + 重试」,而不是只堆在第一步的思考上。

6.4 买不到低延迟与低单价#

这一条是算术,不是观点。假设生成速度是 50 token/s,多花 2,000 个推理 token,就多出约 40 秒;即使算力更快、达到 100 token/s,也要多 20 秒。对实时客服、语音助手、IDE 补全这类有硬延迟预算的场景,20 秒的「更聪明」通常不可用。

成本同理:推理 token 按输出计费,而输出 token 的单价通常高于输入 token。你买到的准确率,是用延迟和账单换来的。下一节把这笔账算清楚。

七、成本曲线:按「每个正确答案」算账#

比较两个配置,不能只比「每次调用多少钱」,也不能只比「准确率多少」。把两者放在一起,才有可比的单位:每个正确答案的成本。

先看一个简化的算例。假设:

  • 输入 1,500 token,答案 300 token;
  • 示例单价:输入 1 元 / 百万 token,输出 4 元 / 百万 token(只为演示数量级,不代表任何厂商的真实报价);
  • 标准模型每次调用 0.00270 元;
  • 推理模型多花 2,000 个推理 token,每次调用 0.01070 元,准确率 0.90。
IN_TOK, OUT_TOK = 1500, 300
PI, PO = 1.0, 4.0 # 示例单价:元 / 百万 token
BASE = (IN_TOK * PI + OUT_TOK * PO) / 1e6
def per_correct(cost, acc):
return cost / acc
def reasoning(think, acc):
cost = (IN_TOK * PI + (OUT_TOK + think) * PO) / 1e6
return cost, per_correct(cost, acc)
for a in (0.25, 0.50, 0.75):
c, pc = reasoning(2000, 0.90)
print(f"std acc={a:.2f} std/correct={per_correct(BASE, a):.5f} "
f"reason/correct={pc:.5f}")

输出:

std acc=0.25 std/correct=0.01080 reason/correct=0.01189
std acc=0.50 std/correct=0.00540 reason/correct=0.01189
std acc=0.75 std/correct=0.00360 reason/correct=0.01189

结果有点反直觉:即使标准模型的准确率只有 25%,推理模型的「每个正确答案成本」仍然略高(0.01189 对 0.01080)。原因很简单——推理模型每次调用贵了约 4 倍,而准确率最多只能到 1,单位正确成本不可能低于单次调用成本。

把盈亏平衡点算出来:

a0* = a1 × c0 / c1
= 0.90 × 0.00270 / 0.01070
≈ 0.227

也就是说,在这个示例单价下,只有当标准模型的准确率低于约 22.7% 时,推理模型才在「每个正确答案」上更便宜。标准模型越准,推理模型越难靠成本说服人。

标准模型准确率标准:每次 / 每正确推理:每次 / 每正确每正确谁更便宜
0.250.00270 / 0.010800.01070 / 0.01189标准(略低)
0.500.00270 / 0.005400.01070 / 0.01189标准
0.750.00270 / 0.003600.01070 / 0.01189标准

这不是说推理模型没有价值,而是说它的价值不在「普遍更省钱」。它买到的是:在标准模型几乎做不对、而错误又足够昂贵的任务上,把正确率抬过可用线。 如果一次错误要人工复核 30 分钟,多付几厘钱把准确率从 25% 抬到 90%,账立刻就算得过来;如果错误只是让用户多点一次重试,推理模型的溢价就很难成立。

7.1 级联:先便宜后贵,但前提是有验证器#

比「全量上推理模型」更常见的做法是级联:先用便宜模型,验证不过再升级。

在上面的例子里,标准模型准确率 0.60,验证器能抓出所有错误,升级后准确率 0.90:

级联成本 = 0.00270 + (1 - 0.60) × 0.01070 ≈ 0.00698
级联准确率 = 0.60 + 0.40 × 0.90 = 0.96
每个正确答案成本 ≈ 0.00698 / 0.96 ≈ 0.00727

比全量推理(0.01189 / 正确)便宜,也比纯标准模型(0.00450 / 正确)更准。但这个结果依赖一个很强的假设:验证器能可靠地判断「这次答错了」。验证器有漏判,级联就会把错误直接放出去;验证器有误判,级联就会为本来正确的答案多付一次推理费。

所以级联的工程问题不是「怎么路由」,而是「验证器从哪来」。有单元测试、Schema、金额合计、外部 API 校验,就值得做;只有「再问一个 LLM 觉得对不对」,级联的收益会被验证器的偏差吃掉。

八、什么时候值得开推理:一张决策表#

把前面的条件收成一张表。判断顺序是:先问「错了能不能被发现」,再问「这个错误值不值得多花钱」。

任务类型可验证信号建议理由
竞赛数学、形式化证明精确答案、证明检查器开,预算可高验证便宜且可靠,搜索和投票都有落点
代码修复、重构单元测试、类型检查、编译开,把测试反馈接进循环测试既是验证器,也是下一轮的输入
结构化抽取Schema、跨字段约束、合计校验开中等预算,验证失败再重试能抓矛盾,但「哪个解释对」仍需人工规则
分类、意图识别标签、抽样人工复核通常不开任务短、答案空间小,小模型加校准更划算
创意写作、文案人工偏好、品牌规范选择性开,用并行采样给编辑挑验证器贵,投票不能替代品味
多轮 Agent工具返回、环境状态、任务完成条件开,但预算分给规划与验证只堆第一步的思考,不会让工具返回变对
实时客服、语音延迟硬约束、业务规则谨慎,级联 + 流式20 秒的思考在对话里不可用
高风险决策人工复核、审计记录开,但输出必须带证据与不确定性正确率之外,还要能解释「为什么」

一个实用的经验法则:如果这个任务错了以后,你能在 5 分钟内写出一条自动检查,推理预算就值得花;如果检查本身要靠人看半天,先把预算花在「让人更快发现错误」上。

九、工程落地:把预算花在刀刃上#

9.1 先管住预算,再谈效果#

推理 token 计入总输出预算,所以第一件事是把截断当成一等失败,而不是等它变成空答案。

type Result = { text: string; finishReason: string; reasoningTokens: number };
async function ask(prompt: string, budget: number): Promise<Result> {
const r = await callModel({ prompt, maxOutputTokens: budget });
if (r.finishReason === "length") {
// 预算可能被推理 token 吃光,答案被截断或为空。
// 不要静默返回空字符串:要么加预算重试,要么降级到非推理模型。
return ask(prompt, Math.ceil(budget * 1.5));
}
return r;
}

不同厂商的字段名不一样(finish_reason、status、incomplete_details),但规则相同:看到长度截断,就把这次调用标记为失败并进入降级路径。在日志里单独记 reasoningTokens,否则你只会看到「输出 200 token,账单 2,200 token」这种对不上的账。

9.2 级联要有验证器,也要有回退上限#

级联不是「便宜模型 + 贵模型」两行代码,它至少需要三个东西:

  1. 验证器:规则、测试、Schema、外部校验,任选其一;
  2. 升级条件:验证失败、置信度低于阈值、输出结构不合法;
  3. 回退上限:最多升级一次,避免在验证器和生成器之间来回打转。

没有第 1 项,级联只是随机分流;没有第 3 项,一次坏输入可能烧掉整条链路的预算。

9.3 流式输出遮不住全部延迟#

流式可以把「首 token 时间」降下来,但推理模型的思考阶段通常不产生用户可见的 token。用户看到的是:转圈 15 秒,然后答案突然开始流。对交互式场景,这 15 秒仍然是实打实的等待。

能做的有三种:把非关键路径的推理移到后台、先返回一个可用的草稿再异步升级、或者对简单请求直接走非推理模型。不要用「我们在流式输出」来解释为什么用户要等 20 秒。

9.4 缓存能省输入,省不了思考#

  • 精确缓存:把「规范化后的输入 + 模型 + 预算」作为 key,缓存最终答案。适合 FAQ、固定报表、重复工单。
  • Prompt caching:缓存长系统提示词、文档、few-shot 示例,降低输入侧成本。它不会缓存模型这次生成的推理过程。
  • 语义缓存:相似问题复用答案,命中率更高,但错配的代价也更高。至少要用阈值 + 抽样复核,别把「差不多」当成「一样」。

9.5 蒸馏:把大模型的思考变成小模型的直觉#

如果某类任务已经被验证为「推理模型稳定做对」,可以把成功的推理轨迹筛出来,蒸馏到更小的模型里。关键是筛:只用验证器通过的轨迹,别把失败轨迹也喂进去;否则小模型学到的是「自信地犯错」。

蒸馏之后仍然要重新评测:小模型在分布内的表现可能接近,分布外会退化得更快。它是把单位成本打下来的手段,不是一次性替代。

9.6 观测指标#

指标为什么看它
输入 / 输出 / 推理 token 分开记定位账单涨在哪一段
每个正确答案的成本把准确率和成本放进同一个单位
延迟 p50 / p95推理 token 的方差通常比答案 token 大
验证器通过率、升级率级联是否真的在省钱
截断率、重试率预算是否给少了
分布外抽样准确率防止蒸馏或缓存把退化藏起来

十、评测陷阱:别用「感觉更聪明」做结论#

推理模型很容易在演示里显得更强,因为演示通常挑的是「标准模型答错、推理模型答对」的题。评测方法本身——公共基准、自建评测集、A/B 与人工评估——在《如何科学评测一个 LLM 应用》里已经展开,这里只列推理模型特有的几个陷阱。

1. 同成本比较,而不是同模型比较。 公平的对照是:标准模型在同样的 token 预算下采样多次(或加长提示词),对比推理模型的一次调用。只拿「标准模型一次」对「推理模型一次」,你比较的是预算,不是模型。

2. 同时报告准确率、token 和延迟。 只看准确率,会把「贵 4 倍、慢 20 秒」的代价藏起来;只看成本,又会把「便宜但不可用」的配置留下。

3. 公共基准有污染风险。 数学和代码 benchmark 的题目可能出现在训练数据里。至少留一套私有题、改写题或时间上更近的题,作为对照。

4. 多数投票的高一致不等于高正确。 前文的模拟已经说明:共享错误前提会让多条样本一起错、且错得一致。把「一致率」当成置信度,会在正需要报警的时候给出高分。

5. LLM-as-a-Judge 与生成器同源时有系统性偏差。 用同一个模型家族做裁判,它更容易认可自己风格的答案。能用规则就用规则;必须用模型时,换一个家族、交换位置、加人工抽样。

6. 思维链不是模型的真实计算过程。 它是模型生成的文本,不是可审计的内部状态。把 CoT 当成「它为什么这么答」的证据,容易过度信任;把 CoT 原样回放给用户,还可能泄露提示词、内部数据或本不该出现的推理细节。

十一、五个反复踩的坑#

  1. 预算被思考吃光,返回空答案。 max_tokens 是总预算,不是答案预算。看到长度截断就重试或降级,别把空字符串当成模型「不会」。
  2. 把推理 token 当成免费或不可见。 它按输出计费,通常还更贵。账单对不上时,先查 reasoning token,再查重试。
  3. 没有验证器就上自洽投票。 错误相关时,投票会把同一个错误放大成共识;先确认错误是分散的,再谈采样。
  4. 用同源 LLM 当验证器。 生成器和裁判共享偏好,裁判会把生成器的错误一起放过。优先用规则、测试、Schema,其次才是异源模型加人工抽样。
  5. 把思维链原样回放给用户或写进日志。 它可能包含敏感信息、错误假设和不适合展示的内部推理。对外给结论和证据,对内只留脱敏摘要。

十二、小结#

  • 推理模型是两层东西。 训练侧让模型「愿意想」,推理侧让你「让它多想」;后者不要求前者,但前者的收益通常更大。
  • test-time compute 买的是采样、搜索和选择,不是智力。 它的上限由两件事决定:正确路径在不在输出分布里,以及你有没有可靠的验证器。
  • 错误相关时,多采样会加固错误。 共享的错误前提不会因为 k 变大而分散;多数投票只能处理分散的随机错误。
  • 验证器决定搜索的上限。 数学和代码好看,是因为它们有便宜可靠的验证器;开放任务的回报会明显下降。
  • 推理买不到知识、题意、外部状态和低延迟。 缺知识补检索,有歧义先澄清,要状态调工具,延迟敏感就级联或降级。
  • 按每个正确答案算账。 推理模型通常每次更贵;只有当标准模型准确率足够低、且错误足够昂贵时,溢价才划算。
  • 级联的关键是验证器。 没有验证器的级联只是随机分流;有验证器,才能把预算花在真正需要的请求上。
  • 把截断、token、延迟、升级率都记下来。 没有这些数,你无法判断下一次该加预算、换模型,还是改验证器。

参考来源#

推理模型:test-time compute 买到了什么,又买不到什么
https://www.hehonglei.cn/posts/reasoning-models-test-time-compute-cost-curve/
作者
Honglei He
发布于
2026-11-05
许可协议
CC BY-NC-SA 4.0