北航ExeCRE:以执行一致性建模可靠度,误导反馈从113例降至14例

ExeCRE: Execution-Consistency Guided Reliability Estimation for Self-Correcting Code Generation

论文原文 ↗ 论文发布 解读发布 解读:AI前沿分享

北航ExeCRE:以执行一致性建模可靠度,误导反馈从113例降至14例 论文图示

大模型写代码早已跨过生成简单函数的阶段,但在处理竞赛级算法题与复杂工程逻辑时,依然容易出现细微逻辑漏洞或边界条件失误。为了弥补单次生成的不足,基于执行反馈的“自纠错”(Self-Correction)机制逐渐成为各大代码生成框架的标配。这种范式的底层直觉非常直接:让模型先写出候选代码,再通过执行生成的测试用例捕获错误,并将报错信息反馈给大模型进行多轮重写。

ArXiv URL:https://arxiv.org/abs/2608.04439v1

然而,这一流程暗藏一个致命假设——用于提供反馈的监督信号本身是完全可信的。在没有标准答案(Ground Truth)的实际测试场景中,模型往往需要依靠大模型自我判断,或者借助模型生成的“参考代码”(如朴素的暴力解法)去构造测试集。当参考代码本身存在隐蔽 Bug 时,错误的反馈就会把原本正确的代码“改错”,或者让错误的代码“越改越偏”。

针对执行引导自纠错中的信任危机,来自北京航空航天大学的研究团队提出了 ExeCRE(Execution-Consistency guided code Reliability Estimation)框架。该方法放弃了让大模型直接充当裁判的传统路线,而是将统计学中用于处理带噪标注的经典 Dawid-Skene 模型引入代码执行分析。通过在大量随机输入上收集候选代码的执行一致性,ExeCRE 能够在无标签环境下精确量化每一份参考代码的潜在可靠度,并设置安全回退机制。在 LiveCodeBench 基准测试中,ExeCRE 展现出极强的纠偏能力:在基于 GPT-5.2 的自纠错流程中,对原本正确代码产生的误导性反馈从代表性基准的平均 113.2 例骤降至 14.0 例,有效遏制了自纠错中的雪崩式错误。

自纠错流程对比

自纠错的阿喀琉斯之踵:当裁判本身在犯错

在探讨 ExeCRE 的设计之前,需要先审视现有代码自纠错框架的核心瓶颈。常规方案获取执行反馈主要有两种路径:第一种是直接让大模型针对题目生成若干测试用例;第二种是利用大模型生成一份相对低效但逻辑直观的暴力解法代码(Brute-force Reference Code),再随机生成输入并由暴力解法跑出“基准输出”,以此拼装成测试套件。

后一种方法在近年来颇受关注,因为暴力搜索在多数情况下确实比精巧的高级算法更容易写对。但现实情况是,大模型生成的暴力代码并非无懈可击。它可能漏掉了某些边界分支,可能对题目约束理解存在微小偏差,更可能在特定极端数据下直接崩溃。

一旦参考代码出错,它所生成的测试用例就变成了“毒药”。当自纠错流水线拿着有毒的测试集去检验初始代码时,如果初始代码原本是完全正确的,执行测试就会判定其未通过,进而强迫模型基于错误的反例修改代码;如果初始代码原本就有 Bug,且巧合地与参考代码犯了同样的错误,流水线反而会得出“测试全过”的假象,导致错误代码被最终采纳。

现有的多数自纠错与代码选择方法对此采取了回避策略。一些方案依赖大模型作为评判者(LLM-as-a-Judge),但大模型对代码语义的主观判断极易受到表面格式影响,难以捕获复杂的边界反例;另一些方案采用多数投票(Majority Voting),假设多个候选解在某个输入下取得相同输出即可代表正确。但代码生成领域存在显著的“共性错误”现象:在同一个复杂分支上,多个模型往往会写出具有相同思维定势的错误实现,导致错误代码在投票中形成虚假的多数派。要打破这种恶性循环,必须建立一套不依赖真实标签、且能有效解开代码共性偏差的可靠度量化工具。

ExeCRE 架构:从执行行为中推断代码可靠度

