Verification-First(VF)与 Iter-VF:从“先挑错再求解”到真实工程收益(以 Codeforces 难度标注为例)
1. 背景:为什么 Chain-of-Thought 不稳定?
为了让大模型(LLM)处理复杂逻辑问题,业界常用思维链(Chain-of-Thought, CoT):让模型输出一串中间推理步骤,再给出最终答案。
但 CoT 的稳定性并不总是可靠,典型失败模式是:
- 中间步骤一旦走错,错误会自回归式累积:模型为了让后续内容“看起来合理”,会继续沿着错误前提往下编,最终得到“表述流畅但逻辑错误”的答案(俗称幻觉)。
- 修复成本高:
- 训练侧:微调/强化学习有效但成本高、周期长。
- 推理侧:Tree-of-Thought、Self-Consistency 投票等提升明显,但会带来额外采样轮数、更多 Token 与更复杂的工程编排。
核心矛盾是:我们想要一种不需要训练、通用、便宜、对闭源模型也有效的提升方式。
2. 论文方法概览:Verification-First(VF)
清华大学提出的 Verification-First(VF)思路非常“反直觉”:
先给模型一个候选答案(甚至完全错误),要求它先验证,再重新求解。
把任务从“直接生成答案”改为“先做审稿人/质检员”,再做“解题者”。
论文给出的一个工程侧重要信号是:VF 的额外开销通常只是多了一段“验证过程”,相对标准 CoT 的 Token 消耗平均增加约 20%~50%,但在多个任务与模型上都能换来更稳定的正确性提升(无需额外训练)。
2.1 基础版 VF:随机候选答案也能提升
VF 的标准 Prompt 结构可以抽象为:
- 输入:问题 (Q)
- 外部提供:候选答案 (A’)(可以随便给,甚至是错的)
- 指令:先验证 (A’) 是否满足约束;若不满足,指出错误并给出正确解
示例模板(可直接复用):
问题:[Q]
参考答案:[A']
要求:
1) 先验证该参考答案是否正确:逐条对照题目条件/约束,明确指出满足或不满足的地方。
2) 如果参考答案不正确:在不依赖前面错误推理的前提下,重新逐步思考并给出正确答案。
3) 最终只输出一个最终答案(格式按题目要求),并简要给出关键依据。论文的关键发现之一是:候选答案不需要“接近正确”。在数学推理任务上,甚至把所有题目的候选答案都固定成“1”,VF 也能显著优于标准 CoT。
2.2 进阶版 Iter-VF:面向“不能乱猜答案”的任务(例如代码生成)
很多任务无法随便给候选答案(比如让模型生成代码/策略/流程)。此时采用 Iter-VF:
- Round 1:先正常生成一个答案(A1)
- Round 2:把 A1 喂回去,让模型“只针对 A1 做验证与重写”(A2)
- Round N:重复“验证 → 重写”
关键点在于:每一轮尽量“无记忆”,只把“上一轮答案”作为被审查对象,避免传统 Self-Correction 把一长串错误历史一起带入、导致被误导。
这里的“无记忆”也解释了为什么论文会用“马尔可夫链”来类比:把每一轮的输出看作状态 (S_t),Iter-VF 的提示把下一轮 (S_{t+1}) 尽量设计为只依赖上一轮答案 (S_t)(被验证/被重写的对象),而不是依赖更长的历史链路。工程上这会显著减少“早期错误推理痕迹”对后续轮次的污染。
3. 为什么“先挑错”反而更容易找到真相?
论文结合认知科学/心理学给出两个解释,在工程视角也很好理解。
3.1 逆向推理(Reverse Reasoning):验证通常比生成更简单
“生成”需要从零构建结构(方程/约束/逻辑链),容易混变量、漏条件;
“验证”则是把答案代回题目约束做一致性检查:
- 为了证明“错”,必须把正确的约束明确写出来(否则无法反驳)。
- 即便候选答案错了,验证过程里抽取出的约束/关键公式往往正是解题所需的信息。
从工程上看,这相当于强制模型先做一次“约束抽取 + 一致性校验”,再做“求解”。
3.2 克服自我中心(Overcoming Egocentrism):从创作者切换为批判者
LLM 在生成时容易陷入“确认偏误”:它更倾向于相信自己第一个想法,并用后续内容把它合理化。
VF 通过角色切换让模型先站在“批判者”的位置:
- 目标变成“找问题、挑漏洞”
- 这会激活更强的批判性思维,减少“圆谎式续写”
4. 如何把论文搬到真实工程:我们选择了“算法题难度标注”
论文在数学/科学基准上数据很亮眼,但工程上更关心:它能否在真实业务任务里稳定增益?
我们选择的落地场景是:算法编程题难度标注(回归到 Codeforces 难度分),原因很直接:
- 需求明确:海量编程题需要可解释、可迭代的难度标签
- 数据完备:有长期积累的历史标注/对齐数据
- 可量化可验证:难度分是连续数值,天然适合度量模型推理深度的微小进步
- 比论文更贴近工程:这是“评分/回归”任务,而非传统算术/选择题
4.1 为什么用 Codeforces 难度体系?
Codeforces(CF)难度分从 800 起,按 100 递增到 3500,连续且细粒度:
很适合用两类指标评估模型:
- MAE(平均绝对误差):预测分数离真实分数有多近(越小越好)
- Pearson 相关系数 ®:模型是否学到“题目相对难度的内在规律”(越大越好)
需要注意:CF 官方难度来自比赛提交数据反推(Elo 思想),单题脱离比赛会有偏差;因此我们用:
- 核心数据:带人工预估难度的题目(更贴近单题)
- 扩展数据:大量官方难度题(用于增大覆盖面)
5. 实验复现设计:四种策略对照
为了快速验证 VF/Iter-VF 是否值得投入,我们先做小规模方向探索(样本:50 道带人工评分的题)。
5.1 Baseline:只看题面直接打分(实验一)
输入:题面
输出:预测 CF 分数
这代表“最朴素的直出答案”能力。
5.2 强基线:题面 + 两份不同的 AC 代码(实验二)
输入:题面 + 两份不同实现风格的 AC 代码
输出:预测分数
这是一种常见工程改进:用代码帮助模型推断复杂度、边界条件、算法类型。
5.3 引入 VF(实验三)
做法要点:
- Round 1:只给题面,让模型先给一个“初始分数”
- Round 2:把初始分数 + 两份 AC 代码喂回去,要求模型先验证初始分数是否合理,再给出修正分数
这等价于:把“分数”当成候选答案 (A’),触发验证。
5.4 引入 Iter-VF(实验四)
三轮链式结构:
- Round 1(领导者):题面 → 分数
- Round 2(传播者):题面 + Round1 分数 + AC 代码 → 验证并修正
- Round 3(员工):题面 + Round2 分数 + AC 代码 → 再次验证并修正
工程上可以把它理解为:
先快速给一个方向(Round1),再两次“审核-重写”(Round2/3)把误差压下去。
6. 典型结果解读:只挑三组最能说明问题的数据
下面只抽取最具代表性的对比,避免被大量表格淹没;但会直接贴出关键数值(MAE 与 Pearson ®),保证“结论可复核、提升可感知”。
6.1 VF 是否稳定有效?(实验一 vs 实验三)
结论非常清晰:VF 相对“只看题面直出”有稳定提升,并且经常能同时提升 MAE 与 ®。
下面节选 5 个代表模型的“实验一(只题面)→ 实验三(VF)”变化(数值均来自你贴的表格):
| 模型 | 实验一 MAE | 实验三 MAE | MAE 改善 | 实验一 ® | 实验三 ® | ® 改善 |
|---|---|---|---|---|---|---|
| Gemini-2.5-Pro | 301.70 | 181.52 | +120.18 | 0.829475 | 0.938295 | +0.108820 |
| GPT-5.2 | 352.31 | 248.71 | +103.60 | 0.842548 | 0.892961 | +0.050412 |
| DeepSeek-V3.2 | 331.98 | 234.06 | +97.92 | 0.745532 | 0.888176 | +0.142644 |
| GPT-5.1 | 376.34 | 279.64 | +96.70 | 0.737031 | 0.832835 | +0.095803 |
| Kimi-K2 | 348.02 | 291.52 | +56.50 | 0.744971 | 0.827503 | +0.082531 |
解释:这符合 VF 的机制——先验证迫使模型把“题目约束/算法复杂度线索”显式化,从而减少一次性拍脑袋给分。
6.2 Iter-VF 是否比“加上下文”更进一步?(实验二 vs 实验四)
实验二已经给了强信息(题面 + 两份 AC 代码),但实验四(Iter-VF,三轮链式验证)仍能带来进一步收益,且很多时候 ® 的提升更显著。
下面节选 6 个代表模型的“实验二(题面+代码)→ 实验四(Iter-VF)”变化:
| 模型 | 实验二 MAE | 实验四 MAE | MAE 改善 | 实验二 ® | 实验四 ® | ® 改善 |
|---|---|---|---|---|---|---|
| DeepSeek-V3.1 | 323.50 | 176.46 | +147.04 | 0.819333 | 0.938219 | +0.118886 |
| GPT-5.1 | 284.28 | 194.79 | +89.49 | 0.901748 | 0.932787 | +0.031039 |
| Gemini-2.5-Flash | 312.18 | 197.06 | +115.12 | 0.882953 | 0.931070 | +0.048117 |
| Doubao-seed-1.6-Thinking | 279.06 | 192.64 | +86.42 | 0.873126 | 0.937737 | +0.064611 |
| GPT-5.2-Chat | 241.12 | 194.18 | +46.94 | 0.890165 | 0.936313 | +0.046148 |
| GPT-5.2 | 223.71 | 225.15 | -1.44 | 0.918633 | 0.933878 | +0.015245 |
解释:当信息充分时,瓶颈往往不再是“有没有线索”,而是“会不会被第一印象带偏”。Iter-VF 把“审核-重写”变成固定流程,等价于引入低成本的质量控制回路。
6.3 进一步工程化:三段马尔可夫链里,“领导者/传播者”强弱是否关键?(实验五/六/七/八)
你们把三轮 Iter-VF 拟人化成:
- 领导者:Round1 给方向
- 传播者:Round2 做第一轮验证纠偏
- 员工:Round3 再验证落地
几组关键观察(只保留最有解释力的结论):
- 观察 A:领导者/传播者越强,员工越强(实验七优于实验五,远优于实验六)
这说明链条前半段给出的“可验证方向”会显著影响后续收敛质量。 - 观察 B:加入“脏数据”并未显著拉垮(实验八与实验七接近)
这支持你们的“猜想一”:提升主要来自“更接近真理的方向”,而不是模型随便落在一个 safe 区间里蒙对。 - 观察 C:多模型分叉 + 脏数据会增加多样性
实验八在多叉组合 Top 结果更好、梯队更分散,提示“脏数据”可能更适合作为后续强化学习/再排序的额外信号源。
为了让“脏数据是否拉垮”更直观,这里只贴两组最关键的 Top3(实验七:全明星;实验八:全明星 + 脏数据):
- 按 MAE(越低越好)的 Top3:
- 实验七:Kimi-K2 177.6723;GPT-5.1 181.1092;DeepSeek-V3.2 189.6891
- 实验八:GPT-5.1 173.7250;Kimi-K2 175.3750;DeepSeek-V3.1 183.4583
- 按 Pearson ®(越高越好)的 Top3:
- 实验七:DeepSeek-V3.2 0.9490;GPT-5.1-Chat 0.9448;GPT-5.1 0.9441
- 实验八:DeepSeek-V3.2 0.9465;DeepSeek-V3.1 0.9450;GPT-5.1 0.9432
7. 工程落地:把 VF/Iter-VF 变成可复用工作流
下面给出一个“评分型任务(如难度标注)”的实用模板。
7.1 单轮 VF(适合:你已经有一个候选分数)
输入:
- 题面
- 两份 AC 代码(可选但强烈建议)
- 候选分数 (A’)
输出:
- 验证结论(对/错 + 为什么)
- 修正后的最终分数
Prompt 模板:
你是 Codeforces 难度评估审核员。
【题面】
{statement}
【AC 代码 1】
{code1}
【AC 代码 2】
{code2}
【候选难度分(可能错误)】
{score_candidate}
请按如下步骤输出:
1) 验证:从算法类型、关键技巧、边界条件、实现复杂度、常见坑点等维度,判断该分数是否合理,并给出证据。
2) 修正:如果不合理,请给出更合理的难度分(以 100 为步长),并解释为何落在该区间。
3) 最终仅输出一个最终分数(整数)。7.2 三轮 Iter-VF(适合:你没有候选分数,但愿意用固定成本换稳定性)
推荐流程(固定 3 轮,成本可控):
- Round1(领导者):只看题面先给粗分(快、便宜)
- Round2(传播者):题面 + Round1 分数 + AC 代码 → 验证并修正
- Round3(员工):题面 + Round2 分数 + AC 代码 → 再验证并修正
要点:
- 每一轮都明确要求“先验证再给最终分数”
- 输入只喂上一轮分数(避免长历史误导)
- 输出只保留最终分数,把验证过程用于内部质检/审计即可
8. 边界、风险与建议
- 不是什么都能靠 VF 解决:如果输入信息不足(题面不完整、代码不可信),验证也会失真。
- 候选答案质量仍然重要(但不要求接近正确):
- VF:候选可以很差也可能增益,但“完全离谱”会浪费验证预算。
- Iter-VF:前几轮模型越强,后面越容易收敛到更好结果(你们实验也验证了这一点)。
- 评估指标要双轨:
- MAE 看“数值贴近程度”
- Pearson ® 看“是否抓住相对规律”
两者一起看,才不容易被“局部拟合”误导。


评论区