如果编程问题解决了,现在该怎么办?:度量代码的粗糙性
摘要
本文探讨了大型语言模型如何生成正确的代码,但常常引入不必要的抽象等粗糙性,并讨论了衡量代码质量的方法,包括使用AI评判和人类评估。
暂无内容
查看缓存全文
缓存时间: 2026/09/11 14:22
# 如果编程已被解决,现在该怎么办?衡量代码的冗余度 | EARENDIL
来源:https://earendil.com/posts/measuring-code-sloppiness/
大语言模型在生成代码方面已近乎完美,但这并非故事的终点。仅仅因为代码在形式上正确,并不意味着它没有引入不必要的抽象、创建重复内容,或者在整体上做出糟糕的决策。这并非什么开创性的观察,大多数进行过临时编码项目的人都意识到,每增加一个新功能有时会导致代码行数的爆炸式增长。
这导致了人类主导权的丧失,因为在每月新增数百万行代码的项目中,人类很难跟上进度。有些人可能会说这根本不是问题,因为他们信任自己的智能体来处理它。但我得告诉你一个坏消息:智能体也无法真正处理这些冗余代码。
我有物理学背景,因此一直以实验/定量的方法解决问题。当我在 Earendil 开始着手思考如何衡量代码冗余度时,我的自然反应是先深入研究文献,然后看看其他公司在做什么。
坦率地说,除了少数几篇富有洞见的论文外,我对行业目前似乎如此“基于感觉”的现状感到失望。在我的研究和在 X 上,我不断收到诸如“端到端编码智能体”、“不仅能建议代码——还能交付代码的 AI”或“无需人类水平成本的人类水平评估”之类的信息。就像所有好故事一样,这些说法都有一丝真实之处。
大语言模型能够写出**几乎**完全正确的代码。这是由于代码的可扩展性和可验证性。让大语言模型生成代码,然后通过隐藏测试来检查代码是相当直接的,这会产生清晰的奖励信号。与此形成鲜明对比的是,检查这些代码的“冗余度”通常需要人类的直觉和品味,这通常是一项极其困难的任务。我认为说明原因的最佳方式是通过探讨可能的衡量冗余度的方法。
**AI 作为评判者:** 这可能是行业中评估代码质量最常见的方式,据我观察,它很少奏效。最简单的方法,即要求模型在1-10分的范围内评估代码质量,基本上等同于一个随机数生成器。更复杂的方法,即尝试给评判模型两个解决方案 A 和 B,然后让它决定更倾向于哪个解决方案,其缺点在于当你重命名解决方案时,模型会改变其偏好。我在这里有点戏谑,这种效应在较大的模型中并不那么明显,但主要观点仍然成立。要求大语言模型评判它们自己编写的代码,不能替代适当的评估。尽管有一些使用评分标准或让大语言模型编写测试的有趣方法,但它们离真正消除冗余代码还相去甚远。
**人类评判 AI:** 如果我们忽略软件工程师质量存在巨大差异这一事实,这将是确保代码保持人类可读性的最佳解决方案。其缺点在于,这对于训练 AI 或为多个模型提供商和测试框架建立大型基准测试来说是不可扩展的。
**最简单的方法:** 在我的研究和测试中,简单地计算代码行数的变化,是一个衡量冗余度出奇有效的指标,具有讽刺意味的是,如果我们开始优化这个指标,它就会停止成为一个有意义的衡量标准。
接下来的两个衡量标准是由论文 SlopCodeBench 介绍给我的,看起来很有前景,因为它们能够很好地将遗留代码库与大语言模型生成的冗余代码区分开来。
**冗长度 (Verbosity):** 试图衡量重复和不必要的冗长代码行的数量。
$$ \mathrm{Verbosity} = \frac{\| \text{AST-Grep 标记行} \cup \text{克隆行} \|}{\mathrm{LOC}} $$
**侵蚀度 (Erosion):** 试图衡量代码库的质量有多少集中在少数几个大型且复杂的函数上。
$$ \mathrm{mass}(f) = CC(f) \sqrt{\mathrm{SLOC}(f)} $$
这里 f 是函数,SLOC 是源代码行数,CC(f) 是函数的圈复杂度。
$$ \mathrm{Erosion} = \frac{\sum_{f:\,CC(f) > 10} \mathrm{mass}(f)}{\sum_f \mathrm{mass}(f)} $$
侵蚀度则简单地是圈复杂度大于10的函数质量占所有函数质量的比例。
如果我们查看 SlopCodeBench 评估期间生成的代码的平均冗长度和侵蚀度,并将其与一组成熟的代码库进行比较,会发现它们之间存在显著差异。代码库的平均冗长度为 0.15 ± 0.06,而智能体代码的冗长度为 0.33 ± 0.10。对于侵蚀度,代码库为 0.31 ± 0.17,而智能体为 0.68 ± 0.20。平均而言,智能体的代码冗长度和侵蚀度大约是人类代码的两倍。然后我调查了自己的一些临时编码项目,其中很多项目的冗长度高达 0.4,侵蚀度高达 0.75,所以这些结果可能不仅仅是评估的产物。
回到智能体本身(真正)无法处理冗余代码的观点,我们需要看看 SlopCodeBench 的评估方法。与其他编码基准测试不同(后者在开始时给智能体一份完整的指令清单,然后通过一组隐藏测试来判断程序是否通过),他们采取了相反的方式。他们创建了多轮指令和测试迭代,在检查点之间会清除模型的上下文。这从而更接近地模拟了一个迭代过程,就像人类实际使用编码智能体的方式一样。其结果是,糟糕的编码决策会随时间累积,而对于严格解决率(必须在所有检查点通过所有测试),即使是最先进的模型也只能达到 0% 的通过率。这应该给那些每天愉快地增加数万甚至数十万行代码行数的人敲响警钟。显然,通常有关于测试过于严格或某个问题陈述略显模糊的注意事项,但总体趋势是成立的。
通过探索这些指标,我希望你现在对为什么评估代码冗余度具有挑战性,以及为什么人类的直觉和品味仍然是(无论隐含还是明确地)评估过程的一部分,有了更清晰的认识。
还有一些有希望的其他方向我想探索,例如函数的耦合度、代码变更率、内聚性等。如果你正在从事评估工作并想交流,我很乐意:[[email protected]](mailto:[email protected])
相似文章
如何避免AI代码质量下降
本期通讯文章讨论了AI生成代码速度超过人工代码审查速度所导致的“AI代码质量下降”问题,并提供了平衡速度与质量的策略。
像人类会维护它一样编写代码
文章警告说,依赖LLM编写代码而不保持良好模式,会教会AI不良习惯,导致代码库充满重复逻辑,代码质量不断恶化。
审查AI代码并非一个站得住脚的论点(2025)
文章认为,要求全面审查代码会抵消LLM编码助手所谓的生产力提升,因为实证研究显示它们并不能帮助写出更好或更快的代码,而且支持者未能解决固有的错误率问题。
@dzhng: https://x.com/dzhng/status/2090252351533973768
这篇文章讨论了因人工审查瓶颈而产生的AI生成代码‘垃圾’问题,并指出软件工程必须演进,以系统设计为重点,而不是代码的可读性。
编码模型做得太多了
一篇博客文章探讨“过度编辑”问题:编码大语言模型在修复简单错误时改写了过多代码,提出衡量指标与训练方法以鼓励最小化、忠实于原意的编辑。