ExeCRE 的核心理念是:代码的正确与否不能仅凭几次测试或模型的自我感觉来判定,而必须从多份候选实现对海量输入的“执行一致性图谱”中统计推断出来。系统整体分为三个紧密相扣的阶段:结构化测试输入构造、执行一致性投影,以及基于 Dawid-Skene 模型的隐式可靠度推断。

ExeCRE 方法架构图

模式驱动的高效测试输入生成

要暴露出不同代码之间的微妙差异,测试集必须具备足够的广度与随机性。两份逻辑有差异的代码可能在简单的样例上表现完全一致,只有当输入覆盖到特定约束边界时,分歧才会显现。但如果频繁调用大模型去逐条生成测试用例,不仅推理成本极高,而且生成的数据往往高度同质化。

ExeCRE 采用了一种 Schema 驱动的输入构造策略。系统仅调用一次大模型,让其从题干中抽取出输入数据的格式规范与类型约束(Schema)。随后,系统利用规则解析引擎批量生成数以千计的随机输入,同时支持标准输入(stdin)和函数传参调用风格。为了防止由于 Schema 理解错误导致后续批量执行崩溃,ExeCRE 引入了执行前校验:一旦某种 Schema 候选在代码执行中引发了超过 10% 的格式不匹配或运行时异常,该 Schema 就会被立即丢弃并重试(最多重试三次)。这一机制以极低的 API 成本,稳定产出了数千个兼具语法有效性与行为辨识度的测试输入 $\mathcal{I}{P} = {I{1}, I_{2}, \dots}$。

降维打击:执行一致性二值投影

拿到测试输入集合 $\mathcal{I}{P}$ 与多份候选参考代码 $\mathcal{C}{P} = {C_{1}, C_{2}, \dots}$ 后,将每份代码在所有输入上运行,可以得到一个原始执行输出矩阵 $\mathbf{O} = [O_{ij}]$,其中 $O_{ij}$ 表示代码 $C_j$ 在输入 $I_i$ 上的输出结果。

如果直接将这些输出视为标注结果去套用统计模型,会遇到严重的维度灾难。在代码生成任务中,字符串、浮点数、数组等可能的输出空间是无限的。如果每个独特的输出都作为一个标签,候选代码的数量远远无法支撑模型去估计多分类的混淆矩阵。

为了化解这一数学困难,ExeCRE 提出了执行一致性投影机制。针对每一个具体的输入 $I_i$,首先找出在所有候选代码中出现频次最高的主流输出值,然后把每个候选代码 $C_j$ 的输出映射为一个二值变量 $U_{ij}$:

\[U_{ij} = \begin{cases} 1, & \text{若 } O_{ij} \text{ 等于输入 } I_i \text{ 下频次最高的输出值且不是异常值} \\ 0, & \text{若 } O_{ij} \text{ 与最高频输出不同且不是异常值} \\ \text{NaN}, & \text{发生运行时错误或超时} \end{cases}\]

需要强调的是,这一二值投影并不预设“多数人的输出就是对的”。在这个投影体系中,每个输入 $I_i$ 都对应一个潜在的“一致性状态”。即使因为共性 Bug 导致多数代码同时输出了错误结果,只要模型能够分析出这种偏差模式,真实可信的行为完全可能落在少数派(即 $U_{ij} = 0$ 的一侧)。这一投影将无限维的执行输出坍缩为了“一致/不一致”的二元信号矩阵,使后续的统计建模成为可能。

Dawid-Skene 模型的潜变量推断

在群体智能与数据标注理论中,Dawid-Skene 模型是一种经典的 EM(Expectation-Maximization)算法,专门用来在没有标准答案的情况下,联合推断出每个任务的真实标签分布以及每个标注员的特异性错误率。

ExeCRE 巧妙地将这一理论映射到代码执行领域:测试输入相当于待标注的样本实例,各个候选参考代码相当于可能带有系统性偏差的标注员,而观察到的二值一致性矩阵就是标注员交出的答卷。

