LLM 代码虽准,为何越来越“烂”?
If coding is solved, what now?: Measuring the sloppiness of code
LLM 生成代码的能力已近乎完美,但这并不意味着问题的终结。代码形式正确,却可能充斥着不必要的抽象、重复和糟糕的决策。我来自物理学背景,习惯用实验和量化方法解决问题,但在研究如何衡量代码的“粗糙度”时,发现行业现状令人失望,大多仍依赖直觉。AI 作为裁判往往失效,而人工审查又难以规模化。通过引入 Verbosity 和 Erosion 等指标,我发现 AI 生成的代码在冗余度和复杂度侵蚀上,平均是人类代码的两倍。更严峻的是,在模拟真实迭代场景的 SlopCodeBench 测试中,即便是最先进的模型,其累积错误也导致严格通过率归零。这警示我们,盲目堆砌代码行数的时代,人类直觉与品味依然不可或缺。
仅仅因为代码在形式上是正确的,并不意味着它没有引入不必要的抽象、制造重复,或者在整体上做出了糟糕的决策。
HN 评论区
215- dang
各位:请不要对标题做出泛泛的、条件反射式的反应。这在 https://news.ycombinator.com/newsguidelines.html 等指南中已有明确规定:
“请不要抓住文章或帖子中最具煽动性的部分在评论区抱怨。相反,请找出有趣的内容进行回应。”
我已经把上面标题中的煽动性部分去掉了,但请大家记住,HN 的讨论区需要的是经过深思熟虑的评论,而不是条件反射式的反应。
https://hn.algolia.com/?dateRange=all&page=0&prefix=true&sor....
- dherman
很高兴看到大家开始探索定量方法,以便为智能体(agents)提供关于代码质量的反馈。这篇文章看起来是个不错的开端!
我对作者的主要反馈是:导致代码粗糙(sloppiness)的最重要问题通常是全局属性,而非局部属性。根据我的经验,智能体和人类一样,注意力是有限的;但如果它遇到了阻碍其运行的局部粗糙问题,它可以按需修复。真正重要的技术债务问题通常是那些不容易修复的全局性问题:它们需要全局分析和全局重构。
我不知道答案是什么,但我认为我们需要找到方法来衡量架构属性,比如关注点分离、清晰的架构分层、定义良好的接口等等。
- toddwprice
或许,只要在前端模型上无限制地消耗 token,编程问题就已经解决了。但这是否永远都昂贵到无法承受,还有待观察。在我所在的公司,我们在形势大好时把 token 用到了上限。但当我们不得不切换到 Anthropic 的企业版计划,并开始按 token 付费时,事情真的闹大了(shit really hit the fan)。现在我们正退回到合理的成本水平,结果发现——猜猜怎么着?——人力可能反而更具成本效益。AI 当然是一个巨大的工具,但目前用它来构建循环并让其自动运行仍然太贵了。当然,随着时间推移这会改变,但假设这个问题已经解决纯属胡扯。也许如果我们解决了冷聚变,那倒有可能。在那之前,进化仍在熵增的战争中获胜。
- conqrr
编程不仅仅是内存中运行的程序,它还包括在团队中分发和理解心智模型(mental model)的过程。
如果人类越来越多地被排除在编程之外,那么谁来持有这个心智模型?
如果由 AI 持有心智模型,那么根据定义,人类的提示词(prompts)将经过一个高损耗的通道。即便没有 AI,这也是事实。软件质量直接取决于优秀的开发者,他们能将业务/产品经理的术语转化为技术决策。
所以,编程现在解决了吗?其实几十年前就已经解决了。
- justinmarsan
得出了与作者相同的结论后,我创建了我的第一个智能体来进行架构审查,这也是我了解到多年来我一直遵循的良好实践背后指标的方式,比如 LCOM、圈复杂度等等……
发布大量代码太容易了,应该投入更多精力确保代码正确性,建立包含开发者的自我改进反馈循环,并配备专用工具……
不过,之前一切都围绕提示工程(prompt engineering),而现在你可以模糊地表达想法并获得一个大致可用的结果,所以这一点可能也会迅速演变……
- mikkelam
这再次回到了 RLHF 循环的问题。
AI 实验室过去和现在都 100% 专注于正确性,因为这很容易设置和验证。
添加一个几乎与另一个功能相同的新函数,通常不会破坏任何东西。
我认为这只是时间问题。到了某个节点,从正确性中榨取的价值将所剩无几,届时 AI 实验室就会开始关注可维护性。不过,要搭建环境来训练这种行为,可能难得多。
- pbjerkeseth
我满怀希望地跳进这个话题,期待它能落脚于此!我最近在 ouijit[1] 的代码库“分析”视图中集成了关于圈复杂度、变更率(churn)和作者身份的基本观察。
有些好处可以立即获得(如圈复杂度),但其他好处需要时间才能显现(如变更率)。一个很好的例子是:假设有一个 500 行的文件,经历了 2500 行的变更,如果这个变更率呈下降或上升趋势,这非常有用。这对于理解你遇到了一个热点,有机会通过花更多时间设计 API,或者将正在经历剧烈变动的代码子集拆分出来,从而偿还债务,非常有帮助。
关于复杂性的有趣之处在于,假设你做得好 lint 和格式化,你可以通过查看每行平均缩进、最深缩进行等,做一个“穷人版”的检查。
[1]: https://ouijit.com
- FiberBundle
有人真的知道 LLM 在处理代码库时是否存在复杂度上限吗?很明显,它们写出的代码并不适合人类理解(而且随着更多 RL 用于训练这些模型,情况只会越来越糟),但如果 LLM 本身不会因为引入的复杂度而遇到瓶颈,那么对于很大一部分非安全关键软件来说,这似乎就不重要了。我真心希望存在这样的上限,因为我觉得引导它们是我仍能提供价值的最后几种能力之一,但真的有证据表明这些模型在处理维护不善的代码时会更加吃力吗?