行业资讯
ETH苏黎世联邦理工伯克利大学联手破解AI写代码的“盲区“
这项由ETH苏黎世联邦理工学院、INSAIT索菲亚大学、加州大学伯克利分校共同完成的研究于2026年7月以预印本形式发布论文编号为arXiv:2607.13921发表在计算机编程语言领域cs.PL。感兴趣的读者可通过该编号在arXiv上查阅完整论文。一、当AI写代码遇上亡羊补牢的困境程序员们有一个共同的经历写了几百行代码满心期待地按下编译按钮结果屏幕上喷出几十条红色报错信息。这时候你才意识到问题早在第10行就埋下了但后面那200行全是建立在这个错误假设上的废物。这就是所谓的错误雪球效应——一个小错误在没人察觉的情况下不断滚大最终演变成一场灾难。现在AI写代码遇到了同样的问题甚至更严重。当今最强大的AI大语言模型可以理解为一种自动完成代码的超级智能在生成代码时是从左到右、一个字符一个字符地往外输出的就像一个人在写作文时从第一个字写到最后一个字中间完全不回头检查。一旦写出了一个错误的假设后面所有的内容都可能建立在沙滩上。研究团队把目光投向了Rust这门编程语言。Rust是近年来极受追捧的系统编程语言它最大的特点是有一套极其严格的安全规则——这套规则能在程序运行之前就发现潜在的内存安全问题。然而正因为规则太严AI在生成Rust代码时频繁踩雷生成的代码往往根本无法通过编译器的检查。目前解决这个问题主要有两条路。第一条路叫做事后反馈等AI把整个代码文件写完再拿去给编译器可以理解为检查代码合法性的裁判检查如果不通过就把错误信息反馈给AI让它重来一遍。这条路最大的问题就是亡羊补牢——错误早就犯了反馈却来得太晚AI可能已经在错误的基础上又写了几百行代码。第二条路叫做约束解码在AI每输出一个字符的时候就实时检查这个字符能不能要如果不合法就强制它换一个。这条路听起来很美但问题是它需要把Rust编译器从头到尾重新实现一遍工程量极其庞大而且完全不支持那些只对外提供接口、无法查看内部机制的商业AI如GPT、Claude等。研究团队的贡献就是找到了这两条路之间那条几乎被所有人忽略的中间路径。二、密封这个天才想法让不完整的代码也能被检查核心思路其实出奇地简单一旦听懂了你会觉得这为什么之前没人做过。假设AI正在写一个函数才写到一半后半截还没出来。正常的Rust编译器面对这种半截代码会直接报语法错误——这不是一个完整的程序我没法检查。研究团队的解决方案是在这半截代码后面机械地补上一些占位符把它变成一个语法上完整的程序然后再交给编译器检查。这个补全的过程研究团队给它取了一个名字叫做密封Sealing而执行这个操作的工具叫做密封器Sealor。密封器不是要猜测程序员接下来想写什么它只是做最简单的机械补全——把没有关闭的大括号关上把还没写完的表达式用一个万能占位符代替让整个代码文件在语法层面上看起来完整。用一个更直观的类比来理解密封器就像一个脚手架工人。当一栋楼还没建完的时候为了检测现有结构的承重能力他们会用脚手架临时撑住那些还没建好的部分让检测工程师能够进场检查已建部分有没有问题。检测完成后脚手架拆掉建筑继续施工。密封器做的就是这个脚手架的工作——让编译器能够对半截代码进行有意义的检查。为了让密封后的代码尽可能不引入新的假错误研究团队设计了两种占位符。第一种叫做holediv()对应于Rust里的panic!()——这个表达式的语义是程序在这里崩溃永远不会正常返回。因为不会正常返回编译器就不会要求后续代码满足各种借用和类型约束从而避免了很多因为后续代码还没写而产生的假报错。第二种叫做holeval()它是一个泛型函数调用时会被类型推断自动匹配成周围代码期望的任何类型相当于这里放一个任意类型的合法值。有了这两个占位符密封器可以在保持编译器检查有效性的同时最大限度地减少因为代码还没写完而引入的误报。三、不能误判密封器必须满足的两个保证密封器要能真正发挥作用必须满足两个关键性质研究团队用数学语言对它们进行了严格的定义。第一个性质叫做完备性Completeness。用大白话说只要一段半截代码存在某种合法的写法能让它变成完整的程序密封器就绝对不能把它拒绝掉。这是最重要的保证——如果AI正在写一段本来可以成功的代码密封器却提前给它判了死刑那AI就会无缘无故地被打断开始朝错误的方向修改最终越改越乱。完备性保证了密封器的不冤枉好人原则。第二个性质叫做健全性Soundness。用大白话说如果密封后的程序通过了编译器检查那就说明原来那段半截代码确实存在某种合法的延续方式。换句话说如果密封器接受了某段代码这个接受是有实际依据的不是瞎猜的。健全性保证了密封器的不放过坏人原则当然这个原则可以在一定程度上放松——因为密封器即使漏掉了一个错误后面还有机会再查。研究团队明确指出这两个性质并不需要同时在所有情况下都完美成立。完备性是更重要的——绝对不能冤枉好代码。健全性则可以在特定的、重要的情况下保证即可。比如他们证明了在语句边界这个时刻也就是AI刚好写完一条完整的语句、准备开始下一条的时候密封器是完全精确的它接受就代表能继续它拒绝就代表真的有问题。四、从理论到实践先在小型语言上打磨再攻克真实Rust为了确保这套方法的理论基础坚如磐石研究团队没有直接上来就对着真实的Rust动刀而是先在一个叫做羽毛量级RustFeatherweight Rust简称FR的迷你版语言上进行了完整的数学证明。FR就像是Rust的精简玩具版——它保留了Rust最核心的特性变量的移动语义用过一次就没了就像把一个苹果递给别人自己手里就没了、借用机制暂时把东西借给别人用用完还回来、共享借用和独占借用的互斥规则要么很多人同时读要么只有一个人写不能同时读写、以及词法生命周期借出去的东西的有效期跟代码块的范围绑定。虽然是玩具版但这些特性已经足够验证密封器的核心思路是否正确。研究团队不仅设计了FR的密封器命名为SFR还用Lean这个定理证明工具把所有证明全部机械化地检验了一遍。所谓机械化证明就是把数学推导翻译成计算机能检查的代码让计算机来验证每一步逻辑是否正确完全排除人为失误。在这个过程中研究团队还意外发现了原始FR论文中的几处错误——包括类型系统中对代码块规则、变量声明规则、赋值规则的细节缺失——并在自己的机械化版本中进行了修正。在FR上打稳基础之后研究团队把同样的方法论移植到了真实的Rust语言上构建了名为SRS的Rust密封器。真实Rust比FR复杂得多需要处理的问题涉及方方面面代码块和语句的密封规则用holediv()强制分支收敛用holeval()填充值位置、条件语句if/else中缺失的分支用holediv()代替使整个表达式类型合法、循环语句循环体用holediv()结尾避免编译器对循环体的跨迭代一致性检查、函数调用先查询函数的参数个数再用holeval()补全缺失的参数、字段访问对部分写完的字段名先保留接收者用引用形式防止意外移动等等。真实Rust还有一类特殊的挑战某些错误只能在代码写完之后才能真正判断。比如一段代码可能引用了一个还没写到的函数或者某个类型现在还不明确、要等后续代码推断出来。对于这类未来依赖型错误密封器会暂时压制它们等代码全部生成完毕后再彻底放行确保不会因为后半段还没写而误杀那些本来合法的前半段。五、七大模型、两类任务实验结果说话研究团队对生成的这套生成式编译系统进行了大规模实验评估横跨七个当前最强的编程AI模型三个商业黑盒模型Claude Opus 4.8、GPT 5.3 Codex、Gemini 3.5 Flash和四个开源模型Kimi K2.7 Code、GLM 5.2、Qwen 3.5 397B参数版、Qwen 3.5 9B参数版。实验选择了两类极具挑战性的任务。第一类叫做Translation也就是C语言转Rust给AI一份C语言写的库让它翻译成对应的Rust代码。这个任务之所以难是因为C语言的内存管理方式和Rust截然不同翻译时需要对数据结构的所有权进行大量的重新思考和设计。第二类叫做UpdatedAPI给AI一个使用了某个Rust第三方库的代码框架但这个库的API已经在AI训练结束之后更新了AI需要根据编译器反馈的错误信息自己推断出新API的用法并修复代码。实验对比了三种方案。纯LLM方案是直接让AI生成代码不做任何编译检查。PC方案Post Compilation事后编译是等代码全部生成完再检查出错就反馈给AI重新生成最多允许若干次循环。GC方案Generative Compilation生成式编译则是在生成过程中实时检查一旦发现无法继续修复的错误就立刻反馈给AI重新开始这次生成同时还保留了最后几轮事后编译反馈作为兜底。结果相当显著。在没有任何编译反馈的情况下AI生成的代码中有高达65.9%无法通过编译最极端的情况Qwen 9B在Translation任务上达到了85.5%的失败率。引入事后编译反馈后失败率降到了20.7%说明编译反馈本身确实很有用。而加入生成式编译之后失败率进一步降到13.1%。在全部14个模型×任务组合中生成式编译在编译错误率上有13个比事后编译更好或持平其中9个差异在统计上显著。功能正确性方面也有明显提升。生成式编译在14个组合中的11个取得了最高的功能正确率。最亮眼的成绩包括GLM 5.2在UpdatedAPI任务上从53.3%提升到71.7%Kimi K2.7在Translation任务上从39.9%提升到53.9%。出乎意料的是生成式编译不仅没有让整体耗时增加反而降低了平均耗时。相比纯LLM事后编译平均增加了233秒的额外耗时而生成式编译只增加了135秒。原因在于生成式编译会在发现无法修复的错误时立刻叫停当前这次生成避免AI把一个错误的文件写到底——写到底再检查不仅浪费了生成这段代码的时间还要再花时间理解错误、重新生成。对于Qwen 9B生成式编译直接将Translation任务的平均耗时从879秒砍到了357秒节省了一半多。六、深入解剖生成式编译到底做了什么实验结果之外研究团队还对生成式编译的工作机制进行了细致分析揭示了它为什么能取得这样的效果。首先是错误雪球的遏制。在使用生成式编译的所有任务中85.3%的任务在生成阶段最多10次重启就完全解决了问题从未需要动用事后编译这个兜底手段。其中55.4%的任务在生成阶段就直接拿到了正确答案。这说明大多数情况下早发现、早纠正代价远低于等到最后再处理。其次是错误报告的瘦身效果。当一个完整文件被提交给编译器检查时一个核心错误可能引发一连串的连锁报错最终报错列表里几十条信息全部堆在一起。研究团队统计发现事后编译产生的错误报告平均包含13.8条具体报错信息在Translation任务中有时甚至达到几百条。而生成式编译在代码写到一半就发现了根源错误此时产生的报告平均只有5.5条信息其中65%的报告只含1到2条。报告越精简AI就越容易找到真正的问题所在修复的效率就越高。最关键的分析是错误检测时机。研究团队对961个AI生成的错误文件做了仔细的复盘他们先记录Rust编译器在完整文件上报告的第一个错误出现在哪一行然后把同样的文件逐段喂给生成式编译记录生成式编译是在哪一行最先发出警报。结果显示在中位数情况下生成式编译发出警报的时间只比最理想情况假设存在一个神奇的全知裁判能在错误刚发生时就立刻察觉晚了3行。四分之一的情况下生成式编译甚至能在错误刚发生时就准确发出警报一行都不差。相比之下另一个对照方案GCfn只在完整函数写完后才检查平均比最理想情况晚14行而事后编译自然只能等到整个文件写完才给反馈平均晚了89行。更重要的是生成式编译平均在文件完成33.3%的时候就发现了无法继续的错误而这个理论下限是32.7%——两者几乎一致。换句话说生成式编译避免了AI在明知无望的错误路径上浪费剩余66.7%的代码生成。在被检测出的错误类型上类型不匹配错误E0308是最常见的占所有报告的三分之一以上。此外生成式编译还能捕捉到更复杂的借用检查错误包括冲突借用E0502也就是同时存在读借用和写借用的情况、从借用值中移出E0507试图永久拿走一个只是临时借用的东西等Rust特有的复杂错误。七、系统的实际工程细节研究团队把整套系统做成了实际可用的工程实现。密封器本身用Rust语言编写代码量约5000行与Rust编译器前端的约60万行相比实现成本低得多。密封器基于rust-analyzerRust语言的官方语言分析工具来解析半截代码的语法结构然后按照密封规则生成密封后的完整代码最后交给rustcRust的正式编译器检查。与AI交互的那一层用Python编写约3000行代码。它负责从AI的流式输出中实时接收代码片段触发密封器和编译器并按照论文中描述的并发逻辑运行AI继续生成代码的同时编译器在后台检查上一个快照如果发现问题就立刻发出信号让AI停下来并给出错误信息。由于密封后的代码和原始代码不完全一样多了占位符少了后半段编译器报告的错误位置也是针对密封后代码的。为了让AI看到的错误信息对应原始代码系统在密封过程中会维护一个位置映射表把密封代码中的位置反向映射回原始代码中的位置确保AI收到的反馈是针对它自己写的内容的而不是针对系统自动补充的占位符。整个系统有329个测试用例覆盖密封器和推理行为并且包含了7个不同AI的接口适配层以及用于评估的基准测试管理代码合计约8000行Python代码。---归根结底这项研究解决的是一个反馈来得太晚的根本问题。AI写代码就像在黑暗中画画——它不断往前走却迟迟得不到反馈于是一个小偏差最终变成了一幅面目全非的图。生成式编译做的事相当于在这条走廊里每隔几步就打开一盏灯让AI知道自己有没有走偏而不是等走到头才发现自己一直走在错误的路上。这个思路不只对Rust有意义。任何有严格静态规则的语言只要能为密封器定义合适的占位符和密封规则都可以复用这套框架。研究团队还指出未来可以探索自动化地从语言规范中生成密封规则而不是像现在这样手工编写——这将使整套方法能够随着语言的演进自动更新甚至在全新语言发布之初就能为AI提供即时的编译反馈支持。对于普通用户来说这项研究意味着未来当你用AI帮你写Rust代码时你可能会发现AI的生成质量变得更稳定、编译错误更少、需要你手动修正的次数更少。这不是因为AI变聪明了而是因为它终于有了一个实时陪跑、随时提醒的编译器伙伴。有兴趣深入了解技术细节的读者可以通过arXiv编号2607.13921查阅完整论文。---QAQ1生成式编译和事后编译反馈有什么本质区别A事后编译是等AI把整个代码文件写完再检查出了问题再反馈。生成式编译则是在AI写代码的过程中实时检查一旦发现不可挽回的错误就立刻告诉AI避免AI在错误的基础上继续写下去。实验显示生成式编译平均在文件完成33%时就发现了问题而事后编译要等到100%完成后才能发现节省了大量无效的代码生成。Q2密封器会不会产生误报误判本来合法的代码A研究团队对密封器设计了完备性这一核心保证只要一段半截代码存在任何合法的延续方式密封器就绝对不会拒绝它。这意味着密封器不会误杀好代码。在语句边界这个特殊时刻密封器甚至是完全精确的拒绝就代表真的有问题接受就代表确实能继续。整套证明已经用Lean定理证明工具完整机械化验证。Q3生成式编译方法能用于Rust以外的编程语言吗A可以。这套框架是语言无关的只需要为目标语言实现一个对应的密封器——定义在代码不完整时如何用占位符补全、如何避免引入假错误。研究团队已经为理论上的简化版Rust和真实Rust分别实现了密封器未来有望通过自动化方法从语言规范中生成密封规则从而将这套方法扩展到其他严格类型系统的编程语言。
郑州网站建设
网页设计
企业官网