Verification-First(VF)与 Iter-VF:从“先挑错再求解”到真实工程收益(以 Codeforces 难度标注为例)

悲剧
悲剧
2026年1月6日
Prompt Engineering进阶指南

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 ® 看“是否抓住相对规律”
      两者一起看,才不容易被“局部拟合”误导。
1
1
1

评论区

加载评论中...
我的头像
Ctrl + Enter 快速发送