像人类维护代码一样编写代码 —— AI 生成重复代码的风险
像人类维护代码一样编写代码 —— AI 生成重复代码的风险
TL;DR
在使用 LLM 生成代码时,如果不强制执行 DRY 或其他最佳实践模式,就会产生重复的条件判断,这些判断会成为代码库的新“风格”;随后模型会模仿这些模式,使未来的维护变得更加困难。通过添加显式的审查命令、提示词和静态分析,可以保持代码库的整洁。
作者阐述的问题
作者描述了一个工作流:反复要求 LLM 在不同地方(路由处理程序、后台任务、API 端点、webhook)添加相同的权限检查逻辑。每个生成的代码片段看起来都像这样:
if (user.isActive && user.hasPermission('read') &&
!user.isSuspended && account.status === 'open') {
// do a thing
}
作者没有提取共享的辅助函数,而是将每个副本原封不动地合并,因为代码可以运行且测试通过。这种短期便利掩盖了长期风险:每一个针对类似端点的后续请求都会收到另一份相同的条件判断副本,从而强化了重复的模式。当稍后要求进行重构时,LLM 只会保留所有五个副本,因为这就是代码库现在的样子。
关键结论: 每一个合并到代码库中的捷径都会成为模型学习重复的信号,将一次性的代码异味(smell)变成一种普遍的风格。
为什么 LLM 会放大坏模式
- 上下文驱动生成 – LLM 会读取你打开的文件和最近的提交。它们将现有代码视为未来建议的模板。
- 模式强化 – 存在的重复代码片段越多,模型重现它们的偏差就越强。
- 缺乏内在的可维护性概念 – 模型针对提示词优化的是“能运行的代码”,而不是长期的可读性或抽象化。
"LLMs are sponges that soak up everything you do and repeat it back to you. So make sure it's good." – Original post
社区建议的缓解措施
1. 添加带有检查清单的审查命令
- 创建一个 markdown 文件(例如
.claude/commands/review.md)。 - 列出具体的检查项,例如“确保新代码不会重复现有逻辑”。
- 在合并之前调用该命令 (
/review);智能体(agent)将生成一个计划并标记违规项。
"Agents don’t care that they just got a wall of generic feedback, they happily look into all the bullet points. I added ‘ensure the new things aren’t duplicating code that already exists elsewhere’ and it gave me such a surprise – it really truly started planning cleanups!" – cadamsdotcom
2. 提示词进行最终代码质量检查
在进行较大改动后,要求模型验证:
- 关注点分离 (Separation of concerns)
- 是否残留实验性代码
- 与文档的一致性
"Now do a final code check. Is everything tidy and do the components adhere to the principle of separations‑of‑concern?" – planb
3. 使用静态分析作为基准
将 linter 或代码异味检测器(例如 Credo, Rubocop, ESLint)集成到 CI 流水线中。随后可以要求 LLM 修复报告的具体问题,从而提供一个确定性的安全网。
"Better yet, add tooling like static code analyzers … Verify against a mechanical baseline, with LLM judgement layered on top as‑needed." – chickensong
4. 定期运行基于模型的异味检测
一些开发者通过定期运行一个单独的 LLM(或专门的异味检测模型)来发现重复模式。
"I continually run codebases through different models to have them look for bad code smells like repeated code. That’s been pretty effective." – carimura
对立观点与细微差别
LLM 可以提高可维护性 – 有一位评论者指出,AI 已经促使他们的代码向更好的关注点分离和可测试性方向发展。
"AI has made my code more human‑maintainable. They’ve been complaining about obsolete comments, separation of concerns, testability…" – andai
并非所有重复都是坏的 – 在项目初期,过早的抽象化可能会有害。在模式稳定之前,重复可能是可以接受的。
"When you start a project not everything is DRY, and you don’t start pulling out shared helpers until they’re called for." – chickensong
LLM 可能忽略现有抽象 – 一些用户观察到,即使存在清晰的抽象,模型也经常从头开始重新实现逻辑。
"The frontier LLM does neither, it just steams ahead re‑implementing things from scratch…" – davnicwil
人类的纪律性仍然至关重要 – 依赖一个工程师团队来一致地应用审查提示词是过于乐观的;许多人担心集体的纪律性可能会被化解。
"The idea that an LLM‑fueled group will collectively have this discipline is… bemusing and sadding." – MattyRad
AI 辅助开发的实践检查清单
- 定义审查检查清单(重复检测、DRY、命名规范)。将其存储在智能体可以读取的地方。
- 在每次合并前运行
/review;将输出结果视为强制性的代码审查项。 - 添加静态分析步骤到 CI;在出现新异味时终止构建。
- 定期安排 LLM 异味扫描以捕捉漂移。
- 在添加类似逻辑时显式提示进行抽象:
- "Create a shared helper
hasReadAccess(user, account)and use it in all new endpoints."
- "Create a shared helper
- 在代码注释中记录意图,以便模型能看到逻辑背后的原理,而不仅仅是实现方式。
结论
LLM 擅长快速生成可运行的代码,但如果没有严谨的检查,它们会固化重复且难以维护的模式。通过将模型视为需要明确指导的队友——通过审查命令、提示词、质量检查、和静态分析——你可以保持代码库的整洁,并防止 AI 学习坏习惯。