对于每个输入 $I_i$,引入一个潜在类别指示变量 $T_{iq} \in {0, 1}$,代表该输入对应的可信一致性状态到底落在二值投影的哪一侧。记类别先验为 $p_q = P(T_{iq} = 1)$,代码 $C_j$ 在潜在真实状态为 $q$ 时输出观察值 $a$ 的条件转移概率为:

\[\pi^{(j)}_{qa} = P(U_{ij} = a \mid T_{iq} = 1), \quad q, a \in \{0, 1\}\]

这里的混淆矩阵参数 $\boldsymbol{\pi}^{(j)}$ 精确捕捉了每份代码的个人特质:某些代码在绝大多数情况下都极其稳定,其对角线概率非常高;而某些代码在特定类型的输入上容易产生系统性偏移。

在 EM 算法的 E 步中,模型利用当前的代码错误率参数与类别先验,通过贝叶斯公式更新每个输入样本处于各个潜在一致性状态的后验期望 $\hat{T}_{iq}$:

\[\hat{T}_{iq} \triangleq E[T_{iq}\mid U] = \frac{\prod_{j\in\Omega_i}\prod_{a\in\{0,1\}}\left(\pi^{(j)}_{qa}\right)^{n^{(j)}_{ia}}p_q}{\sum_{q^{\prime}=0}^{1}\prod_{j\in\Omega_i}\prod_{a\in\{0,1\}}\left(\pi^{(j)}_{q^{\prime}a}\right)^{n^{(j)}_{ia}}p_{q^{\prime}}}\]

在 M 步中,模型根据更新后的后验概率重新最大化完全数据的对数似然,更新先验分布 $p_q$ 以及各个代码的条件误差概率 $\pi^{(j)}_{qa}$:

\[p_q \leftarrow \frac{1}{\lvert I_P \rvert}\sum_{i=1}^{\lvert I_P \rvert}\hat{T}_{iq}, \qquad \pi^{(j)}_{qa} \leftarrow \frac{\sum_{i=1}^{\lvert I_P \rvert}\hat{T}_{iq}\,n^{(j)}_{ia}}{\sum_{i=1}^{\lvert I_P \rvert}\hat{T}_{iq}}\]

经过数轮迭代直至收敛,系统最终可以为每份候选代码 $C_j$ 计算出一个综合的潜在可靠度得分 $\alpha_j$:

\[\alpha_j \triangleq \hat{p}_1\,\hat{\pi}^{(j)}_{1,1} + \hat{p}_0\,\hat{\pi}^{(j)}_{0,0} \in [0, 1]\]

该得分反映了代码在统计意义上符合整体可信行为的概率。

为什么统计推断能击败朴素投票?

为了直观展现 Dawid-Skene 为何比简单的多数投票更加敏锐,本文给出了一个极具代表性的条件逻辑场景:假设一道题目要求判定优惠券是否生效,正确规则是“总金额 $\ge 25$ 且商品件数 $\ge 3$”。

在候选代码池中,代码 A、B、C 完整实现了正确规则;代码 D、E 错误地写成了“总金额 $> 25$”;代码 F、G 错误地写成了“件数 $> 3$”。

如果使用基于频率的朴素多数投票,错误代码在关键用例上的联合抱团会拉低正确代码的置信度。在这组用例上,朴素投票给正确代码 A–C 计算出的平均分仅有 $13/21$,给错误代码 D–G 的得分也有 $11/21$。两者极其接近,且均远低于高置信度门槛,投票机制根本无法分辨孰优孰劣。

而 Dawid-Skene 模型能够联合分析所有样本在全局的表现。它能识别出 D、E 与 F、G 分别在不同测试子集上表现出不稳定的转移行为,从而在最大似然推断中压低它们的可靠性得分,给始终保持一致的 A–C 赋予压倒性的高分。这种从跨输入行为相关性中剔除噪声的能力,是传统启发式投票完全不具备的。

在完成评分后,ExeCRE 设定了严格的准入阈值 $\tau = 0.95$。只有当最高评分代码的可靠度满足 $\alpha^* \ge 0.95$ 时,系统才会采纳其构建的大规模测试集;若所有候选代码的可靠度都未能达标,ExeCRE 将直接触发回退(Fallback)逻辑——完全放弃生成参考测试,仅依靠题干自带的公开基础用例进行保守纠错。这种“宁缺毋滥”的设计,从源头上切断了劣质参考用例对生成管道的污染。

