Execution Guided Line-by-Line Code Generation¶
会议: NeurIPS2026(任务清单归档;本文缓存未提供该会议录用依据)
arXiv: 2506.10948
代码: https://github.com/boazlavon/eg_cfg
领域: 代码智能
关键词: 执行反馈、逐行代码生成、无分类器引导、执行轨迹、推理时搜索
阅读版本为 arXiv v2,2025-10-23;以下数字与方法边界均对应该版本,而非对 NeurIPS2026 录用状态的确认。
一句话总结¶
EG-CFG 在推理时预览并执行代码前缀的多种短续写,把运行轨迹注入提示,再通过双分布无分类器引导逐 token 生成、逐行刷新反馈;使用 DeepSeek-V3-0324 时,论文报告 MBPP / HumanEval / DS-1000 准确率分别为 96.6% / 99.4% / 69.9%,但依赖可执行的已提供测试与额外搜索计算。
研究背景与动机¶
代码语言模型擅长补出看起来合理的程序,却未必知道某个变量运行后是什么值、循环是否处理了所有元素,或库调用实际返回了什么。Self-Debugging、MapCoder、LPW 等方法通常先生成完整程序,再执行测试并修复。这种反馈可以定位错误,但如果最早几行已经采用了错误的数据结构或状态更新方式,后续生成仍会沿着该选择展开,最后才付出整段重写的代价。
更早地执行程序也并非直接运行尚未闭合的代码文本就能实现。短续写可能停在函数体、条件分支或循环头之后,缺少后续语句;即便补成可解析的 Python,也可能返回空值、触发异常,或者只完成了任务的一部分。因此,本文不把每个中间候选判成“正确答案”,而是把候选在具体输入上的变量、类型、返回值和异常作为观察材料,让模型判断当前选择将把程序带向什么行为。
本文把执行检查前移到代码行边界,并把“获得观察”与“正式写下下一行”分开:多个试探性续写负责产生运行证据,双分布解码负责吸收这些证据,正式程序仍按 token 增长。核心 idea:利用短程候选的真实执行轨迹,持续改变下一行代码的 token 偏好,而不是只在完整答案失败后追加一次修复指令。
方法详解¶
整体框架¶
输入包含任务描述、推理时可用的测试和目标 Python 函数名,输出是一份候选程序。EG-CFG 不训练新模型:先保留模型在代码块之前的推理前缀,再进入“短程候选预览 → 轨迹反馈 → 双分布解码”的循环;多配置实例可独立并行探索同一题目。
下面是每个实例内部的推理数据流。训练监督不在图中,因为本文没有微调或奖励学习;最终测试检查是控制器的停止条件,不是隐藏评测集提供的生成监督。
%%{init: {'flowchart': {'rankSpacing': 24, 'nodeSpacing': 28, 'padding': 6, 'wrappingWidth': 400}}}%%
flowchart TD
I["任务与已提供测试"] --> A["短程候选预览"]
A --> B["执行轨迹反馈"]
B --> C["双分布逐行引导"]
C -->|换行后刷新| A
C -->|行内复用反馈| C
C -->|代码结束或长度上限| D["独立并行择解"]
D -->|首个通过可用测试的解| O["返回程序并终止其余实例"]
关键设计¶
1. 短程候选预览:先看几条可能的后续路径,而不是直接承诺整份答案
模型首先按所选指令模板生成初始响应,识别最终代码块开始的位置,保留它之前的推理文本;另外记录动态信号的插入位置,使反馈可以放在提示中的固定位置,而不混成正在写的 Python 语句。代码生成开始后,每轮从当前正式前缀出发,生成若干试探性续写,达到指定换行数便停止。候选不是已经选中的下一行,更不是把其中一份完整拷贝成最终答案,而是用于观察局部选择的短程后果。
实验固定候选数 \(s=3\),续写行数 \(d\in\{2,3,6,8\}\)。较短预览可以较早获得反馈,较长预览则更可能形成有意义的循环体或返回路径;论文把不同长度交给不同配置探索,没有证明某一长度普遍最优。正文将候选生成称为 beam search,但式 (6) 和附录 C 写的是按温度逐 token 抽样,未明确给出传统束搜索的保留与排序规则。因此,这里保留作者的命名,同时将可确认的机制限定为“生成多个短续写候选”,不额外补造标准束搜索算法。
短续写经常不完整,作者先尝试 AST 解析,失败时补 pass 再试,仍失败则逐步删去末行并重试,之后对抽取结果去重。这一步只解决语法截断问题:补空语句不会补出缺失的算法逻辑,AST 通过也不意味着变量已定义、返回值正确或测试能够通过。候选去重后数量还可能小于原始候选数,不能把每轮三条预览当成始终有三条独立的有效路径。
2. 执行轨迹反馈:保留程序发生了什么,而不只给成功或失败的标签
试探性续写以当前已有代码为上下文,抽取出的程序片段在全部已提供测试上执行。理解这一点时应把被观察对象视为“已有代码前缀加候选续写形成的部分程序”,而不是把孤立的函数体中间几行当成独立程序。正文与附录 C 的抽取、执行调用都以候选符号简写,没有把拼接前缀单列成一步;因此,缓存不足以核实实现中具体在何处拼接,也不能据此宣称系统可以无上下文执行任意片段。
自定义调试器记录四种事件:call、line、return、exception。每个事件包含源代码行号、变量名到值与类型的映射,以及适用时的返回值和异常信息。模型因此可以看到不仅是“结果错了”,还包括某个累计量在哪一步变化、分支是否进入、某个操作抛出了什么异常。未完成候选的运行失败也可以成为反馈,而非自动淘汰所有失败轨迹。
动态信号把固定指导语与“候选代码、测试输入、对应轨迹”组合起来,插回指令提示中的固定位置,再接上当前模型响应和代码前缀。这样,轨迹仍保留产生它的候选与输入,避免只提供一个缺乏来源的异常字符串。附录 B 用两条候选、一个测试说明这种结构,这是提示示例,不是实验候选数改成两条的证据。
这个阶段没有用隐藏测试指导生成,也没有训练一个程序正确性分类器。原始运行信息是给语言模型解释的软条件,而不是一条经外部评分器认证的“最佳候选”指令;但最终择解仍会使用可用测试的通过/失败结果,不能把“不用显式正确性标签引导每个 token”扩大为“整个系统从不判断测试是否通过”。
3. 双分布逐行引导:用轨迹造成的概率变化调节正式续写
在同一个正式代码前缀上,模型分别计算不含新增轨迹的提示分布与含轨迹的提示分布。作者称前者为 unconditional,但它仍包含任务说明、示例或指令、推理前缀和已生成代码;准确含义是“相对执行反馈无条件”,而不是无提示生成。两次查询的差异才用于无分类器引导(classifier-free guidance,CFG)。
式 (13) 的核心组合为:
其中,\(p_{\text{sol}}\) 是没有新增轨迹的当前提示,\(p_{\text{dyn}}\) 是插入轨迹后的提示,\(\gamma\) 控制放大程度。式中省略了把组合分数变成归一化概率所需的归一化项;对于当前步的 token 排序和 argmax,该项与 token 无关,不影响选择。不能直接把未归一化的对数分数称作严格归一化概率,也不能把 CFG 理解为只向提示追加一段文字。
当 \(\gamma=0\) 时退回不含执行反馈的分支;当 \(\gamma=1\) 时就是含轨迹的条件分布,并没有移除执行反馈;当 \(\gamma>1\) 时进一步放大轨迹使 token 相对更可能或更不可能的差异。因此,消融中的“w/o CFG”实际指固定为普通条件解码,考察的是对比分布引导,而非完全禁用运行信息。
正文使用“sample”描述正式续写,但式 (14) 和附录算法 2 明确采用 \(\arg\max\) 选择下一个 token。笔记据公式描述正式 token 决策,同时保留措辞不一致这一实现边界,不把候选抽样与正式代码抽样混成同一过程。行内每一步的代码前缀继续增长,两分布也随此前缀更新;保持不变的是本行使用的轨迹材料,不是所有 token 概率。
第一次生成代码时先建立反馈;此后只有前一个 token 含换行时才重新生成候选、执行并刷新轨迹。换言之,执行观察按行更新,反馈影响却作用于行内每个 token。这样不会在尚未闭合的一行中途不停换观察依据,同时也不是逐 token 重新运行程序。遇到代码结束标记或长度上限,实例返回自己生成的候选程序,再交给控制器检查。
4. 独立并行择解:用配置多样性探索,而不是让实例互相讨论
同一题目可以交给多个独立实例,每个实例选择自己的温度、预览长度、引导强度和提示模板。它们不交换消息、不合并轨迹,也没有“规划者向程序员发指令”的角色分工。图中的择解节点表示控制器汇总各实例的完成结果;每个实例此前都在独立运行相同的三个内部阶段,而不是最后才启动并行。
实验列出温度 \(t\in\{0.7,0.75,0.85,0.95,1.2,1.5\}\)、引导强度 \(\gamma\in\{0,0.5,1,3\}\),以及两种提示模板:标准 DeepSeek-Coder 3-shot 模板和鼓励更原子化、逐步实现的另一模板。与前述四种预览长度相乘,完整笛卡尔积有 192 种可能配置,但论文没有充分交代每题实际启用数量、并发限制或调度预算,不能把 192 当成确认的常驻并行实例数或成本估计。
控制器返回首个通过全部可用测试的程序,随即终止其余实例;若没有实例找到这样的程序,返回失败。这一“成功”只对推理时可用测试成立,并不等于隐藏测试正确性被事先知道。多配置搜索可以覆盖不同局部选择,但也可能在测试较弱时提早接受只适配样例的程序;最终隐藏评测正是检验这一差距,而非充当在线择解的 oracle。
一个完整示例¶
设一个独立的说明性任务要求返回列表中所有正数之和,可用样例输入为 [-2, 3, 4]、预期返回值为 7。这不是论文原有代码示例,也不是新增实验结果。正式前缀已经建立累计变量并开始遍历列表,系统以三条短续写观察不同的状态更新路径。
某个候选把负数也累加进去,轨迹会显示累计量由 0 变为 -2,最后得到 5;另一个候选过滤非正数,最后得到 7;第三个候选可能在循环内部提前返回,显示只处理了部分输入。若候选停在尚未闭合的分支头,AST 抽取可以补 pass 让部分程序接受语法解析,但这不代表它已经完成求和任务。
系统将各候选、该测试与运行轨迹一起注入提示,不必先把第二条候选宣布为获胜者。双分布逐行引导据此调整下一行正式 token 的偏好,正式生成不必与任何候选逐字相同;本行内复用这些轨迹,换行后再从新的正式前缀建立预览。最后,控制器只知道程序是否通过已有样例,其他输入上的正确性仍需独立测试。
损失函数 / 训练策略¶
本文是推理时算法,没有新增损失函数、反向传播、微调数据或强化学习奖励。较小模型 DeepSeek-Coder-1.3B 在 RTX 2080 Ti / RTX 3090 上运行,DeepSeek-V3-0324 通过 Fireworks AI 云端接口运行;接口需提供用于双分布组合的 token 对数概率。论文未充分说明有限 log-prob 输出下的词表覆盖与组合细节,不能默认任意黑箱聊天接口都可直接复现。
实验关键数据¶
主实验¶
指标是通过评测所要求全部测试的题目比例,不是一次无搜索生成的 pass@1。MBPP 有 500 题、HumanEval 有 164 题、DS-1000 有 1000 题;CodeContests 使用 ExecEval 框架。HumanEval、HumanEval-ET、MBPP-ET、CodeContests 和 DS-1000 的最终评测使用推理阶段不可访问的隐藏测试;MBPP 的已提供测试需与这些隐藏评测区分。
下表仅选论文表 1–4 中同为 DeepSeek-V3-0324 的结果。不同模型、外部论文报告值及 CodeContests 的自定义测试集结果未混作严格同设置对比;横向收益也不代表等 token 或等 GPU 预算收益。
| 数据集 | Baseline LLM 准确率 (%) | EG-CFG 准确率 (%) | 同模型参考方法与准确率 (%) |
|---|---|---|---|
| MBPP | 82.8 | 96.6 | MapCoder 87.2;MGDebugger 86.8;LPW 84.0 |
| MBPP-ET | 64.8 | 73.0 | MapCoder 69.6;MGDebugger 64.8;LPW 65.2 |
| HumanEval | 82.92 | 99.4 | MapCoder 96.95;MGDebugger 87.20;LPW 95.12 |
| HumanEval-ET | 79.20 | 89.02 | MapCoder 81.70;MGDebugger 81.09;LPW 84.74 |
| CodeContests | 41.81 | 60.6 | MapCoder 50.30;CodeSim 52.72 |
| DS-1000 | 38.9 | 69.9 | 表 4 未列同模型的其他方法 |
结果来源:表 1 为 MBPP 系列,表 2 为 HumanEval 系列,表 3 为 CodeContests,表 4 为 DS-1000。论文在 HumanEval 上是追平其列出的 LDB 99.4%,不能写成独占领先;其他 SOTA 说法也仅指该版本收录的对比,而不是持续更新的排行榜结论。
消融实验¶
下表来自表 6,模型固定为 DeepSeek-Coder-1.3B,而非上表的大模型。最小轨迹仅保留完整轨迹的最后一个事件,不是彻底不执行程序。
| 配置 | MBPP 准确率 (%) | MBPP-ET 准确率 (%) | 说明 |
|---|---|---|---|
| EG-CFG | 83.2 | 59.8 | 完整方法 |
| no beam search | 58.2 | 43.6 | 将多候选预览改为单个续写 |
| w/o CFG | 75.2 | 48.2 | 固定引导强度为 1,仍用执行反馈条件分布 |
| minimal trace | 76.4 | 51.2 | 仅提供最后一个运行事件 |
| Baseline LLM | 49.4 | 42.6 | 标准提示基线 |
取消多候选预览后,MBPP 从 83.2% 降到 58.2%,MBPP-ET 从 59.8% 降到 43.6%,是三项消融中降幅最大的一项。普通轨迹条件解码仍优于基线,但低于完整方法;详细中间轨迹也优于仅保留末事件。这支持“预览多样性、轨迹细节与对比分布引导共同起作用”,不能据单因素移除推断它们的独立可加贡献。
关键发现¶
表 5 的 MBPP 每题运行时间显示,并行设计不等于总是更快。以下均为作者报告的秒数均值与标准差,而非本地复现实测。
| 模型 | EG-CFG (s) | MGDebugger (s) | MapCoder (s) | LPW (s) |
|---|---|---|---|---|
| DeepSeek-Coder-1.3B | 123.23 ± 344.91 | 495.16 ± 411.07 | 121.9 ± 213.89 | 197.71 ± 128.07 |
| DeepSeek-V3-0324 | 271.37 ± 271.45 | 842.24 ± 705.19 | 283.84 ± 197.54 | 87.51 ± 210.84 |
- 小模型下 EG-CFG 的均值接近但略高于 MapCoder;大模型下明显慢于 LPW。标准差很大,不能把均值概括为所有题目的稳定速度优势。
- 作者把大模型 MBPP 上 MGDebugger 和 MapCoder 的重试次数从 5 提到 200:前者从 86.8% 到 93.6%,后者从 87.2% 到 88.8%,仍低于 EG-CFG 的 96.6%。这是 40 倍重试数的压力对比,不是实际 token 消耗、GPU 时间或总费用严格匹配的证明。
- 扩展测试准确率依然明显低于原测试准确率。执行反馈帮助产生更可靠的解,但没有消除有限测试与真实泛化之间的缺口。
- 作者说明基线适配 DeepSeek 时需要调试,尤其 LPW 在小模型上出现异常低分;QualityFlow 未公开代码,未做同模型复现。比较应保留这些实现与来源边界。
亮点与洞察¶
- 观察先于承诺。 试探候选可以先暴露局部选择的运行后果,再决定正式代码。这与生成完整答案后修复不同,反馈位置本身成为推理时算法的一部分。
- 语法可解析与语义正确分开处理。 AST 抽取让截断程序有机会产生轨迹,轨迹再告诉模型运行出了什么问题。把两者分开,才能避免将“可运行片段”误当成“正确解”。
- 反馈内容与反馈权重是两件事。 轨迹进入提示提供信息,CFG 则改变该信息相对原有代码先验的影响。固定为普通条件解码的消融仍有收益,说明不应把所有效果都归因于 CFG 单独一项。
- 并行性来自独立探索,不来自协作对话。 这减少了实例间的顺序依赖,但把资源调度与停止条件变成了重要工程问题,不能只报告准确率而忽略搜索成本。
局限与展望¶
- 需要可执行且有覆盖面的测试。 没有测试、测试输入过少或环境难以搭建时,轨迹反馈的价值会受限;通过样例不能证明隐藏输入正确。可以研究覆盖率驱动的测试选择,但本文没有验证该改进。
- 额外计算未被并行性消除。 候选生成、重复执行与双分布查询都增加工作量。应补充每题实际实例数、token 数、执行次数、并发限制和费用,再讨论效率,而非用 192 种可能配置代替真实预算。
- 短程预览难以替代全局规划。 作者承认当前方法自底向上,未利用任务分解;多文件状态和长程依赖也尚未被本文实验覆盖。与自顶向下规划结合是合理方向,但不是已验证结论。
- 执行需要隔离,而不是仅靠 AST。 生成代码应在受控沙箱中执行,并设置超时、资源和外部访问限制。本文的正确率实验及语法抽取不构成代码安全保证,也未提供足够依据确认完整隔离机制。
- 实现描述仍有空白。 beam search 与抽样记号、正式生成的 sample 与 argmax、候选执行前的前缀拼接以及实际并行调度细节均需结合实现核实。当前缓存附录 A/B 主要提供图注,不能从中复原未显示的完整提示正文。
相关工作与启发¶
- vs Self-Debugging / Reflexion:这些方法主要在完整答案执行后利用错误反馈修复;EG-CFG 在形成最终代码时就预览局部后果。代价是更频繁的运行与双分布计算,而不是消除测试依赖。
- vs MGDebugger / LPW:MGDebugger 利用层次调试和模型模拟轨迹,LPW 将规划与调试组织为分阶段流程;本文主要用真实执行的短候选轨迹改变下一行解码。可探索把规划与局部执行引导结合,但不能据此声称本文已包含高层规划器。
- vs MapCoder / AgentCoder:这些工作强调角色或阶段间交互,本文的实例仅配置不同、彼此独立。应区分“多实例搜索”与“协作式多智能体”以免误解贡献来源。
- vs 通常的文本 CFG:通常的条件信号较固定,本文的轨迹随程序前缀在行边界刷新。可迁移的思路是在可执行环境中动态提供行为证据,例如数据库查询或仿真,但本文没有给出这些领域的实验。
评分¶
- 新颖性: 4/5 — 将动态短程执行轨迹与双分布解码结合,反馈时机有明确辨识度。
- 实验充分度: 4/5 — 六个评测、两种规模和机制消融较全面,实际计算预算与部分实现边界不足。
- 写作质量: 3/5 — 主要流程清楚,但束搜索、抽样、argmax 和程序拼接的表述不够严密。
- 价值: 4/5 — 对有测试、可隔离执行的代码生成很有参考价值,尚不能直接推广为真实软件工程的普遍解决方案。