关于 code-slop
面向开发者和编码 Agent 的代码审查技能,用于检查 PHP/Laravel 与 TypeScript/React 项目中与 AI 生成代码相关的定性问题,重点关注常规指标难以体现的可读性。
主要功能
- 01涵盖六类的 24 项检查
- 02审查注释与命名
- 03检查过度设计模式
- 04审查防御性代码
- 05检查测试质量
- 06识别 AI 风格特征
适用场景
- 01审查 AI 辅助编写的拉取请求
- 02审计含 AI 贡献的代码库
- 03入职时评估代码可读性
- 04快速原型开发后检查代码
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ asyrafhussin/ agent-skills --skill code-slop安装后在 Claude Code 中输入/code-slop确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
AGENTS.mdmetadata.jsonREADME.mdrules/_sections.md_template.mdcomments-closing-brace-labels.mdcomments-empty-docblocks.mdcomments-narration.mdcomments-placeholder.mddefensive-generic-catch.mddefensive-impossible-null.mddefensive-missing-real.mdnaming-generic-placeholders.mdnaming-over-descriptive.mdnaming-suffix-abuse.mdnaming-type-in-name.mdover-eng-dependency-creep.mdover-eng-premature-interface.mdover-eng-single-method-class.mdover-eng-useless-wrapper.mdstyle-as-any-escape.mdstyle-debug-artifacts.mdstyle-hyper-consistent.mdstyle-no-hack-scars.mdstyle-trivial-boilerplate.mdtest-doesnt-throw.mdtest-mirror-implementation.mdtest-mock-everything.mdtest-snapshot-abuse.md详细介绍
代码臃肿检测
从品味层面审查代码中的 AI 生成模式。包含 6 个类别、24 条规则,涵盖注释、命名、过度工程化、防御过度、测试臃肿和风格特征。[technical-debt](../technical-debt) 衡量的是代码债务的量化指标(复杂度、重复代码、CVE),而本技能衡量的是定性失误:代码虽然通过所有指标,却读起来像教程博客文章,不像人写的。
元数据
- 版本: 1.0.0
- 范围: PHP / Laravel + TypeScript / React(Node)
- 规则数量: 6 个类别,共 24 条规则
- 许可证: MIT
本技能的存在意义
关于 AI 辅助编程的行业数据(GitClear 2025、cURL 漏洞赏金计划于 2025 年关闭、arXiv 2510.03029):
- 重构比例从 25% 降至 <10%
- 复制粘贴比例从 8.3% 升至 12.3%;代码重复率约增长 8 倍
- 代码异味率比人工基线高出 42–85%
- 82% 的 AI PR 使用无法区分错误类型的通用 catch 块
- 76% 的 AI PR 未在外部调用中设置超时
这些问题都不会导致常见的 CI lint 检查失败,只会让代码库逐渐变得难以维护。本技能提供了一种视角,帮助你在代码发布前发现这些问题。
核心洞察:现在,阅读成本 > 编写成本。编写代码的成本大幅降低了,阅读成本却没有。即使代码能运行,如果无法快速理解,也属于臃肿代码。
如何审查
当用户要求“审查 AI 臃肿代码”“审计代码质量品味”或“查找 AI 模式”时,请将本技能的规则作为检查清单,对照变更文件(PR 差异)或整个代码库逐项审查。
审计步骤 1:确定范围
- 如果提供了 PR 差异:仅审查差异中变更的文件
- 如果指定了文件:审查这些文件
- 如果未指定范围:审查整个代码库,优先检查最近有改动的文件(最有可能是 AI 生成的)
审计步骤 2:检测技术栈
| 信号 | 技术栈 |
|---|---|
composer.json + artisan | PHP / Laravel |
package.json(含 TypeScript/React 依赖) | Node / TypeScript / React |
| 两者都存在 | Laravel + Inertia + React |
审计步骤 3:运行臃肿代码检查清单
对以下每一项,输出:
- CLEAN — 未发现该模式(简要确认)
- SUSPICIOUS — 少量出现;标记并讨论
- INFLATED — 大量出现;冗长但可用;建议修复
- CRITICAL — 存在大量 AI 风格特征;合并前需要全面审查
注释
- 没有只是在叙述代码的注释(在
User::create(...)上方写着// create user) - 没有空洞的文档块(在
getUser()上方写着/** Get user */) - 没有遗留占位注释(
// TODO: implement、// your code here、// implementation) - 没有闭括号标签(
} // end function、} // end if block)
命名
- 没有通用占位名称(
data、result、info、temp、helper) - 没有过度描述、冗长的名称(
theUserWhoIsCurrentlyLoggedIn) - 没有滥用后缀(无正当理由地过度使用
*Helper/*Manager/*Util/*Wrapper) - 没有将类型写入名称的模式(
userObject、resultArray、stringData)
过度工程化
- 没有恰好只有一个实现、且没有第二个实现计划的接口
- 没有应该作为顶层函数的单方法类
- 没有只调用一次、只负责委托的包装函数
- 没有在现有依赖已能完成同样工作的情况下新增依赖
防御过度
- 没有在不可能抛出异常的代码周围使用通用的
catch (e) { console.error(...) }块 - 没有对不可能为 null 的值进行 null 检查(例如已使用非 null 断言或由类型保证的值)
- 确实处理了真实的防御需求(外部调用的超时、速率限制)
测试水分
- 没有将每个依赖都模拟掉、却没有真实行为断言的测试
- 没有只调用函数并检查是否抛出异常的“不抛出异常”测试
- 没有照搬实现逻辑的测试(重新编码,而非验证)
- 没有用快照测试代替行为断言
风格特征
- 存在一些格式上的不一致(没有哪个代码库的每个文件看起来都经过最激进的代码检查工具处理)
- 没有在难以推断类型的地方随意散布
as any/@ts-ignore/@ts-expect-error - 仓库中某处有一些
// HACK:/// XXX:/ 凌晨 2 点写下的注释——毫无瑕疵的代码库值得怀疑 - 生产代码中没有遗留调试内容(
console.log、var_dump、dd()、dump()) - 没有
if (x) return true; else return false/ 对明显字面量重复标注类型的情况
审计步骤 4:创建水分清单
以一张判定表结束审计:
## Code Slop Ledger
| File | Verdict | Top findings | Suggested action |
|------|---------|--------------|------------------|
| app/Services/UserExportService.php | INFLATED | 12 narration comments; 3 closing-brace labels; `*Helper` overuse | Strip comments; rename Helper → split into functions |
| resources/js/Pages/Orders/Show.tsx | CRITICAL | 4 `as any`; mock-everything tests; useless wrapper; impossible null checks | Rewrite section; remove tests; revisit type model |
| app/Models/Order.php | CLEAN | — | — |
## Summary
- CLEAN: X files
- SUSPICIOUS: Y files
- INFLATED: Z files (top priority: …)
- CRITICAL: N files (rewrite before merge)
适用场景
在以下情况参考此技能:
- 合并前审查 AI 辅助完成的 PR
- 审计接受了大量 AI 辅助贡献的仓库
- 熟悉某个代码库,并评估其是否读起来像是由人维护的
- 加强团队的代码审查清单,以防范 AI 水分
- “氛围编程”冲刺后,在宣布功能完成前进行检查
- 为 AI 输出质量设置 CI 门禁
步骤 1:检测项目技术栈
大多数规则在概念上与技术栈无关,但 PHP 和 TypeScript 的示例与检测命令有所不同。
| 信号 | 技术栈 | 工具 |
|---|---|---|
composer.json | PHP / Laravel | phpstan、phpcs、phpmd、手动 grep |
package.json | Node / TS / React | eslint、tsc --noEmit、knip、手动 grep |
按优先级划分的规则类别
| 优先级 | 类别 | 影响 | 前缀 |
|---|---|---|---|
| 1 | 注释 | 严重 | comments- |
| 2 | 命名 | 严重 | naming- |
| 3 | 过度设计 | 高 | over-eng- |
| 4 | 防御性代码过量 | 高 | defensive- |
| 5 | 测试水分 | 高 | test- |
| 6 | 风格特征 | 中 | style- |
快速参考
1. 注释(严重)
comments-narration— 只是复述下一行代码的注释comments-empty-docblocks— 在带类型的getUser()函数签名上方使用通用的/** Get the user */comments-placeholder—// TODO: implement、// your code here、// implementation、// helper functioncomments-closing-brace-labels—} // end function/} // end if block
2. 命名(严重)
naming-generic-placeholders—data、result、info、temp、helper、valuenaming-over-descriptive—theUserWhoIsCurrentlyLoggedIn、calculateTotalAmountFromItemsListnaming-suffix-abuse— 过度使用*Helper/*Manager/*Util/*Wrapper/*Processornaming-type-in-name—userObject、resultArray、stringData、listOfItems
3. 过度设计(高)
over-eng-premature-interface— 只有一个实现、且路线图上没有第二个实现的接口over-eng-single-method-class— 唯一用途是封装一个函数的类over-eng-useless-wrapper— 只在一个地方调用、且仅负责委托的封装器over-eng-dependency-creep— 现有依赖已经能胜任,却又引入新库
4. 防御性代码过量(高)
defensive-generic-catch— 到处都是try { ... } catch (e) { console.error("error") }defensive-impossible-null— 在非空断言或类型保证的值之后检查 nulldefensive-missing-real— 在不该防御的地方添加防御,却在真正重要的地方遗漏超时/速率限制
5. 测试水分(高)
test-mock-everything— 模拟每个依赖;测试重新编码了实现,而非验证行为test-doesnt-throw— 只调用函数并断言没有异常的测试test-mirror-implementation— 逻辑照搬被测生产代码的测试test-snapshot-abuse— 用快照测试取代行为断言
6. 风格指纹(中等)
style-hyper-consistent— 任何地方都没有格式漂移;每个文件看起来都像通过了完美的 lint 检查style-as-any-escape— 遇到难处理的类型时,便到处使用as any/@ts-ignore/@ts-expect-errorstyle-no-hack-scars— 代码库中完全没有// HACK:/// XXX:标记;没有“地质层”style-debug-artifacts— 在生产代码路径中遗留了console.log、var_dump、dd()、dump()style-trivial-boilerplate—if (x) return true; else return false;,以及对显而易见的字面量添加多余的 TS 类型注解
核心模式
“这能通过代码审查吗?”筛选
对于每段代码,问自己:
- 删掉三分之一的注释后,代码会不会更清晰? → 很可能是注释冗余
- 变量名能告诉我变量存的是什么,还是只告诉我它是什么类型? → 很可能是命名冗余
- 这个类能不能写成函数? → 很可能是过度设计
- 这个 catch 块真的处理了什么问题,还是只做了日志记录? → 很可能是防御过度
- 如果我破坏这个函数,这个测试会失败吗? → 如果不会,测试很可能是冗余的
- 这个 diff 里有没有
// HACK:/// XXX:标记? → 如果没有,对 AI 来说就很可疑
评判等级(与 AI-SLOP-Detector 的评分相匹配)
| 评判 | 含义 | 操作 |
|---|---|---|
| CLEAN | < 5% 的行被标记 | 发布 |
| SUSPICIOUS | 5–15% 的行被标记 | 再审查一遍更改 |
| INFLATED | 15–30% 的行被标记 | 清除冗余内容,拆分提交 |
| CRITICAL | > 30% 的行被标记 | 合并前重写该部分 |
使用方法
阅读各条规则文件,了解详细约定和示例:
rules/comments-narration.md
rules/naming-generic-placeholders.md
rules/over-eng-premature-interface.md
rules/defensive-generic-catch.md
rules/test-mock-everything.md
rules/style-hyper-consistent.md
每条规则文件都包含:
- YAML frontmatter(标题、影响、标签)
- 简要说明该模式为何是 AI 指纹
- 展示冗余内容的“不正确”示例
- 展示人类等效写法的“正确”示例
- 检测指南(grep / eslint / phpstan / 启发式方法)
- 参考链接
参考资料
-
GitClear — 2025 Code-Quality Trends Report(重构骤减、复制粘贴激增)
-
arXiv 2510.03029 — Investigating the Smells of LLM-Generated Code
-
Addy Osmani — Comprehension Debt(O'Reilly Radar)
-
Stack Overflow Blog — Eno Reyes 关于 AI 代码质量的问答
-
hardikpandya/stop-slop — 面向文本冗余的姊妹项目
-
flamehaven01/AI-SLOP-Detector — 带有 27 种模式的 Python AST 扫描器
完整汇编文档
包含所有扩展规则的完整指南:AGENTS.md