评测见证:从压制误导到提升最终求解率

为了在严苛环境下检验 ExeCRE 的表现,作者选取了 LiveCodeBench v6(包含 2025 年 1 月至 5 月发布的 182 道全新算法题)展开评估,以彻底规避大模型预训练过程中的数据污染。评估模型跨越了不同量级,包括开源的 LLaMA-3.1-8B-Instruct、Qwen2.5-Coder-32B-Instruct,以及前沿的 DeepSeek-V3.2 与 GPT-5.2。

在代码自纠错中,衡量监督信号质量的核心指标在于语义层面的精确率(Precision)与召回率(Recall)。如果采纳的参考代码本身包含 Bug,就会在自纠错中制造出误导性反馈。在对 DeepSeek-V3.2 候选代码的可靠度识别测试中,ExeCRE 表现出显著的判别优势:

  1. 相比大模型自身作为裁判(LLM Judge)或先分析后判断的 CodeJudge,ExeCRE 在语义正确代码识别上的 F1 得分大幅领先;

  2. 基于统计学习的 ExeCRE 在 Precision 指标上显著优于基于多数投票的 ExeCRE-Voting,这意味着跨过 0.95 门槛被采纳的代码几乎全部是语义上完全正确的程序;

  3. 对于由于算法设计错误而确实无法选出可靠代码的难题,ExeCRE 展现出高度审慎的回退能力,没有强行给出误导性结论。

这一可靠度筛选能力在后续的自纠错闭环中产生了立竿见影的效果。传统的自纠错基准(如 TextGrad 与 ALGO)经常出现“越纠越错”的退化现象:本来在初始阶段已经 Accepted 的代码,在被注入未经筛选的自生成测试用例后,被误导性报错强行打断并反复修改,最终改得面目全非。而在 GPT-5.2 的自纠错实验中,面对原本已经正确的初始代码,传统基准平均触发了高达 113.2 例误导性修正指令;而在引入 ExeCRE 作为守门人之后,这一破坏性指标被压缩至 14.0 例,降幅达到了惊人的 87.6%。

在抑制误导的同时,ExeCRE 带来的正面修正收益也十分显著。由于输入的测试信号高度可信,模型在修改初始错误代码时能够得到精准的边界反例,避免了在错误的调试方向上浪费 Token。最终在四种不同规模的模型上,整合了 ExeCRE 的自纠错流水线在 Pass@1 综合表现上均超越了包括 ConTested、Oracle-Guided、B4 以及 TextGrad 在内的所有对比方案,在各难度梯度(Easy、Medium、Hard)上均实现了稳健的性能增益。

除了算法编程任务,研究团队还将该机制迁移至基于代码的数学推理基准 GSM8K(采用 Program-of-Thought 设定)。实验表明,对生成的计算代码运用同样的执行一致性与 Dawid-Skene 错误率建模,同样能够有效筛选出可靠的数值解,准确率较未加控制的代码推理基线获得了稳定提升。这印证了该框架在广义“代码辅助推理”任务中的普适潜力。

启示:推理时计算不仅需要发散,更需要统计锚点

ExeCRE 的成功给当下的代码大模型与 Agent 自主进化研究提供了一个极具价值的视角。当前整个学术界与工业界都在全力探索 Test-time Compute(测试时计算)与模型自我反思,很多人倾向于把所有环节都寄托在更强的大模型 Prompting 或多智能体辩论上。

但事实证明,大模型系统内部产生的噪声极易产生自我强化与幻觉放大。将经典统计推断理论——尤其是经过数十年检验的潜变量分析与带噪标注学习算法——重新引入现代大模型流程,往往能以极低的额外计算成本,解决纯靠提示词工程难以逾越的可靠性鸿沟。

知道何时该相信自己的反馈,更知道何时该主动放弃有毒的线索并安全回退,这种带有概率统计锚点的自省能力,或许才是让大模型代码生成在复杂生产环境中真正落地的关键拼图。