衡量代码随意性:指标、发现与社区洞察

TL;DR

LLM 生成的代码虽然在形式上正确,但明显比人类编写的代码更随意;简单的指标如 LOC 变化、冗余度和侵蚀度表明,代理生成的代码冗余度和侵蚀度约为成熟代码库的两倍,而现有的评估方法无法捕捉这种退化。


为什么衡量随意性很重要

通过隐藏测试的代码仍可能包含不必要的抽象、重复的逻辑和糟糕的架构决策。在每月新增数百万行代码(LOC)的大规模项目中,这种“随意性”会侵蚀开发者的自主性,因为开发者无法跟上隐藏的技术债务。作者认为,代理无法自主解决随意性问题,因此量化评估至关重要。


天真的评估方法失败

AI 作为裁判并不可靠

  • 要求 LLM 在 1–10 分制上评估自己生成的代码,其行为如同随机数生成器。
  • 成对比较(“A 对 B”)不稳定:重命名解决方案可能导致模型偏好反转,如 arXiv:2604.16790 所示。
  • 即使是复杂的评分标准或 LLM 生成的测试,也无法完全消除随意性。

"让 LLM 评判自己写的代码,并不能替代真正的评估。" – 作者

人工介入不可扩展

  • 人工审查能保证可读性,但无法扩展到训练或基准测试所需的规模。
  • 审查数百万行 LOC 的成本超过了持续排名模型提供商所带来的收益。

简单指标:LOC 变化

在代码修改后统计 LOC 的净变化,被证明在识别随意性方面出人意料地有效。然而,作者警告称,一旦优化此指标,就会触发古德哈特定律——一旦一个指标成为目标,它就不再是一个好的衡量标准。


基于研究的指标:SlopCodeBench

论文 SlopCodeBench(arXiv:2603.24755v1)引入了两个指标,用于区分遗留代码库与 LLM 生成的随意代码。

冗余度

衡量重复或不必要的冗长代码行数:

$$ \text{冗余度} = \frac{|\text{AST‑Grep 标记的行} \cup \text{克隆行}|}{\text{LOC}} $$ 通过 AST‑Grep 中的手工启发式方法实现。

侵蚀度

量化代码质量集中在少数大型复杂函数中的程度:

$$ \text{mass}(f) = \text{CC}(f) \sqrt{\text{SLOC}(f)} $$ $$ \text{侵蚀度} = \frac{\sum_{f:,\text{CC}(f)>10}\text{mass}(f)}{\sum_{f}\text{mass}(f)} $$ CC(f) 为圈复杂度;SLOC(f) 为源代码行数。


实证发现

数据集 冗余度(均值 ± 标准差) 侵蚀度(均值 ± 标准差)
成熟的人类代码库 0.15 ± 0.06 0.31 ± 0.17
代理生成的代码(SlopCodeBench) 0.33 ± 0.10 0.68 ± 0.20

代理生成的代码冗余度和侵蚀度约为人类代码的两倍。

作者对自己“直觉编码”的项目进行额外的定性检查,发现冗余度高达 0.4,侵蚀度高达 0.75,确认该现象不仅限于基准测试。


为什么代理无法自我纠正随意性

  • SlopCodeBench 在迭代设置中评估代理:每次指令-测试循环后,模型的上下文被清除,模拟了代码在多步演化中的真实使用场景。
  • 错误决策不断累积,导致最先进模型的严格求解率仅为 0%——即没有任何模型在每个检查点都通过所有隐藏测试。
  • 这一严重失败警示我们,仅靠 AI 驱动的无限制 LOC 增长是危险的。

社区反应与扩展

"衡量随意性的最重要问题在于全局属性,而非局部属性。需要像关注关注分离这样的架构度量。" – dherman

"优化最小 LOC 可能反而加剧代码高尔夫化,产生难以维护的一行代码。" – cjalmeida

"像圈复杂度、变更率和作者归属这样的指标已在内部仪表板中使用;结合它们可以更全面地描绘随意性。" – pbjerkeseth

"古德哈特定律被引用却未加讨论;我们需要检验最小化 LOC 是否真的导致更随意的代码。" – drsopp

"当前讨论中缺少全局架构度量(如耦合度、内聚度),对于大型代码库而言,这些可能是必不可少的。" – dherman

"即使使用代理,人类设计工作仍然必不可少;否则代码库会变成杂乱无章的临时功能拼凑。" – cheney_2004

这些评论突出了三个反复出现的主题:

  1. 需要全局架构度量(耦合度、内聚度、分层)。
  2. 指标操纵风险(古德哈特定律)以及多指标组合的重要性。
  3. 人工监督依然至关重要,尤其是在设计和可维护性方面。

开放研究方向

作者列出了未来研究的有前景方向:

  • 函数耦合度 – 衡量函数之间依赖的紧密程度。
  • 代码变更率 – 跟踪快速增删作为不稳定的代理指标。
  • 内聚度 – 评估模块职责是否集中。
  • 反馈循环 – 将冗余度/侵蚀度评分反馈至 LLM 训练中,引导生成更清晰的代码(同时监控古德哈特效应)。

实践者的实用建议

  1. 跟踪 LOC 变化 作为快速的合理性检查,但应视为启发式方法,而非硬性目标。
  2. 使用 AST‑Grep 或类似静态分析流水线 实现冗余度和侵蚀度,以标记重复或过度复杂的代码。
  3. 结合多种指标(复杂度、变更率、耦合度)以降低单一指标被操纵的风险。
  4. 保持人工审查周期 用于架构决策;自动化指标可揭示问题,但无法替代设计判断。
  5. 设计模仿迭代开发的基准(如 SlopCodeBench 所做),以暴露在多次精炼步骤后才显现的随意性。

结论

LOC 变化、冗余度和侵蚀度等量化指标为代码随意性提供了清晰的视角,揭示当前 LLM 代理生成的代码在冗余度和侵蚀度上约为人类代码的两倍。尽管这些指标有价值,但必须作为更广泛、多维度评估策略的一部分,包含全局架构属性和人工监督,以避免古德哈特定律,并确保软件的可维护性。

Sources

相关